1.说明
CVE-2016-4450,可通过构造特定数据包,可引发nginx引用空指针,导致nginx出错从而造成拒绝服务攻击。
影响1.3.9到1.11.0的所有版本,进行修复的1.10.1和1.11.1都发布于2016年5月31日,这就决定了凡是这日期之前安装的nginx都必然存在这个漏洞。
对漏洞修复而言,最麻烦的一是可能是因为这个漏洞比较严重也可能是因为poc比较简单,扫描器一般对这个漏洞使用原理扫描,隐藏版本号的做法就没用了;
二是nginx一般用作负载均衡,负载均衡意味意一是需要手动编译进行定制化,二是需要安装负载均衡相关的插;更简单些就是,升级不是随便make就完事了。
2.下载
下载页面:http://nginx.org/en/download.html
所有版本下载页面:http://nginx.org/download/
3.升级
升级nginx,为了避免重新部署应用了或重新配置的麻烦,最合适的做法是重新编译一个nginx二进制文件,替换旧的nginx二进制文件,然后重启nginx。
但是如果只是不管不顾地随便下载nginx,然后configure--make--make install编译,那生成nginx要么由于路径与原先不一致运行不了,要么即便运行得了但由于参数不一致造成应用出现异常。
推荐的做法是在本地构建一个与服务器相一致的环境(这里的环境主要指操作系统大版本,插件版本,文件目录),在本地编译后再传到服务器替换旧的nginx二进制文件。(直接在服务端编译也可以但是这就要先将当前nginx停掉并将其目录先移走)
3.1到服务端查看旧版本nginx编译参数
到服务器端,进入$NGINX_HOME/sbin目录,执行以下命令查看其编译参数:
./nginx -V
3.2 在本地构建与服务端相“一致”的环境
操作系统版本--操作系统大版本要相一致,比如都是CentOS7.x版本或者都是CentOS6.x版本;RHEL6.x与CentOS6.x也算相一致。
插件版本--插件版本这一项并没有进行验证,但是经验来看版本升级后有可能编译步骤需要调整。所以上一步得到的编译参数的那些插件,如果可以确认这些插件版本或者直接就保存有插件源码包那还是直接用的好。
文件目录--就是服务器安装nginx的目录,本地也得编译生成在同样的目录不然替换后启动不了。
用户--进行编译的用户倒没什么要求,最后替换时文件归属原先nginx所属的用户即可。
附上图编译参数中用到的插件及其下载地址:
nginx_upstream_check:https://github.com/yaoweibin/nginx_upstream_check_module
nginx-upstream-fair:https://github.com/gnosek/nginx-upstream-fair
nginx-sticky-module:https://github.com/michaelneale/nginx-sticky-module
ngx_cache_purge:https://github.com/FRiCKLE/ngx_cache_purge
openssl:https://www.openssl.org/source/
pcre:https://ftp.pcre.org/pub/pcre/
zlib:https://sourceforge.net/projects/libpng/files/zlib/
3.3在本地编译生成nginx二进制文件
将要用的各插件下载并解压到与编译参数中相同的目录下,然后执行编译命令(这里只以我的为例,具体目录根据自己的修改):
./configure --prefix=/ztesoft/nginx --http-client-body-temp-path=/ztesoft/nginx/cache/client_temp --http-proxy-temp-path=/ztesoft/nginx/cache/proxy_temp --http-fastcgi-temp-path=/ztesoft/nginx/cache/fastcgi_temp --http-uwsgi-temp-path=/ztesoft/nginx/cache/uwsgi_temp --http-scgi-temp-path=/ztesoft/nginx/cache/scgi_temp --add-module=/ztesoft/soft/nginx_upstream_check --add-module=/ztesoft/soft/nginx-upstream-fair --add-module=/ztesoft/soft/nginx-sticky-module --add-module=/ztesoft/soft/ngx_cache_purge --with-mail=dynamic --with-stream=dynamic --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream_ssl_module --with-http_slice_module --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-ipv6 --with-openssl=/ztesoft/soft/openssl --with-pcre=/ztesoft/soft/pcre --with-zlib=/ztesoft/soft/zlib make make install
3.4 将编译生成的nginx二进制文件上传到服务器替换并重启nginx
要注意几点:
注意上传的nginx文件所属用户已和原nginx一样
上传的nginx文件可能没有执行权限,要给其增加可执行权限
在停止当前nginx前要使用nginx -t查看其当前使用的配置文件,不然停了就不懂nginx该用哪个配置文件启了
./nginx -t #查看nginx启动所用的配置文件,以备稍后重新启动时使用
./nginx -s stop #停止nginx命令,停完后替换nginx文件 ./nginx -c /path/to/config_file #启动nginx文件,替换完nginx文件后再重启
3.5 编译过中遇到的错误及处理办法
报错一:make -f objs/Makefile
make[1]: Entering directory `/ztesoft/soft/nginx-1.12.2'
cd /ztesoft//soft/pcre
&& if [ -f Makefile ]; then make distclean; fi
&& CC="cc" CFLAGS="-O2 -fomit-frame-pointer -pipe "
./configure --disable-shared
/bin/sh: line 2: ./configure: No such file or directory
make[1]: *** [/ztesoft//soft/pcre/Makefile] Error 127
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
make: *** [build] Error 2
处理:确保--with-pcre参数正确指向了pcre源码包解压到的目录
报错二:checking for windows.h... no
configure: error: You need a C++ compiler for C++ support.
make[1]: *** [/ztesoft/soft/pcre/Makefile] Error 1
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
make: *** [build] Error 2
处理:yum install -y gcc-c++
报错三:cd /ztesoft/soft/openssl
&& if [ -f Makefile ]; then make clean; fi
&& ./config --prefix=/ztesoft/soft/openssl/.openssl no-shared
&& make
&& make install_sw LIBDIR=lib
/bin/sh: line 2: ./config: No such file or directory
make[1]: *** [/ztesoft/soft/openssl/.openssl/include/openssl/ssl.h] Error 127
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2
处理:指定openssl的源代码位置
报错四:src/http/modules/ngx_http_log_module.c:13:18: fatal error: zlib.h: No such file or directory
#include <zlib.h>
^
compilation terminated.
make[1]: *** [objs/src/http/modules/ngx_http_log_module.o] Error 1
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
make: *** [build] Error 2
处理:确保--with-zlib参数正确指向了zlib的源代码包解压到的目录
报错五:make -f objs/Makefile
make[1]: Entering directory `/ztesoft/soft/nginx-1.12.2'
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I /ztesoft/soft/nginx_upstream_check -I /ztesoft/soft/pcre -I /ztesoft/soft/openssl/.openssl/include -I /ztesoft/soft/zlib -I objs -I src/http -I src/http/modules -I src/http/v2 -I src/mail -I src/stream
-o objs/addon/nginx-upstream-fair/ngx_http_upstream_fair_module.o
/ztesoft/soft/nginx-upstream-fair/ngx_http_upstream_fair_module.c
/ztesoft/soft/nginx-upstream-fair/ngx_http_upstream_fair_module.c: In function ngx_http_upstream_init_fair_rr’:
/ztesoft/soft/nginx-upstream-fair/ngx_http_upstream_fair_module.c:543:28: error: ‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’
if (us->port == 0 && us->default_port == 0) {
^
/ztesoft/soft/nginx-upstream-fair/ngx_http_upstream_fair_module.c:553:51: error: ‘ngx_http_upstream_srv_conf_t’ has no member named ‘default_port’
u.port = (in_port_t) (us->port ? us->port : us->default_port);
^
make[1]: *** [objs/addon/nginx-upstream-fair/ngx_http_upstream_fair_module.o] Error 1
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
处理:到nginx的src/http/ngx_http_upstream.h文件找到ngx_http_upstream_srv_conf_s结构添加in_port_t default_port;
参考:http://www.mamicode.com/info-detail-89267.html
报错六:/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_module.c: In function ‘ngx_http_get_sticky_peer’:
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_module.c:312:59: error: ‘ngx_http_upstream_rr_peer_t’ has no member named ‘check_index’
if (ngx_http_upstream_check_peer_down(peer->check_index)) {
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_module.c:338:60: error: ‘ngx_http_upstream_rr_peer_t’ has no member named ‘check_index’
if (!ngx_http_upstream_check_peer_down(peer->check_index)) {
^
make[1]: *** [objs/addon/nginx-sticky-module/ngx_http_sticky_module.o] Error 1
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
处理:确保有--add-module参数正确指向了nginx-sticky源代码包解压到的目录
报错七:make -f objs/Makefile
make[1]: Entering directory `/ztesoft/soft/nginx-1.12.2'
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I /ztesoft/soft/nginx_upstream_check -I /ztesoft/soft/pcre -I /ztesoft/soft/openssl/.openssl/include -I /ztesoft/soft/zlib -I objs -I src/http -I src/http/modules -I src/http/v2 -I src/mail -I src/stream
-o objs/addon/nginx-sticky-module/ngx_http_sticky_module.o
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_module.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I /ztesoft/soft/nginx_upstream_check -I /ztesoft/soft/pcre -I /ztesoft/soft/openssl/.openssl/include -I /ztesoft/soft/zlib -I objs -I src/http -I src/http/modules -I src/http/v2 -I src/mail -I src/stream
-o objs/addon/nginx-sticky-module/ngx_http_sticky_misc.o
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c: In function ‘ngx_http_sticky_misc_md5’:
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:152:15: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
u_char hash[MD5_DIGEST_LENGTH];
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:152:15: note: each undeclared identifier is reported only once for each function it appears in
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:152:10: error: unused variable ‘hash’ [-Werror=unused-variable]
u_char hash[MD5_DIGEST_LENGTH];
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c: In function ‘ngx_http_sticky_misc_hmac_md5’:
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:189:15: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
u_char hash[MD5_DIGEST_LENGTH];
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:190:12: error: ‘MD5_CBLOCK’ undeclared (first use in this function)
u_char k[MD5_CBLOCK];
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:190:10: error: unused variable ‘k’ [-Werror=unused-variable]
u_char k[MD5_CBLOCK];
^
/ztesoft/soft/nginx-sticky-module/ngx_http_sticky_misc.c:189:10: error: unused variable ‘hash’ [-Werror=unused-variable]
u_char hash[MD5_DIGEST_LENGTH];
^
cc1: all warnings being treated as errors
make[1]: *** [objs/addon/nginx-sticky-module/ngx_http_sticky_misc.o] Error 1
make[1]: Leaving directory `/ztesoft/soft/nginx-1.12.2'
处理:解决方式就是修改在你下载解压缩之后的sticky模块文件夹中的ngx_http_sticky_misc.c文件
将 <openssl/sha.h>和<openssl/md5.h>这两个模块包含到文件ngx_http_sticky_misc.c中
参考:http://blog.csdn.net/zbc496218/article/details/52515247