NGINX DNS解析漏洞(CVE-2021-23017)

一、漏洞情况说明:

Nginx DNS解析漏洞(CVE-2021-23017):
在处理DNS响应时,ngx_resolver_copy()中的一个off-by-one错误将允许网络攻击者在堆分配的缓冲区中写入超出
边界的点字符(‘.’, 0x2E)。配置解析程序原语时,响应nginx服务器DNS请求的DNS响应可能会触发该漏洞。精心构造的数据包可以通过使用0x2E覆盖下一个堆块元数据的最低有效字节,此时,能够向nginx服务器提供DNS响应的网络攻击者可以实现拒绝服务攻击或远程代码执行攻击。
由于nginx中缺少DNS欺骗防御措施,并且在检查DNS事务ID之前调用了易受攻击的函数,因此远程攻击者可以通过在可行的时间内向目标服务器发送恶意DNS响应来利用该漏洞实施攻击。

二、影响范围:

Nginx DNS解析漏洞影响版本:
0.6.18 - 1.20.0
建议升级至1.20.1及以上版本

三、nginx1.20.1部署脚本

部署脚本如下:

#!/bin/bash
#################################
# copyright by hwb
# DATE:2021-05-05
#
# 自动化部署nginx 1.20
# 脚本及安装包统一放在/opt目录下
#################################

#nginx
NGINX_USER=nginx
NGINX_GROUP=nginx
NGINX_HOME=/usr/local/nginx
NGINX_PORT=80
NGINX_SOFTWARE=/opt/nginx

#调用函数库
[ -f /etc/init.d/functions ] && source /etc/init.d/functions
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
source /etc/profile

#Require root to run this script.
[ $(id -u) -gt 0 ] && echo "请用root用户执行此脚本!" && exit 1


function install_nginx_el7(){
  echo ""
  echo -e "\033[33m***********************************************自动部署nginx服务*****************************************************\033[0m"
  
  #建用户及目录
  groupadd -r nginx && useradd -r -g nginx nginx -d /home/nginx -m
  [ -d ${NGINX_SOFTWARE} ] || mkdir -p ${NGINX_SOFTWARE}

  #关闭selinux
  setenforce 0
  sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

#常用module
#ngx_http_core_module:核心模块;内置模块。
#ngx_http_upstream_module:“upstream”模块,内置模块,核心模块;用于请求的“负载均衡”。
#ngx_http_proxy_module:“请求代理”模块,核心模块;将请求转发给代理Server,或者对请求进行额外的cache操作。
#ngx_http_rewrite_module:“URL重写”模块,内置模块;根据规则,rewrite特定的URL并转发给代理Server。
#ngx_http_access_module:“访问控制”模块;“允许”或者“拒绝”特定的IP列表对server的访问,内置模块。
#ngx_http_limit_conn_module:“访问控制”模块;可以限定每个key(可以为客户端IP)允许的最大并发连接数,内置模块。
#ngx_http_limit_req_module:“访问控制”模块;可以限定每个key(可以为客户端IP)在单位之间内允许处理的request个数,“流量控制”,内置模块。
#ngx_http_headers_module:“header”模块;主要是“add_header”和“expired”两个指令,向response中添加header信息,内置模块。
#ngx_http_charset_module:“字符集”模块;在响应头部的“Content-Type”中增加charset信息,内置模块。
#ngx_http_addition_module:“增添”模块;在response内容之前或者之后额外添加文本信息,内置模块。
#ngx_http_sub_module:“后置修改响应”模块;可以过滤并替换response内容中特定的字符串,附加模块,需要在编译时指定“--with-http_sub_module”。
#ngx_http_fastcgi_module:将请求发送给“fastcgi”服务器,内置模块。
#ngx_http_geo_module:“geo”模块;创建一个变量,此变量的值由client ip值决定,对实现小型私有“CDN”方案有参考价值,内置模块。
#ngx_http_geoip_module:“geo”模块;通过配置(数据源)可以得知clientip所属的“城市”、“区域”等信息,对实现小型私有的CDN有一定的参考价值,附加模块,需要在编译时指定“--with-http_geoip_module”。
#ngx_http_gzip_module:“gzip”模块;对response使用gzip压缩,对减少数据传输量有益,内置模块。
#ngx_http_gzip_static_module:“gzip”模块;对response使用gzip压缩,输出为“.gz”文件,附加模块,需要在编译时指定“--with-http_gzip_static_module”。
#ngx_http_image_filter_module:“图片”模块;可以对“JPEG”、“GIF”、“PNG”格式的图片进行裁剪等操作,附加模块,需要在编译时指定“--with-http_image_filter_module”。
#ngx_http_status_module/ngx_http_stub_status_module:“nginx内部状态”模块;用于获取nginx内部的一些状态统计信息,通常用来获取一些简单的统计数据,其中nginx_http_stub_status_module为附加模块,编译时需要指定“--with-http_stub_status_module”。
#nginx-http-concat:第三方附加模块,由taobao开发,主要用于合并“静态资源”请求,提升性能,需要额外下载,并在编译时添加“--add-module=software/nginx-http-concat-master”。(https://github.com/alibaba/nginx-http-concat)
#ngx_cache_purge:第三方附加模块,由frickle提供,当在proxy中使用cache保存静态资源时,那么cache_purge模块提供删除过期数据的功能支持,需要额外下载,并在编译时添加“--add-module=software/ngx_cache_purge”。(http://labs.frickle.com/nginx_ngx_cache_purge/)
#nginx_upstream_check_module:第三方附加模块,由taobao开发,通过它检测后端 realserver的健康状态,如果后端 realserver 不可用,则请求就不会转发到该节点上,该模块需打补丁。
#nginx-module-vts:第三方附加模块,Nginx virtual host traffic status module,nginx的监控模块,能够提供json、html、prometheus格式的数据产出。
#nginx-sticky-module:第三方附加模块,sticky模块与Ip_hash都是与负载均衡算法相关,Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route。
#wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
#ngx_http_referer_module:内置模块,可根据header中的referer信息屏蔽某些请求对网站或应用的访问,可以起到禁止直接访问网站static files的作用(防盗链或保护文件)
#nginx-http-sysguard:阿里巴巴开发的一个 Nginx 模块,用来保护运行 Nginx 服务器的系统负载和内存使用不会太高,不支持最新版本。


  #下载nginx安装包
  if [ -f ${NGINX_SOFTWARE}/nginx-1.20.1.tar.gz ] && [ -f ${NGINX_SOFTWARE}/nginx_upstream_check_module-master.zip ] && [ -f ${NGINX_SOFTWARE}/nginx_upstream_check_module-master.zip ] && [ -f ${NGINX_SOFTWARE}/nginx-http-concat-master.zip ] && [ -f ${NGINX_SOFTWARE}/nginx-module-vts-master.zip ] && [ -f ${NGINX_SOFTWARE}/nginx-goodies-nginx-sticky-module-ng-08a395c66e42.tar.gz ] && [ -f ${NGINX_SOFTWARE}/ngx_cache_purge-2.3.tar.gz ];then
	  action "*****已存在nginx安装包,无需下载*****" /bin/true
  else
      ping -c 4 app.fslgz.com >/dev/null 2>&1
      if [ $? -eq 0 ];then
      	#wget http://nginx.org/download/nginx-1.20.1.tar.gz  -P /opt
        #wget https://codeload.github.com/alibaba/nginx-http-concat/zip/master  -P /opt
        #wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz   -P /opt
        #wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master -P /opt
        #wget https://codeload.github.com/vozlt/nginx-module-vts/zip/refs/heads/master -P /opt
		#wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz -P /opt
		#wget https://github.com/alibaba/nginx-http-sysguard/archive/master.zip -O nginx-http-sysguard-master.zip  -P /opt
		#wget --progress=bar:force https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839506330304708608 -O ${NGINX_SOFTWARE}/nginx-1.20.1.tar.gz 2>&1 | progressfilt
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=860117865959849984 -O ${NGINX_SOFTWARE}/nginx-1.20.1.tar.gz
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839568288638894080 -O ${NGINX_SOFTWARE}/nginx_upstream_check_module-master.zip
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839568884758544384 -O ${NGINX_SOFTWARE}/nginx-http-concat-master.zip
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839569060348887040 -O ${NGINX_SOFTWARE}/nginx-http-sysguard-master.zip
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839569209208930304 -O ${NGINX_SOFTWARE}/nginx-module-vts-master.zip
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839568746614947840 -O ${NGINX_SOFTWARE}/nginx-goodies-nginx-sticky-module-ng-08a395c66e42.tar.gz
		wget -q  https://app.fslgz.com/portal/api/public/fs/association/file/downLoad?uploadId=839569359721529344 -O ${NGINX_SOFTWARE}/ngx_cache_purge-2.3.tar.gz
		[ $? -eq 0 ] && action "nginx安装包及依赖包下载完成!" /bin/true
      else
        action "please download nginx package manual!" /bin/false
		exit $?
      fi
  fi
  
  #安装依赖包及打补丁
  yum -y install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel patch gd-devel libgd2-xpm libgd2-xpm-dev GeoIP-devel.x86_64 >/dev/null   
  [ $? -eq 0 ] || action "依赖包未安装成功" /bin/false || exit $?
  cd ${NGINX_SOFTWARE} && tar -xvf nginx-1.20.1.tar.gz >/dev/null  && unzip nginx_upstream_check_module-master.zip >/dev/null && unzip nginx-http-concat-master.zip >/dev/null && unzip nginx-http-sysguard-master.zip >/dev/null && unzip nginx-module-vts-master.zip >/dev/null  && tar -xvf ngx_cache_purge-2.3.tar.gz >/dev/null && tar -xvf nginx-goodies-nginx-sticky-module-ng-08a395c66e42.tar.gz >/dev/null &&  mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky-module
  chown -R root:root ${NGINX_SOFTWARE} && chmod -R 755 ${NGINX_SOFTWARE}
  action "*****开始打补丁*****" /bin/true
  cd ${NGINX_SOFTWARE}/nginx-1.20.1 
  patch -p1 < ../nginx_upstream_check_module-master/check_1.16.1+.patch
  #patch -p1 < ../nginx-http-sysguard-master/nginx_sysguard_1.3.9.patch
    
  #编译安装nginx 
  ps -ef|grep nginx |grep -v grep|grep -v sh
  if [ $? -eq 0 ] ;then
     action "*****已存在nginx进程*****" /bin/false
     exit $?
  else
	 # 卸载 nginx
	 rpm -qa|grep nginx|xargs -i rpm -e --nodeps {}
	# 安装nginx
	 action "*****编译安装nginx*****" /bin/true
	 cd ${NGINX_SOFTWARE}/nginx-1.20.1 
	 ./configure --user=${NGINX_USER} --group=${NGINX_GROUP} --prefix=${NGINX_HOME}  --with-threads --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module  --with-stream  --with-http_flv_module --with-http_mp4_module  --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" --with-file-aio --with-debug --with-cc-opt='-g -O0' --add-module=${NGINX_SOFTWARE}/nginx_upstream_check_module-master --add-module=${NGINX_SOFTWARE}/nginx-module-vts-master --add-module=${NGINX_SOFTWARE}/nginx-sticky-module  --add-module=${NGINX_SOFTWARE}/nginx-http-concat-master  --add-module=${NGINX_SOFTWARE}/ngx_cache_purge-2.3/  >/dev/null
	 make >/dev/null && make install >/dev/null
	 [ $? -eq 0 ] && action "*****nginx编译安装成功*****" /bin/true
  fi
  
cat > ${NGINX_HOME}/conf/nginx.conf <<EOF
user ${NGINX_USER} ${NGINX_GROUP};
#工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU
worker_processes  8;
worker_cpu_affinity auto;
#指定进程可以打开的最大描述符:数目
worker_rlimit_nofile 65535;
error_log  logs/error.log  notice;

events {
   #使用epoll的I/O 模型
    use epoll;
    accept_mutex off;
    worker_connections  65500;
}
http {
include       mime.types; #设定mime类型,类型由mime.type文件定义
default_type  application/octet-stream;
log_format main '[\$time_local] \$remote_addr - \$remote_user  "\$request" '
                '\$status \$body_bytes_sent "\$http_referer" '
                '"\$http_user_agent" "\$http_x_forwarded_for"';
log_format log404 '[\$time_local] \$status \$remote_addr \$host$request_uri \$sent_http_location';
access_log  logs/host.access.log  main;
access_log  logs/host.access.404.log  log404; #用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径;
sendfile        on; #指定 nginx 是否调用sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为on
tcp_nopush     on; #此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
tcp_nodelay on;
keepalive_timeout  600; #keepalive超时时间  
server_names_hash_bucket_size 128;
server_tokens off; #隐藏版本号
vhost_traffic_status_zone;  #流量监控,在server段增加/status配置
server {
        listen       ${NGINX_PORT};
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
		error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}
include gzip.conf;
include proxy.conf;
include vhosts/*.conf;
}
EOF

cat > ${NGINX_HOME}/conf/gzip.conf <<EOF
gzip on;
gzip_min_length 2k; #设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。
gzip_buffers 4 32k; #压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。
gzip_http_version 1.1;#压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可
gzip_comp_level 6; #压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。
gzip_proxied any;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on; #varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据
EOF

cat > ${NGINX_HOME}/conf/proxy.conf <<EOF
#client_header_timeout 60; 
client_body_timeout 60;
#client_header_buffer_size 1m; #客户端请求头部的缓冲区大小
#large_client_header_buffers 32 128k; #客户请求头缓冲大小
client_max_body_size       800m;  #通过nginx上传文件的大小
client_body_buffer_size    1024k; #Nginx分配给请求数据的Buffer大小,如果请求的数据小于client_body_buffer_size直接将数据先在内存中存储。如果请求的值大于client_body_buffer_size小于client_max_body_size,就会将数据先存储到临时文件中
reset_timedout_connection on;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Accept-Encoding 'gzip';
proxy_http_version 1.1;
proxy_set_header Connection "upgrade";
proxy_set_header Origin '';
proxy_redirect http:// https://;
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
proxy_connect_timeout      9000; #单位秒,后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_send_timeout         6000; #单位秒,后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_read_timeout         6000;  #单位秒,连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
proxy_ignore_client_abort  on;
proxy_buffer_size          256k; #设置从被代理服务器读取的第一部分应答的缓冲区大小
proxy_buffers              4 256k; #设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_busy_buffers_size    256k; 
proxy_temp_file_write_size 100m; #设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
proxy_temp_path ${NGINX_HOME}/proxy_temp; #proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
#proxy_cache_path ${NGINX_HOME}/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=1g; #设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
EOF
  mkdir -p ${NGINX_HOME}/conf/vhosts && mkdir -p ${NGINX_HOME}/proxy_temp && mkdir -p ${NGINX_HOME}/proxy_cache
  #配置开机启动
cat > /usr/lib/systemd/system/nginx.service <<EOF
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
  
[Service]
Type=forking
ExecStartPre=${NGINX_HOME}/sbin/nginx -t -c ${NGINX_HOME}/conf/nginx.conf
ExecStart=${NGINX_HOME}/sbin/nginx -c ${NGINX_HOME}/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
  
[Install]
WantedBy=multi-user.target
EOF

  chown -R ${NGINX_USER}:${NGINX_GROUP}  ${NGINX_HOME} && chmod -R 755 ${NGINX_HOME}
  #启动nginx服务
  action "*****启动nginx服务*****" /bin/true
  systemctl daemon-reload
  systemctl restart nginx.service
  systemctl enable nginx.service
  systemctl status nginx.service

echo -e "\033[33m************************************************完成nginx服务部署*************************************************\033[0m"
cat > /tmp/nginx.log  <<EOF
nginx安装目录:${NGINX_HOME}
NGINX版本:NGINX-1.20.1
NGINX端口:${NGINX_PORT}
NGINX服务:systemctl status nginx
EOF
  cat /tmp/nginx.log
  echo -e "\e[1;31m 以上信息10秒后消失,保存在/tmp/nginx.log文件下 \e[0m"
  echo -e "\033[33m*****************************************************************************************************************\033[0m"
  echo ""
  sleep 10
}


install_nginx_el7

忘记截图,就放一个状态好了…
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定波007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值