一、 背景
安全部门扫描发现,某业务主机存在以下漏洞:
nginx 安全漏洞(CVE-2019-9511)
nginx 安全漏洞(CVE-2019-9513)
nginx 安全漏洞(CVE-2019-9516)
受影响版本:Nginx 1.9.51 至 16.0版本及1.17.2.
按照建议升级到:Nginx 1.16.1,下载地址:https://nginx.org/download/nginx-1.16.1.tar.gz
二、升级过程
2.1、前要
Nginx 在启动后,会有一个 master 进程和多个 worker 进程。
master进程:接受外界的信号,向worker 发送信号,监控 worker 进程的运行状态,当 worker 进程退出后 (异常情况下),会自动重新启动新的 worker 进程
worker进程:接受客户端的请求,将请求一次送入各个功能模块进行过滤处理,与后端服务器通信,接收后端服务器处理结果,数据缓存 proxy_cache 模块,响应客户端请求
多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其它进程的请求。
2.2、升级过程
1、登录云主机rz上述安装包到系统内,然后解压
2、备份旧版本的nginx的执行程序;
3、进入新版本源码包目录,编译处理(因业务需要https)
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-http_realip_module
由上图可知nginx的目录后不应写/,再次编译:
编译完成后,执行make:
4、进入到源码包目录的objs目录:
新生成的:
复制其下的nginx二进制文件到nginx应用目录的二进制sbin下;
5、发送USR2信号给旧版本主进程号,使nginx的旧版本停止接收请求,用nginx新版本接替,且老进程处理完所有请求,关闭所有连接后,停止或直接pkill掉nginx
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
验证:查看nginx pid目录,多了个nginx.pid.oldbin文件,存放了旧版本nginx的pid号
关闭旧进程:kill -QUIT cat nginx.pid.oldbin
6、进入nginx应用目录验证:
测试:
重新编译到nginx的根目录下:
./configure --user=nginx --group=nginx --prefix=/usr/local/app/nginx --with-http_v2_module --with-http_ssl_module --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-http_realip_module
再次测试OK:
7、启动nginx并验证:
8、浏览器登录站点
三、附录:
3.1 Kill命令信号说明
更多参看:signal.h;kill;Controlling nginx
QUIT :Graceful shutdown 优雅的关闭进程,即等请求结束后再关闭
HUP : Configuration reload ,Start the new worker processes with a new configuration Gracefully shutdown the old worker processes。改变配置文件,平滑的重读配置文件
USR1 :Reopen the log files 重读日志,在日志按月/日分割时有用
USR2 : Upgrade Executable on the fly 平滑的升级,使用新版本的nginx文件启动服务,之后平缓停止原有nginx进程,也就是所谓的“平滑升级”。
WINCH : Gracefully shutdown the worker processes 优雅关闭旧的进程(配合USR2来进行升级)
如上所示,SIGTERM或者SIGINT信号,会让nginx快速退出。SIGQUIT信号,会让nginx优雅退出,就是资源主动释放干净、日志正常关闭、SOCKET正常关闭,但会慢一些退出。SIGUSR1信号,会让nginx重新打开日志文件,这明显是一个nginx自己的独特行为。每个进程都可以将各种信号定义成自己的独特行为。USR1亦通常被用来告知应用程序重载配置文件;注意:在POSIX兼容的平台上,SIGUSR1和SIGUSR2是发送给一个进程的信号,它表示了用户定义的情况。它们的符号常量在头文件signal.h中定义。在不同的平台上,信号的编号可能发生变化,因此需要使用信号名称。
USR1信号将导致以下步骤的发生:
停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。
nginx中你会发现,kill -HUP $PID时,进程被重启了。而使用kill -USR1 $PID时,则进程不会重启。
USR2信号过程:
Nginx服务接收到USR2信号后,首先将旧的nginx.pid文件(如果在配置文件中更改过这个文件的名字,也是相同的过程)添加后缀.oldbin,变为nginx.pid.oldbin文件;然后执行新版本Nginx服务器的二进制文件启动服务.如果新的服务启动成功,系统中将有新旧两个Nginx服务共同提供Web服务.之后,需要向旧的Nginx服务进程发送WINCH信号,使旧的Nginx服务平滑停止,并删除nginx.pid.oldbin文件.在发送WINCH信号之前,可以随时停止新的Nginx 服务。
注意事项:
1、 新的服务器安装路径应该和旧的保持一致、在升级之前最后备份旧的nginx 。
2、安装之前在旧的nginx的sbin目录下执行./nginx -V 查看nginx 安装并启用了那些模块。
3、新的nginx 安装时 不执行 make install!!!
3.2 killall
yum install -y psmisc
apt-get install -y psmisc
-Z 只杀死拥有scontext 的进程
-e 要求匹配进程名称
-I 忽略小写
-g 杀死进程组而不是进程
-i 交互模式,杀死进程前先询问用户
-l 列出所有的已知信号名称
-q 不输出警告信息
-s 发送指定的信号
-v 报告信号是否成功发送
-w 等待进程死亡
–help 显示帮助信息
–version 显示版本显示