在对网站服务器进行漏洞扫描时,发现了一个较严重的漏洞 SSL/TLS协议信息泄露漏洞(CVE-2016-2183)
查看下同的openssl 版本
$ openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
系统使用的 nginx, 查看nginx编译用的OpenSSL版本
$nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments:
--prefix=/usr/share/nginx
解决上面的漏洞,需要将nginx的OpenSSL升级到1.1.1
平滑升级参考How To Upgrade Nginx In-Place Without Dropping Client Connections
- 准备好新的nginx可执行文件。(从其他地方下载或已有的服务器上复制(运行的系统要相似),或者源码编译,底部附有详细的编译过程)
校验新的二进制文件能否执行,从其他地方复制来的可能会出现缺少库的情形,这时只需要吧响应的库一并复制过来,放到相应位置即可。
./nginx -V
./nginx: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
- 查看当前运行的ngixn
$ which nginx
/usr/sbin/nginx
- 备份当前nginx,及器配置文件(nginx二进制文件直接移走,不影响运行中的nginx服务)
mv /usr/sbin/nginx /usr/sbin/nginx.bak
cp -r /etc/nginx/ /etc/nginx_conf.bak
- 将新的二进制文件,移到之前nginx的位置
cp nginx.new /usr/sbin/nginx
- 启动新的nginx master,work进程组(不影响正在服务的master,worker)
sudo kill -s USR2 `cat /run/nginx.pid`
- 查看新老nginx服务 共存
ps aux | grep nginx
root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 10847 0.0 0.1 47936 1908 ? S 13:26 0:00 nginx: worker process
root 11003 0.0 0.3 47564 3132 ? S 13:56 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 11004 0.0 0.1 47936 1912 ? S 13:56 0:00 nginx: worker process
user 11031 0.0 0.0 112640 960 pts/0 S+ 14:01 0:00 grep --color=auto nginx
查看pid文件,发现老的nginx的pid文件从nginx.pid 变成了 nginx.pid.oldbin
tail /run/nginx.pid*
==> /run/nginx.pid <==
11003
==> /run/nginx.pid.oldbin <==
10846
- 停止老nginx的worker (worker服务完后当前的链接后,就退出了),
sudo kill -s WINCH `cat /run/nginx.pid.oldbin`
可以看到只有新nginx的work再响应请求。
ps aux | grep nginx
root 10846 0.0 0.3 47564 3280 ? S 13:26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
root 11003 0.0 0.3 47564 3132 ? S 13:56 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 11004 0.0 0.1 47936 1912 ? S 13:56 0:00 nginx: worker process
user 11089 0.0 0.0 112640 964 pts/0 R+ 14:13 0:00 grep --color=auto nginx
- 查看请求的处理情况
没有问题的话就可以安全的停止老nginx的进程了
sudo kill -s QUIT `cat /run/nginx.pid.oldbin`
如果新的nginx有问题的话,启用老nginx的worker,来响应请求. 同时停止新的有问题的nginx
sudo kill -s HUP `cat /run/nginx.pid.oldbin`
sudo kill -s QUIT `cat /run/nginx.pid`
附录 nginx源码编译
- 下载openssl源码 https://www.openssl.org/source/ (使用openssl的源码,不升级系统的openssl,因为系统中很多程序依赖openssl,升级后可能造成严重的问题)
$wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz
$tar zxvf openssl-1.1.1i.tar.gz
- 下载nginx源码 http://nginx.org/en/download.html
$wget http://nginx.org/download/nginx-1.18.0.tar.gz
$tar zxvf nginx-1.18.0.tar.gz
- 安装编译环境
yum groupinstall "Development tools"
yum install -y zlib zlib-devel openssl openssl-devel pcre pcre-devel
- 查看nginx当前的编译参数
$nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments:
--prefix=/usr/share/nginx
--sbin-path=/usr/sbin/nginx
--modules-path=/usr/lib64/nginx/modules
......
参数说明参考 http://nginx.org/en/docs/configure.html 和 https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc/
- 可根据当前的编译参数还有需要调整编译参数,但要加上openssl的源码地址
$./configure --with-openssl=../openssl-1.1.1i --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log
- 这时可能出现缺少库的情形,安装后,再次config即可
$./configure: error: the Google perftools module requires the Google perftools
library. You can either do not enable the module or install the library.
$yum install gperftools
- configure 成功后会出现 Makefile 文件,这时make编译,切记不要再执行make install
$make
- make后会生成nginx的可执行文件,查看编译有无问题。有问题的话,make clean,重新 configure,make(过程中要查看问题)
$./objs/nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.1.1i 8 Dec 2020
TLS SNI support enabled
configure arguments: --with-openssl=../openssl-1.1.1i --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log