【前言】
前段时间扫描出来发现线上业务存在Heartbleed漏洞,听着名字挺瘆人的。百度老哥告诉我,这个是OpenSSL在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检查),会导致攻击者可以追踪OpenSSL所分配的64KB缓存、将超出必要范围的字节信息复制到缓存当中再返回缓存内容,这样一来受害者的内存内容就会以每次64jKB的速度进行泄露,在后面的升级版本中得以修复,看来我们使用的版本还是处于低版本,于是乎就需要升级OpenSSL。因为种种原因,我们必须要手动在nginx中添加此升级后的模块,又因为种种原因,nginx版本太低不适用新版本的,于是乎,就有了Nginx的平滑升级。
【准备各种包】
首先你需要去官方下载以下包:
OpenSSL 1.1.1d:https://www.openssl.org/source/openssl-1.1.1g.tar.gz
Nginx 1.16.1:http://nginx.org/download/nginx-1.16.1.tar.gz
操作步骤
备份旧nginx
cp -r /usr/local/nginx /data/nginx-bak
1.解压nginx新版本包
tar xvf nginx-1.16.0.tar.gz
2.检测平台的目标特征 (此处的内容和旧版本保持一致)
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/var/log/nginx/err.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx/nginx.lock --user=apache --group=apache --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --http-log-path=/var/log/nginx/access.log --add-module=/root/update-nginx/nginx-upstream-fair-master/ --add-module=/opt/nginx_upstream_check_module-master/ --with-http_stub_status_module --with-openssl=/root/update-nginx/openssl-1.1.1d/
3.编译(注意:不要执行make install)
make
4.备份旧版本二进制文件,用新版本替代
(cp的时候要带上-f参数,不然会一直报“cp: 无法创建普通文件"/data/nginx/sbin/nginx": 文本文件忙”)
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx1.8.bak
cp -f /root/nginx-1.16.1/objs/nginx /usr/local/nginx/sbin/
5.验证配置文件
/usr/local/nginx/sbin/nginx –t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
6.发送USR2信号,用新二进制启动新进程
向主进程(master)发送USR2信号,Nginx会启动一个新版本的master进程和对应工作进程,和旧版一起处理请求
ps aux | grep nginx
找到master process进程号,图中为18192,执行下面命令
kill -USR2 18192
7.查看是否生效
ps aux | grep nginx
此时会有两个nginx主进程,分别是新旧版本的主进程
8.发送WINCH信号,新进程接管旧子进程
向旧的Nginx主进程(master)发送WINCH信号,它会逐步关闭自己的工作进程(主进程不退出),这时所有请求都会由新版Nginx处理
kill -WINCH 18192
ps aux | grep nginx
可以看到之前的子进程已经消失,只剩下旧版本的主进程。
回滚步骤:此时如果需要回退继续使用旧版本,给旧nginx主进程发送HUP信号,它会重新启动工作进程, 仍使用旧版配置文件。然后可以将新版Nginx进程杀死(使用QUIT、TERM、或者KILL)
kill -HUP 18192
9.发送QUIT信号,退出旧主进程
升级完毕,可向旧的Nginx主进程(master)发送(QUIT、TERM、或者KILL)信号,使旧的主进程退出
kill -QUIT 18192
此时再次查看nginx进程,就只剩新版本的nginx进程了
10.验证版本号,并访问测试服务是否正常
/usr/local/nginx/sbin/nginx –v
至此,整个nginx就已经平滑的升级成功