Openssh 8.4p1制作成rpm包批量升級
文章簡介
目的:解決openssh安全漏洞(CVE-2019-16905、CVE-2020-15778)
機器較少時,是一臺一臺的編譯安裝是比較輕松,當(dāng)機器達到幾十上百臺時,openssh的安裝將成為一個繁重的工作,如果能將openssh的源碼包制作成rpm格式的安裝包,這將降低了安裝openssh的難度和減輕了安裝openssh的工作量。
本文將介紹如何通過openssh官方源碼包生產(chǎn)rpm的安裝包,制作RPM包報錯解決思路,及升級過程的方式方法。
一、制作RPM包,確認(rèn)操作系統(tǒng),內(nèi)核版本,openssh當(dāng)前版本,目標(biāo)openssh版本。
1、操作系統(tǒng):CentOS Linux release 7.9.2009 (Core)
2、內(nèi)核版本:Linux version 3.10.0-1160.el7.x86_64
3、openssh版本:OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
4、openssh目標(biāo)版本:OpenSSH_8.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
二、制作過程
1、下載相關(guān)依賴包,安裝制作工具等。
[root@localhost ~]# yum -y install rpm-build gcc gcc-c++ glibc glibc-devel openssl-devel openssl prce pcre-devel zlib zlib-devel make wget krb5-devel pam-devel libX11-devel xmkmf libXt-devel initscripts libXt-devel imake gtk2-devel
2、查看若沒有rpmbuild目錄,可手動創(chuàng)建得到一個完整的rpmbuild目錄
[root@localhost ~]# mkdir -p rpmbuild/{SOURCES,SPECS,RPMS,SRPMS,BUILD,BUILDROOT}
3、下載好制作rpm包需要的源碼文件及依賴包
openssh8.4p1下載地址:https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/openssh-8.4p1.tar.gz
/x11-ssh-askpass下載地址:http://ftp.riken.jp/Linux/momonga/6/Everything/SOURCES/x11-ssh-askpass-1.2.4.1.tar.gz
4、切換路徑,解壓openssh-8.4p1.tar.gz,拷貝文件。(注,這里使用VM,root,可創(chuàng)建普通用戶給與權(quán)限的方法操作)
[root@localhost ~]# cd /home/rpmbuild/SOURCES
[root@localhost ~]# tar xf openssh-8.4p1.tar.gz
[root@localhost ~]# cd openssh-8.4p1/contrib/redhat
[root@localhost ~]# cp openssh.spec /home/rpmbuild/SPECS/
5、修改、優(yōu)化spec文件。
[root@localhost ~]# vim /home/rpmbuild/SPECS
第一處修改:12行,15行,原openssh.spec的文件內(nèi)容為0,改為1
# Do we want to disable building of x11-askpass? (1=yes 0=no)
%global no_x11_askpass 1
# Do we want to disable building of gnome-askpass? (1=yes 0=no)
%global no_gnome_askpass 1
第二處修改:104行 原openssh.spec文件中把行改為注釋BuildRequires: openssl-devel < 1.1
Requires: initscripts >= 5.20
%endif
BuildRequires: perl
%if %{compat_openssl}
BuildRequires: compat-openssl10-devel
%else
BuildRequires: openssl-devel >= 1.0.1
# BuildRequires: openssl-devel < 1.1
%endif
BuildRequires: /bin/login
%if ! %{build6x}
第三處修改:89行,原 openssh.spec文件89行,增加Source2: sshd,
URL: https://www.openssh.com/portable.html
Source0: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz
Source2: sshd
License: BSD
Group: Applications/Internet
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
第四處修改:280-281行
原openssh.spec文件把行install -m644 contrib/redhat/sshd.pam$RPM_BUILD_ROOT/etc/pam.d/sshd 改為注釋
%if %{build6x}
install -m644 contrib/redhat/sshd.pam.old $RPM_BUILD_ROOT/etc/pam.d/sshd
%else
#install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd
install -m644 $RPM_SOURCE_DIR/sshd $RPM_BUILD_ROOT/etc/pam.d/sshd
%endif
install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd
第五處修改:342行,需要添加的內(nèi)容挺多的,從cp -r /etc/ssh /etc/ssh_bak 到service sshd restart ,從342行到356行的內(nèi)容進行添加。
%pre server
%{_sbindir}/groupadd -r -g %{sshd_gid} sshd 2>/dev/null || :
%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \
-g sshd -M -r sshd 2>/dev/null || :
#從這里開始復(fù)制
cp -r /etc/ssh /etc/ssh_bak
%post server #一行原文里面有,如果原文復(fù)制,這一行先,行改為注釋
chmod 600 /etc/ssh/ssh_host_*_key
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
sed -i -e "s/#X11Forwarding no/X11Forwarding yes/g" /etc/ssh/sshd_config
echo "KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1" >>/etc/ssh/sshd_config
chmod +x /etc/init.d/sshd
mv /usr/lib/systemd/system/sshd.service /opt/
mv /usr/lib/systemd/system/sshd.socket /opt/
/sbin/chkconfig --add sshd
service sshd restart
#這里結(jié)束
%postun server
/sbin/service sshd condrestart > /dev/null 2>&1 || :
6、準(zhǔn)備完畢,開始制作rpm包,
[root@localhost ~]# cd rpmbuild/SPECS
[root@localhost SPECS]# rpmbuild -bb openssh.spec
制作成功后的輸出結(jié)果
Requires: /bin/bash libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.16)(64bit) libc.so.6(GLIBC_2.17)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.6)(64bit) libc.so.6(GLIBC_2.8)(64bit) libcom_err.so.2()(64bit) libcrypt.so.1()(64bit) libcrypt.so.1(GLIBC_2.2.5)(64bit) libcrypto.so.10()(64bit) libcrypto.so.10(OPENSSL_1.0.1_EC)(64bit) libcrypto.so.10(OPENSSL_1.0.2)(64bit) libcrypto.so.10(libcrypto.so.10)(64bit) libdl.so.2()(64bit) libgssapi_krb5.so.2()(64bit) libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit) libk5crypto.so.3()(64bit) libkrb5.so.3()(64bit) libkrb5.so.3(krb5_3_MIT)(64bit) libpam.so.0()(64bit) libpam.so.0(LIBPAM_1.0)(64bit) libresolv.so.2()(64bit) libutil.so.1()(64bit) libutil.so.1(GLIBC_2.2.5)(64bit) libz.so.1()(64bit) rtld(GNU_HASH)
Obsoletes: ssh-server
Processing files: openssh-debuginfo-8.4p1-1.el7.x86_64
Provides: openssh-debuginfo = 8.4p1-1.el7 openssh-debuginfo(x86-64) = 8.4p1-1.el7
Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/openssh-8.4p1-1.el7.x86_64
Wrote: /root/rpmbuild/RPMS/x86_64/openssh-8.4p1-1.el7.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/openssh-clients-8.4p1-1.el7.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/openssh-server-8.4p1-1.el7.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/openssh-debuginfo-8.4p1-1.el7.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.RK1ICd
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd openssh-8.4p1
+ rm -rf /root/rpmbuild/BUILDROOT/openssh-8.4p1-1.el7.x86_64
+ exit 0
7、制作完RPM包??梢钥吹皆?root/rpmbuild/RPMS/x86_64/路徑下會有4個rpm包。注意:構(gòu)建完成后,會生成一個debug的rpm包,安裝時無需安裝此包
[root@localhost ~]#ls /root/rpmbuild/RPMS/x86_64/
openssh-8.4p1-1.el7.x86_64.rpm openssh-debuginfo-8.4p1-1.el7.x86_64.rpm
openssh-clients-8.4p1-1.el7.x86_64.rpm openssh-server-8.4p1-1.el7.x86_64.rpm
三、升級
1、準(zhǔn)備VM ,2臺,確認(rèn)好沒安裝之前ssh版本信息,多開一個信息口接收,注意,這里可以多開端口防止因升級失敗無法連接。
2、升級實施過程,這里介紹三種方式
第一種安裝方法如下,建議使用該方法。
確認(rèn)版本信息
ssh -V
rpm -qa|grep openssh
備份設(shè)置
cd /root/openssh
cp /etc/pam.d/sshd pam-ssh-conf-old-$(date +%F)
cp -r /etc/ssh /etc/ssh_$(date +%F)
解壓,此步驟可以省略。
tar xf openssh-8.1p1-1.el7.x86_64.tar
安裝openssh
rpm -U *.rpm
恢復(fù)配置
mv /etc/pam.d/sshd /etc/pam.d/sshd_$(date +%F)
cp pam-ssh-conf-old-$(date +%F) /etc/pam.d/sshd
重啟openssh
systemctl restart sshd
查看版本信息確認(rèn)升級完成
ssh -V / rpm -qa|grep openssh
第二種安裝方法如下(這種方法會自動處理依賴關(guān)系):
ssh -V
rpm -qa|grep openssh
yum install ./*.rpm
部分機器使用方法二安裝會提示依賴問題,可以使用以下方法:
yum update *.rpm
至此,升級完成,新開SSH終端連接即可。
因為openssh升級后,/etc/ssh/sshd_config會還原至默認(rèn)狀態(tài),我們需要進行相應(yīng)配置:
cd /etc/ssh/
chmod 400 ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
systemctl restart sshd
setenforce 0
即可正常登錄,然后修改/etc/selinux/config 文件:
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
進行永久禁用SElinux即可。
ssh -V
rpm -qa|grep openssh
查看版本信息確認(rèn)升級完成
注意:
如果Centos7默認(rèn)openssl版本不為OpenSSL 1.0.2k,就需要先進行升級:
yum install openssl -y
然后回到第一步進行安裝即可。
第三種安裝方法如下:
rpm -Uvh *.rpm
安裝后會如下提示:
[root@test ~]# rpm -Uvh *.rpm
Preparing... ################################# [100%]
Updating / installing...
1:openssh-8.4p1-1.el7 ################################# [ 14%]
2:openssh-clients-8.4p1-1.el7 ################################# [ 29%]
3:openssh-server-8.4p1-1.el7 ################################# [ 43%]
4:openssh-debuginfo-8.4p1-1.el7 ################################# [ 57%]
Cleaning up / removing...
5:openssh-server-7.4p1-16.el7 ################################# [ 71%]
6:openssh-clients-7.4p1-16.el7 ################################# [ 86%]
7:openssh-7.4p1-16.el7 ################################# [100%]
[root@test ~]# ssh -V
OpenSSH_8.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
修改權(quán)限
cd /etc/ssh/
chmod 400 ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key
允許 root登錄
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
不修改這個文件,會出現(xiàn)密碼是正確的,但無法登陸。
cat <<EOF>/etc/pam.d/sshd
#%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
重啟服務(wù)
systemctl restart sshd
確認(rèn)版本信息
ssh -V
rpm -qa |grep openssh
3、檢查升級是否成功
ssh -V
rpm -qa |grep openssh
重開連接
無論使用的是哪種升級方法,都要重開ssh連接,或者ssh xxx@192.168.2xx.1xx。只有重新連接成功,升級才算完成。
4、報錯歸納:
(1)、在制作RPM包時,可能會報以下的錯誤:
Processing files: openssh-server-8.4p1-1.el7.x86_64
error: File not found: /root/rpmbuild/BUILDROOT/openssh-8.4p1-1.el7.x86_64/etc/pam.d/sshd
RPM build errors:
File not found: /root/rpmbuild/BUILDROOT/openssh-8.4p1-1.el7.x86_64/etc/pam.d/sshd
解決的辦法是:在openssh.spec 280-281行中,把剛才我們標(biāo)記改為注釋的內(nèi)容去掉,把注釋改為行,重新rpmbuild -bb openssh.spec即可 。
在openssh.spec文件,以下把內(nèi)容開頭部分注釋去掉改為行
install -m644 contrib/redhat/sshd.pam$RPM_BUILD_ROOT/etc/pam.d/sshd
(2)安裝過程,使用第一種安裝方法,安裝完畢后會有兩個警告,但是是正常的。警告信息如下:
[root@localhost openssh]# rpm -U *.rpm
Restarting sshd (via systemctl): [ OK ]
warning: file /usr/lib/systemd/system/sshd.socket: remove failed: No such file or directory
warning: file /usr/lib/systemd/system/sshd.service: remove failed: No such file or directory
(3)使用第2種安裝方法,安裝完畢后可能會報有以下錯誤。
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Unable to load host key "/etc/ssh/ssh_host_ed25519_key": bad permissions
Unable to load host key: /etc/ssh/ssh_host_ed25519_key
sshd: no hostkeys available -- exiting.
[FAILED]
sshd.service: control process exited, code=exited status=1
Failed to start SYSV: OpenSSH server daemon.
Unit sshd.service entered failed state.
sshd.service failed.
解決的辦法是:
chmod 0600 /etc/ssh/ssh_host_ed25519_key
service sshd restart
(4)使用第二、三種方式進行安裝,/etc/pam.d/sshd文件會被覆蓋,需要進行還原。
先清空:
>/etc/pam.d/sshd;
再j進行還原:
echo '#%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'>/etc/pam.d/sshd