邹洪

【工作】线上Nginx升级OpenSSL版本防止安全漏洞
背景说明:最近公司用网藤对网站业务进行了风险分析,发现了OpenSSL漏洞,由于线上的OpenSSL版本过旧,现在...
扫描右侧二维码阅读全文
17
2019/06

【工作】线上Nginx升级OpenSSL版本防止安全漏洞

背景说明:

最近公司用网藤对网站业务进行了风险分析,发现了OpenSSL漏洞,由于线上的OpenSSL版本过旧,现在需要着手升级,公司的Web Server是Nginx,而Nginx安装时分为动态编译和静态编译OpenSSL两种方式,所以先查看是由那种方式安装的。

一、判断webserver是动态编译还是静态编译ssl的两种方法:

1.查看Nginx编译参数

输入以下指令,查看Nginx的编译参数:
# /opt/nginx/sbin/nginx -V
 
nginx version: nginx/1.4.7
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx-1.4.7 --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-openssl=/tmp/openssl-1.0.1c --with-pcre
如果编译参数中含有--with-openssl=...,则表明Nginx是静态编译Openssl,上面就是静态编译的

2.查看Nginx的依赖库

另外一种方法是查看一下Nginx程序的依赖库:
# ldd `which nginx` | grep libssl

libssl.so.10 => /usr/lib/libssl.so.10 (0xb76c6000)
如果输出中不包含libssl.so的文件,就说明是静态编译的Openssl的,而上面的是动态编译的

二、静态编译升级OpenSSL的方法(动态编译也适用)

说明:
  1. 由于线上服务器是静态编译的,所以重点介绍此方法的升级步骤(只升级Web Server的OpenSSL版本,系统的OpenSSL版本不动)下面采用虚拟机模拟演示线上的升级过程,方法和注意点都是一样的。
  2. 其实无论动态还是静态编译,对于线上业务都推荐采用静态升级的方法,因为动态升级涉及到升级系统的OpenSSL,而系统的很多服务(如OpenSSH)都会调用,会造成一些未知的问题,坑很大~

1.先查看nginx编译时候的参数:

# /opt/nginx-1.4.7/sbin/nginx -V
nginx version: nginx/1.4.7
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx-1.4.7 --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-openssl=/tmp/openssl-1.0.1c --with-pcre

2.下载最新的OpenSSL软件

# wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz (2016-9-26发布)
# tar zxvf openssl-1.0.2j.tar.gz -C /tmp/
注:官网最新的版本openssl-1.1.0c.tar.gz,但是编译nginx make 时候会报错,无法编译成功,后来Google了一下,发现OpenSSL API 在1.1.版本中发生了很大的变化,估计是nginx不支持(nginx 1.9版本也试了,1.1版本也会报错)。所以换成了1.0版本,这个openssl-1.0.2j.tar.gz是1.0版本中最新的稳定版,基本上修复了ssl的一些漏洞。

3.重新编译安装nginx

进入nginx源码目录,使用之前安装nginx的参数,改变--with-openssl= 参数指定的OpenSSL软件版本
# cd nginx-1.4.7
# ./configure --prefix=/opt/nginx-1.4.7 --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-openssl=/tmp/openssl-1.0.2j --with-pcre
# make

4.平滑升级(此处没有进行版本升级,但是对于线上业务操作应该一样)

# mv /opt/nginx-1.4.7/sbin/nginx /opt/nginx-1.4.7/sbin/nginx.bak
# cp ./objs/nginx /opt/nginx-1.4.7/sbin/
# /opt/nginx-1.4.7/sbin/nginx -t    (查看是否有报错)
注意:如果提示“cp:cannot create regular file `/usr/local/nginx-1.4.1/sbin/nginx': Text file busy”建议使用如下语句cp (一般原因是由于你没有把sbin目录下旧的nginx二进制文件移走造成)
#cp -rfp objs/nginx /opt/nginx-1.4.1/sbin/nginx
先查看线上目前运行的nginx的pid
# ps aux| grep nginx
root     28146  0.0  0.0  21776   828 ?        Ss   15:02   0:00 nginx: master process /opt/nginx-1.4.7/sbin/nginx
nobody   28147  0.0  0.1  22184  1416 ?        S    15:02   0:00 nginx: worker process      
root     30203  0.0  0.0 103308   852 pts/0    S+   15:18   0:00 grep nginx
在源码目录执行make upgrade开始升级
# cd nginx-1.4.7    # 进入nginx的源码目录
# make upgrade      # 执行命令的输出结果如下

/opt/nginx-1.4.7/sbin/nginx -t
nginx: the configuration file /opt/nginx-1.4.7/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx-1.4.7/conf/nginx.conf test is successful
kill -USR2 `cat /opt/nginx-1.4.7/logs/nginx.pid` #给旧nginx发送平滑迁移信号
sleep 1
test -f /opt/nginx-1.4.7/logs/nginx.pid.oldbin   #等待旧版本Nginx的pid变为oldbin
kill -QUIT `cat /opt/nginx-1.4.7/logs/nginx.pid.oldbin` #结束旧工作进程,完成此次升级操作
可以查看下Nginx的pid已经改变:
# ps aux| grep nginx
root     30209  0.0  0.2  21776  2180 ?        S    15:18   0:00 nginx: master process /opt/nginx-1.4.7/sbin/nginx
nobody   30211  0.0  0.1  22188  1412 ?        S    15:18   0:00 nginx: worker process      
root     30223  0.0  0.0 103308   852 pts/0    S+   15:19   0:00 grep nginx
注:对于线上的业务,执行上面命令时候,可能会发现有2个主进程,并且有正在关闭的进程(nginx: worker process isshutting down),这属于正常现象,因为需要等一些旧连接断开,逐渐转入新的进程,过一段时间后,再次确认nginx进程,可以发现老进程已自动退出了。
当所有旧进程消失后,查看是否升级成功:
# /opt/nginx-1.4.7/sbin/nginx -V

nginx version: nginx/1.4.7
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx-1.4.7 --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-openssl=/tmp/openssl-1.0.2j/ --with-pcre
由上面的"--with-openssl=/tmp/openssl-1.0.2j/ "可以看出Nginx使用的OpenSSL版本已经成为最新的了。
Last modification:November 7th, 2019 at 03:28 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment