1. 写在前面
在工作中经常会碰到系统安全检测之类的事情,由于常用的发行版如CentOS自带的openssh版本都比较低,所以安全检测的结果常会出现大堆跟它相关的中高危漏洞,以及openssl的高危漏洞。
为了加固系统安全性,所以索性将openssh升级到已修复各项漏洞的高版本。
系统环境:CentOS6.9-2.6.32-696.10.1.el6
2. 升级思路
- 查阅官方网站openssh,了解其最新的版本信息及其对系统内核和其它依赖组件的要求。
- 然后备份系统中现有的openssh信息,以备升级失败后进行回退。再根据说明优先完成其依赖组件的升级。
- 最后升级openssh,并进行验证。
openssh最新的版本是2017年3月20日释出的OpenSSH 7.5。
3. 升级步骤
3.1 升级openssl
根据openssh7.5p1的文档说明,这一版本建议使用openssl 1.1.0f,所以优先将系统中的openssl升级至1.1.0f。于是访问openssl官网下载其最新的稳定版本,正好也是1.1.0f。然后将源码包解压后查阅其中的README,然后发现结合系统环境(CentOS6.9)还需要阅读NOTE.PERL。待全部读过之后,再开始openssl的升级工作。
升级前查看系统现有openssl版本:
[root@server1 ~]# openssl version -a
OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Wed Mar 22 21:43:28 UTC 2017
platform: linux-x86_64
options: bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/etc/pki/tls"
engines: dynamic
[root@server1 ~]# rpm -qa | grep openssl
openssl-devel-1.0.1e-57.el6.x86_64
openssl-1.0.1e-57.el6.x86_64
openssl升级步骤:
rpm -qa | grep perl #openssl的安装依赖于perl运行环境,并且还需要perl-core包
rpm -qa | grep perl-core
yum install perl-core -y #如果系统中没有安装则yum安装之
perl -MCPAN -e shell #进入perl的shell命令行模式
shell>install YAML #perl shell中执行install YAML,shell>是提示符,perl安装其它模块时需要用到YAML,一路回车完成YAML的安装
quit #退出perl shell模式
cpan -f -i Text::Template #bash中输入此命令,安装perl的Text::Template模块
wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz #下载openssl1.1.0f的源码包
./config --prefix=/usr/local/openssl-1.1.0f #编译openssl,此处我只指定了新的openssl将要安装的位置
make
make install #安装编译好的openssl到指定的位置
mv /usr/bin/openssl /usr/bin/openssl.old #备份系统原有openssl程序
mv /usr/include/openssl /usr/include/openssl.old #备份系统原有openssl头文件,安装了openssl-devel后才会有
ln -s /usr/local/openssl-1.1.0f/bin/openssl /usr/bin/openssl #将新版本的openssl执行文件链接至原openssl程序位置
ln -s /usr/local/openssl-1.1.0f/include/openssl /usr/include/openssl #替换掉原来的openssl头文件
echo "/usr/local/openssl-1.1.0f/lib/" >> /etc/ld.so.conf #将新的openssl库文件位置添加到库文件搜索配置文件中
ldconfig -v #手动更新系统的动态链接库,不更新的话,新安装的openssl库文件会找不到,进而无法使用新版本的openssl指令
cd /usr/local/openssl-1.1.0f/share/man
cp man1/* /usr/share/man/man1/
cp man3/* /usr/share/man/man3/
cp man5/* /usr/share/man/man5/
cp man7/* /usr/share/man/man7/ #将新版本openssl的全部man手册放置到系统默认位置,这样使用man指令就可查看
openssl版本验证
[root@server1 openssl-1.1.0f]# openssl version -a
OpenSSL 1.1.0f 25 May 2017 #版本显示正确,openssl升级完成
built on: reproducible build, date unspecified
platform: linux-x86_64
compiler: gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DNDEBUG -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DRC4_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DPADLOCK_ASM -DPOLY1305_ASM -DOPENSSLDIR="\"/usr/local/openssl-1.1.0f/ssl\"" -DENGINESDIR="\"/usr/local/openssl-1.1.0f/lib/engines-1.1\"" -Wa,--noexecstack
OPENSSLDIR: "/usr/local/openssl-1.1.0f/ssl"
ENGINESDIR: "/usr/local/openssl-1.1.0f/lib/engines-1.1"
注意
升级完openssl后,系统中的应用软件如nginx,mysql,curl,wget,cobbler,yum等,如果要使用新版本的openssl都需要关联新的openssl库文件进行重新编译。不然只是继续使用旧版本的openssl库文件。
3.2 升级openssh
- 查看现有openssh及其调用的openssl版本:
[root@server1 ~]# ssh -V
OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013
- 启用telnet-server
启用telnet-server一是为了借助telnet通道完成openssh的升级,二是防止ssh升级失败或者配置不当导致无法ssh连接服务器。
yum install telnet telnet-server -y
sed -i 's/yes/no/g' /etc/xinetd.d/telnet
service xinetd start
#如果启用了iptables记得允许从外部连接telnet端口
iptables -t filter -I INPUT 1 -p tcp -m state --state NEW --dport 23 -j ACCEPT
- 使用非root用户telnet登录上服务器
- 卸载系统自带的openssh软件包组
rpm -qa | grep openssh | xargs -i{} rpm -e --nodeps {}
- 下载openssh源码及openssl补丁文件
wget http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-7.5p1.tar.gz
wget http://www.linuxfromscratch.org/patches/blfs/svn/openssh-7.5p1-openssl-1.1.0-1.patch
- 删除原系统中的sshd账户及组并设定组ID为50 (GID实际操作中按需调整)
userdel -r sshd
grep 50 /etc/group #系统中gid 50为ftp所占用,如果不使用ftp组可以将其删除
userdel -r ftp #ftp组因默认只有ftp一个用户,group ftp会一并删除
- 创建新的sshd用户及组
install -v -m700 -d /var/lib/sshd &&
chown -v root:sys /var/lib/sshd &&
groupadd -g 50 sshd &&
useradd -c 'sshd PrivSep' \
-d /var/lib/sshd \
-g sshd \
-s /bin/false \
-u 50 sshd
- 解压openssh源码包
tar zxf openssh-7.5p1.tar.gz
cd openssh-7.5p1
- 给openssh源码包打上openssl-1.1.0的补丁包
patch -Np1 -i ../openssh-7.5p1-openssl-1.1.0-1.patch #注意此时工作目
录是在openssh的解压后的源码包下,patch是放在它的上一层目录中,
所以其路径用了“.."表示上一层目录
[root@server1 openssh-7.5p1]# patch -Np1 -i ../openssh-7.5p1-openssl-1.1.0-1.patch
patching file auth-pam.c
patching file cipher-3des1.c
patching file cipher-bf1.c
patching file cipher.c
patching file cipher.h
patching file dh.c
patching file dh.h
patching file digest-openssl.c
patching file kexdhc.c
patching file kexdhs.c
patching file kexgexc.c
patching file kexgexs.c
patching file monitor.c
patching file openbsd-compat/openssl-compat.c
patching file regress/unittests/sshkey/test_file.c
patching file regress/unittests/sshkey/test_sshkey.c
patching file rsa.c
patching file ssh-dss.c
patching file ssh-ecdsa.c
patching file ssh-keygen.c
patching file ssh-pkcs11-client.c
patching file ssh-pkcs11.c
patching file ssh-rsa.c
patching file sshkey.c
#执行patch指令后显示如上内容即表示补丁添加正常
- 编译openssh
可以指定ssh执行文件、配置文件、sftp-server、文档文件(包含man文件)安装的位置,以及指定要使用的openssl库文件的位置。参数如下:
./configure --prefix=/usr/local/openssh-7.5p1 --exec-prefix=/usr \
--libexecdir=/usr/libexec/openssh-7.5p1 --datarootdir=/usr/share \
--sysconfdir=/etc/ssh --with-md5-passwords --with-pam --with-selinux \
--with-privsep-path=/var/lib/sshd --with-ssl-dir=/usr/local/openssl-1.1.0f
openssh7.5默认不再继续支持ssh1,如果要使用ssh1,需要在上面的添加--with-ssh1
参数。上面的参数我还启用了pam和selinux,以及md5-password支持。同时ssh的指令放置位置和配置文件放置位置都和系统原openssh路径保持一致。
configure完成以后的汇总和提示信息:
OpenSSH has been configured with the following options:
User binaries: /usr/bin
System binaries: /usr/sbin
Configuration files: /etc/ssh
Askpass program: /usr/libexec/openssh-7.5p1/ssh-askpass
Manual pages: /usr/share/man/manX
PID file: /var/run
Privilege separation chroot path: /var/lib/sshd
sshd default user PATH: /usr/bin:/bin:/usr/sbin:/sbin
Manpage format: doc
PAM support: yes
OSF SIA support: no
KerberosV support: no
SELinux support: yes
Smartcard support:
S/KEY support: no
MD5 password support: yes
libedit support: no
libldns support: no
Solaris process contract support: no
Solaris project support: no
Solaris privilege support: no
IP address in $DISPLAY hack: no
Translate v4 in v6 hack: yes
BSD Auth support: no
Random number source: OpenSSL internal ONLY
Privsep sandbox style: rlimit
Host: x86_64-pc-linux-gnu
Compiler: gcc
Compiler flags: -g -O2 -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wno-pointer-sign -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-all -fPIE
Preprocessor flags: -I/usr/local/openssl-1.1.0f/include -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE
Linker flags: -L/usr/local/openssl-1.1.0f/lib -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -fstack-protector-all -pie
Libraries: -lcrypto -lrt -ldl -lutil -lz -lcrypt -lresolv
+for sshd: -lpam -lselinux
+for ssh: -lselinux
PAM is enabled. You may need to install a PAM control file
for sshd, otherwise password authentication may fail.
Example PAM control files can be found in the contrib/
subdirectory
- 安装openssh及相关程序和文档
make install &&
install -v -m755 contrib/ssh-copy-id /usr/bin &&
install -v -m644 contrib/ssh-copy-id.1 \
/usr/share/man/man1 &&
install -v -m755 -d /usr/share/doc/openssh-7.5p1 &&
install -v -m644 INSTALL LICENCE OVERVIEW README* \
/usr/share/doc/openssh-7.5p1
默认make install不会安装ssh-copy-id及其man手册文件,所以在这通过install指令特别安装。
- 验证openssh版本
[root@server1 redhat]# ssh -V
OpenSSH_7.5p1, OpenSSL 1.1.0f 25 May 2017
查看openssh版本是否为7.5p1同时调用的是openssl 1.1.0f。
- 安装sshd服务并设置开机自启
在编译openssh源码包时就会根据提供的参数生成符合实际情况的service启动脚本(主要是程序路径与系统安装路径一致)。
cd contrib/redhat/
cp sshd.init /etc/init.d/sshd
chkconfig --add sshd
chkconfig --list sshd
- 修改sshd配置文件并启动sshd服务
7.5中默认禁止root以密码方式登录但可以密钥登录,默认设置UseDNS no。根据实际需要修改sshd配置文件(/etc/ssh/sshd_config)。确认sshd配置无误后启动sshd服务。
service sshd start
- 连接ssh服务端
通过ssh登录服务器,确认sshd服务使用正常后,卸载telnet-server,关闭23端口,停用xinetd服务。
4. 写在最后
至此openssh的升级完成,对于openssh的漏洞防范不止于软件版本的升级,其sshd_config配置也非常重要,可以结合man sshd_config
学习它的使用,并结合iptables设置严格的openssh使用策略,并做好相应的监控工作(登录用户,登录日志)才行。
注意
在编译的过程中,我启用了SElinux和PAM支持,如果没有配置针对SSH的PAM和SElinux策略,建议关闭SELinux,否则即使保持配置文件sshd_config中默认的UsePAM为no,启用PasswordAuthentication yes,也无法使用密码通过ssh登录。始终提示Permission denied, please try again.但密码其实输入的是正确的。
参考链接