背景说明:
最近公司用网藤对网站业务进行了风险分析,发现了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的方法(动态编译也适用)
说明:
- 由于线上服务器是静态编译的,所以重点介绍此方法的升级步骤(只升级Web Server的OpenSSL版本,系统的OpenSSL版本不动)下面采用虚拟机模拟演示线上的升级过程,方法和注意点都是一样的。
- 其实无论动态还是静态编译,对于线上业务都推荐采用静态升级的方法,因为动态升级涉及到升级系统的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版本已经成为最新的了。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END