一、實驗背景
客戶請第三方安全公司掃描了下他們的服務器,發(fā)現(xiàn) SSH 存在許多安全漏洞,原因是 CentOS 7.2 使用了一個比較舊的 OpenSSH 版本 v6.6.1,而這些漏洞在新版的 OpenSSH 中均已被修復,所以出于安全考慮,需要升級。



yum 倉庫中并沒有最新版的 OpenSSH,我們需要自己從官方下載最新的opeenSSh源碼包編譯制作 rpm 安裝包。
因為客戶服務器不能連外網(wǎng),所以還需要將其做成離線升級包。
二、實驗環(huán)境
操作系統(tǒng): CentOS7.2 Mininal
serverA? 192.168.1.104? 模擬開發(fā)機,能聯(lián)網(wǎng),用于制作離線升級包
serverB? 192.168.1.106? 模擬客戶服務器,不能聯(lián)網(wǎng),openSSH相關包及其依賴版本較低
三、實驗預期
在severA上完成openSSH相關編譯及依賴下載,寫成一鍵升級腳本,拖到serverB上完成openSSH的升級。
OpenSSH源碼包官網(wǎng):http://www.openssh.com?
截止目前,最新OpenSSH源碼包版本為?openssh-7.9p1.tar.gz

What?is?the?difference?between?OpenSSH?Release?and?OpenSSH?Portable?Release?
https://www.openssh.com/portable.html
http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/

四、實驗操作
在serverA
# yum -y install? vim? wget epel-release
# yum? -y? install? rpm-build? gcc make
# yum -y install? openssl? openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel?gtk2-devel
# wget? http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.9p1.tar.gz
# tar -zxf openssh-7.9p1.tar.gz
# mkdir -p? /root/rpmbuild/{SOURCES,SPECS}
# cp ./openssh-7.9p1/contrib/redhat/openssh.spec? ? /root/rpmbuild/SPECS/
# cp openssh-7.9p1.tar.gz? ? /root/rpmbuild/SOURCES/
# cd? /root/rpmbuild/SPECS/
# sed? -i? -e? "s/%define no_gnome_askpass 0/%define no_gnome_askpass 1/g"? ? openssh.spec
# sed? -i? -e? "s/%define no_x11_askpass 0/%define no_x11_askpass 1/g"? ? openssh.spec
# sed? -i? -e? "s/BuildPreReq/BuildRequires/g"? ? openssh.spec
# sed -i? -e? "s/BuildRequires: openssl-devel < 1.1/#BuildRequires: openssl-devel < 1.1/g" openssh.spec
# rpmbuild? -bb? openssh.spec

編譯好后的文件被放在 /root/rpmbuild/RPMS/x86_64/ 目錄下:
# ll? /root/rpmbuild/RPMS/x86_64

將上述操作腳本化:
# cat build.sh
#####################################################
#!/bin/bash
OPENSSH_VERSION=7.9p1
yum -y install? vim? wget epel-release
yum -y install? rpm-build? gcc make
yum -y install? openssl? openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel
# cd /root
wget http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${OPENSSH_VERSION}.tar.gz
tar -zxf? openssh-${OPENSSH_VERSION}.tar.gz
mkdir -p /root/rpmbuild/{SOURCES,SPECS}
cp ./openssh-${OPENSSH_VERSION}/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/
cp openssh-${OPENSSH_VERSION}.tar.gz /root/rpmbuild/SOURCES/
cd /root/rpmbuild/SPECS/
sed -i -e "s/%define no_gnome_askpass 0/%define no_gnome_askpass 1/g" openssh.spec
sed -i -e "s/%define no_x11_askpass 0/%define no_x11_askpass 1/g" openssh.spec
sed -i -e "s/BuildPreReq/BuildRequires/g" openssh.spec
sed -i -e? "s/BuildRequires: openssl-devel < 1.1/#BuildRequires: openssl-devel < 1.1/g" openssh.spec
rpmbuild -bb openssh.spec
ls -l /root/rpmbuild/RPMS/x86_64
########################################################

五、在開發(fā)機上做openSSH升級測試
在serverA
# cd? /root/rpmbuild/RPMS/x86_64
# rpm -Uvh *.rpm

# rpm -qa | grep openssh

本來到此,我們升級就完成了,但是從客戶端登陸的時候卻失敗了!

開始我們以為自己制作的 rpm 包有問題,幾經(jīng)折騰,最后發(fā)現(xiàn)還是默認的配置不正確導致的結(jié)果。
無法用 ssh key 方式登錄,默認的 host key 文件授權(quán)太大,需要修改 key 文件的權(quán)限
# ll? /etc/ssh/ssh_host_*_key

# chmod 600? /etc/ssh/ssh_host_*_key
# ll /etc/ssh/ssh_host_*_key

升級完后的openSSH默認不允許用密碼方式登錄,我們需要更改配置文件:
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# sed -i -e? "s/#PasswordAuthentication yes/PasswordAuthentication yes/g"? /etc/ssh/sshd_config
# sed -i -e? "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g"? ? /etc/ssh/sshd_config
# sed -i -e? "s/#PermitEmptyPasswords no/PermitEmptyPasswords no/g"? /etc/ssh/sshd_config
# sed -i? -e? "s/#UsePAM no/UsePAM yes/g"? /etc/ssh/sshd_config
默認的 /etc/pam.d/sshd 中使用了過時的 pam_stack.so 動態(tài)庫,需要更新:
# cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
# cat >? /etc/pam.d/sshd? <<EOF
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
session include password-auth
EOF

重啟ssh服務,查看服務狀態(tài):
# systemctl restart sshd
# systemctl enable? sshd
# systemctl status sshd

你會發(fā)現(xiàn),升級后的sshd服務,是用的啟動腳本,不是/usr/lib/systemd/system/sshd.service文件了。
實際上升級過程中,程序已經(jīng)將 /usr/lib/systemd/system/sshd.service 刪除了,并且添加了服務啟動腳本 /etc/init.d/sshd
細心的你還會發(fā)現(xiàn),升級完后,我們經(jīng)常用于做免密登錄的公鑰拷貝命令 ssh-copy-id也沒有了!

其實不是沒有了,而是我們需要去解壓后源碼包拷貝到/usr/bin/目錄

# cp /root/openssh-7.9p1/contrib/ssh-copy-id? /usr/bin/
# chmod? 755? /usr/bin/ssh-copy-id
六、制作離線升級安裝包
在serverA
# yum -y install? yum-utils createrepo
# mkdir? /root/localrepo
# repotrack? openssl? -p /root/localrepo/

你可能會疑惑:不是找opennsh相關包的依賴么,怎么找的是openssl了?
其實從上面安裝可以,升級opennsh版本并不會缺少依賴,我們們只是需要相應地升級一下openssl的版本:
# cp? /root/rpmbuild/RPMS/x86_64/*.rpm? /root/localrepo
# createrepo -v? ? /root/localrepo
編寫離線升級安裝腳本:
cat install.sh
######################################################
#!/bin/bash
# 定位腳本當前路徑
parent_path=$( cd "$(dirname "${BASH_SOURCE}")"; pwd -P )
cd "$parent_path"
mkdir -p /etc/yum.repos.d/backup
mv /etc/yum.repos.d/*.repo? /etc/yum.repos.d/backup
rm -rf /tmp/localrepo
mkdir -p /tmp/localrepo
cp -rf? ./localrepo/*? /tmp/localrepo
echo "[localrepo]"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > /etc/yum.repos.d/localrepo.repo
echo "name=Local Repository"? ? ? ? ? >> /etc/yum.repos.d/localrepo.repo
echo "baseurl=file:///tmp/localrepo"? ? >> /etc/yum.repos.d/localrepo.repo
echo "gpgcheck=0"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? >> /etc/yum.repos.d/localrepo.repo
echo "enabled=1"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? >> /etc/yum.repos.d/localrepo.repo
yum clean all
yum -y? install openssl
yum -y install openssh*? --disablerepo="*" --enablerepo="localrepo"
rm -rf /tmp/localrepo
rm -f /etc/yum.repos.d/localrepo.repo
mv /etc/yum.repos.d/backup/*.repo? /etc/yum.repos.d
rm -rf /etc/yum.repos.d/backup
chmod 600? /etc/ssh/ssh_host_*_key
# modify /etc/ssh/sshd_config
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sed -i -e "s/#PasswordAuthentication yes/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitEmptyPasswords no/PermitEmptyPasswords no/g"? ? ? /etc/ssh/sshd_config
sed -i -e "s/#UsePAM no/UsePAM yes/g"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /etc/ssh/sshd_config
# modify /etc/pam.d/sshd
cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
cat > /etc/pam.d/sshd <<EOF
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
session include password-auth
EOF
# copy ssh-copy-id
cp ssh-copy-id /usr/bin
chmod 755 /usr/bin/ssh-copy-id
systemctl restart sshd
systemctl enable sshd
systemctl status sshd
rpm -qa | grep open
systemctl status? sshd| grep? "Active: active (running)"
if [ $? -eq 0 ]; then
? echo -e "\033[32m[INFO] OpenSSH upgraded to 7.9p1? successfully!\033[0m"
else
? echo -e "\033[31m[ERROR] OpenSSH upgraded to 7.9p1 faild!\033[0m"
fi
##############################################################


打包離線安裝包
# mkdir? /root/opensshUpgrade
# cp install.sh? /root/opensshUpgrade
# cp? -r? lcoalrepo /root/opensshUpgrade
# cp /root/openssh-7.9p1/contrib/ssh-copy-id? /root/opensshUpgrade
# tar openssshUpgrade.tar.gz? opensshUpgrade
七、離線安裝升級openSSH
將離線升級安裝包 openssshUpgrade.tar.gz拷貝到serverB 服務器
#? tar? -zxf? openssshUpgrade.tar.gz
# cd? openssshUpgrade
#? bash install.sh | tee install.log

# rpm -qa | grep openssl
# rpm -qa | grep openssh


# systemctl? status sshd

測試登錄
[C:\~]$? ssh? root@192.168.1.106

八、參考
Upgrade OpenSSH in CentOS 7
https://blog.forhot2000.cn/linux/2017/09/04/upgrade-openssh-in-centos-7.html
編譯升級OpenSSH 7.9
https://blog.csdn.net/weixin_42123737/article/details/85283972
Centos 6.5升級openssh到7.9p1
https://blog.csdn.net/qq_25934401/article/details/83419849
openssh升級腳本分享(openssh-7.7p1版)
https://blog.csdn.net/GX_1_11_real/article/details/82152459
Upgrade OpenSSH to 7.7p1 in CentOS 6
https://docs.junyangz.com/upgrade-openssh-to-7.7p1-in-centos-6
createrepo生成倉庫元數(shù)據(jù),搭建本地yum源
http://www.itdecent.cn/p/5cb5af152e75
解決離線安裝依賴包的方法
http://www.itdecent.cn/p/6f4f9a80a726
升級操作系統(tǒng)OpenSSH及其OpenSSL的正確姿勢
https://blog.51cto.com/techsnail/2138927
Openssh版本升級修復漏洞
https://www.cnblogs.com/Dev0ps/p/9629694.html
CentOS7 openssh升級到7.9p1
http://www.itdecent.cn/p/220f7fd908b0
OpenSSH-8.0p1
http://www.linuxfromscratch.org/blfs/view/svn/postlfs/openssh.html
CenOS7.2 升級OpenSSH 8.0 升級步驟及排錯
https://blog.csdn.net/weixin_40592911/article/details/90519686