当前位置: 首页 > web >正文

nginx集成防火墙ngx_waf的docker版

由于公网的环境越来与严峻,所以想找一个nginx带防火墙的版本

调研过openresty,大部分集成redis了,感觉还是太重了,有一个不那么重的https://github.com/unixhot/waf 但是维护没有那么勤,最后维护是5年前,倒数第二次维护是十年前。

调研过雷池,也是基于tengine做的一个版本,配置就很繁琐。最后还是考虑基于nginx原生集成一个版本

这里使用的是:https://github.com/ADD-SP/ngx_waf

一、docker编译

编写Dockerfile

# ================= Stage 1: 构建 Nginx with WAF 模块 ==================
# 使用 Alpine 3.18 基础镜像作为构建阶段
FROM alpine:3.18 AS builderLABEL maintainer="eric@slant.co"# 设置版本号
ENV NGINX_VERSION=1.22.0 \WAF_VERSION=6.1.9 \LIBINJECTION_VERSION=3.10.0 \UTHASH_VERSION=2.3.0# 替换 Alpine 的官方源为阿里云源
#RUN sed -i 's|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g' /etc/apk/repositories && \
#    apk update && \
#    apk upgrade# 安装构建依赖
RUN apk add --no-cache --virtual .build-deps \gcc \libc-dev \make \openssl-dev \pcre-dev \zlib-dev \linux-headers \curl \gnupg \libxslt-dev \gd-dev \geoip-dev \perl-dev \flex \bison \unzip \libsodium-dev \tar \gzip \zip# 创建目录并下载 Nginx 和 WAF 模块
WORKDIR /usr/src# 下载并解压 Nginx
RUN curl -fSL http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -o nginx.tar.gz && \tar -zxC /usr/src -f nginx.tar.gz && \rm -rf nginx.tar.gz# 下载并解压 ngx_waf 模块
RUN curl -fSL https://github.com/ADD-SP/ngx_waf/archive/refs/tags/v${WAF_VERSION}.tar.gz -o ngx_http_waf_module.tar.gz && \tar -zxC /usr/src -f ngx_http_waf_module.tar.gz && \mv /usr/src/ngx_waf-${WAF_VERSION} /usr/src/ngx_http_waf_module && \rm -rf ngx_http_waf_module.tar.gz# 安装 libinjection(用于 WAF)
RUN mkdir -p /usr/src/ngx_http_waf_module/inc && \curl -fSL https://github.com/libinjection/libinjection/archive/refs/tags/v${LIBINJECTION_VERSION}.zip -o libinjection.zip && \unzip libinjection.zip -d /usr/src/ngx_http_waf_module/inc/ && \mv /usr/src/ngx_http_waf_module/inc/libinjection-${LIBINJECTION_VERSION} /usr/src/ngx_http_waf_module/inc/libinjection && \rm -rf libinjection.zip# 安装 uthash(用于 WAF)
RUN mkdir -p /usr/local/src && \curl -fSL https://github.com/troydhanson/uthash/archive/refs/tags/v${UTHASH_VERSION}.tar.gz -o uthash.tar.gz && \tar -zxC /usr/local/src -f uthash.tar.gz && \mv /usr/local/src/uthash-${UTHASH_VERSION} /usr/local/src/uthash && \rm -rf uthash.tar.gz# 编译 WAF 模块
WORKDIR /usr/src/ngx_http_waf_module
ENV LIB_UTHASH=/usr/local/src/uthash
RUN make# 配置和编译 Nginx
WORKDIR /usr/src/nginx-${NGINX_VERSION}
ENV CONFIG="--prefix=/etc/nginx \--sbin-path=/usr/sbin/nginx \--modules-path=/usr/lib/nginx/modules \--conf-path=/etc/nginx/nginx.conf \--error-log-path=/var/log/nginx/error.log \--http-log-path=/var/log/nginx/access.log \--pid-path=/var/run/nginx.pid \--lock-path=/var/run/nginx.lock \--http-client-body-temp-path=/var/cache/nginx/client_temp \--http-proxy-temp-path=/var/cache/nginx/proxy_temp \--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \--http-scgi-temp-path=/var/cache/nginx/scgi_temp \--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-http_xslt_module=dynamic \--with-http_image_filter_module=dynamic \--with-http_geoip_module=dynamic \--with-http_perl_module=dynamic \--with-threads \--with-stream \--with-stream_ssl_module \--with-stream_ssl_preread_module \--with-stream_realip_module \--with-stream_geoip_module=dynamic \--with-http_slice_module \--with-mail \--with-mail_ssl_module \--with-compat \--with-file-aio \--with-http_v2_module \--add-module=/usr/src/ngx_http_waf_module"# 创建用户组和用户
RUN addgroup -S nginx && \adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx# 配置、编译安装 Nginx
RUN ./configure $CONFIG --with-debug && \make -j$(getconf _NPROCESSORS_ONLN) && \make install && \strip /usr/sbin/nginx* && \strip /usr/lib/nginx/modules/*.so# 清理无用文件
RUN rm -rf /etc/nginx/html/* && \mkdir -p /etc/nginx/conf.d && \mkdir -p /usr/share/nginx/html && \cp html/index.html /usr/share/nginx/html/ && \cp html/50x.html /usr/share/nginx/html/# ================ Stage 2: 最终运行时镜像 ==================
FROM alpine:3.18# 替换 Alpine 的官方源为阿里云源(可选)
#RUN sed -i 's|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g' /etc/apk/repositories# 更新索引并安装 tzdata
RUN apk update && \apk add --no-cache tzdata && \cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \echo "Asia/Shanghai" > /etc/timezone
# 复制构建阶段中的必要文件
COPY --from=builder /usr/sbin/ /usr/sbin/
COPY --from=builder /usr/lib/nginx/ /usr/lib/nginx/
COPY --from=builder /etc/nginx/ /etc/nginx/
COPY --from=builder /usr/share/nginx/html/ /usr/share/nginx/html
# 新增:复制 ngx_waf 的 assets 资源目录
COPY --from=builder /usr/src/ngx_http_waf_module/assets /usr/local/src/ngx_waf/assets# 创建 nginx 用户和目录
RUN addgroup -S nginx && \adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx && \mkdir -p /var/log/nginx /var/cache/nginx && \ln -sf /dev/stdout /var/log/nginx/access.log && \ln -sf /dev/stderr /var/log/nginx/error.log# 安装运行时依赖
RUN apk add --no-cache \libgcc \libstdc++ \pcre \openssl \zlib \libxslt \gd \geoip \perl \libsodium# 安装 Bash
RUN apk add --no-cache bash bash-doc bash-completion# 设置默认的shell为Bash
RUN echo "/bin/bash" >> /etc/shells && \sed -i 's|/bin/ash$|/bin/bash|' /etc/passwd# 可选:复制配置文件
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf# 开放端口
EXPOSE 80 443# 设置停止信号
STOPSIGNAL SIGTERM# 启动命令
CMD ["nginx", "-g", "daemon off;"]

使用到的文件

nginx.conf


user  nginx;
worker_processes  auto;error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;events {worker_connections  1024;
}http {include       /etc/nginx/mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile        on;#tcp_nopush     on;keepalive_timeout  65;#gzip  on;include /etc/nginx/conf.d/*.conf;
}

default.conf

server {listen       80;listen  [::]:80;server_name  localhost;#access_log  /var/log/nginx/host.access.log  main;location / {root   /usr/share/nginx/html;index  index.html index.htm;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   /usr/share/nginx/html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {#    proxy_pass   http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {#    root           html;#    fastcgi_pass   127.0.0.1:9000;#    fastcgi_index  index.php;#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;#    include        fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#    deny  all;#}
}

编译

docker build -t nginx-waf:1.22.0 .

运行

docker run -itd --name nginx-waf -p80:80 nginx-waf:1.22.0

访问

http://ip:80

二、防火墙功能简单验证

简单的防火墙测试

进入容器,修改default.conf文件 在第一个server增加如下内容

docker exec -it nginx-waf sh

cd /etc/nginx/conf.d

vi default.conf

    waf on;# 规则文件所在目录的绝对路径,必须以 / 结尾。waf_rule_path /usr/local/src/ngx_waf/assets/rules/;# 防火墙工作模式,STD 表示标准模式。waf_mode STD;# CC 防御参数,1000 每分钟请求次数上限,超出上限后封禁对应 ip 60 分钟。waf_cc_deny rate=1000r/m duration=60m;# 最多缓存 50 个检测目标的检测结果,对除了 IP 黑白名单检测、CC 防护和 POST 检测以外的所有检测生效。waf_cache capacity=50;

进入容器的/usr/local/src/ngx_waf/assets/rules目录,修改user-agent文件内容,在最后添加

cd /usr/local/src/ngx_waf/assets/rules

vi user-agent

(?i)(?:Edg)

最后退出容器,然后重启容器,这样edge浏览器访问会报403,chrome浏览器访问正常

具体文档参考:配置 | ngx_waf

在封禁ipv4时有时候会有一些手误造成ip填写不规范,可以用下面的脚本检测IPv4的CIDR地址。

check_cidr.sh

#!/bin/bash# 检查参数
if [ $# -ne 2 ]; thenecho "Usage: $0 <input_file> <output_file>"exit 1
fiINPUT_FILE="$1"
OUTPUT_FILE="$2"# 清空输出文件
> "$OUTPUT_FILE"# 检查是否安装了 ipcalc
if ! command -v ipcalc &> /dev/null; thenecho "Error: 'ipcalc' is not installed."echo "Please install it first (e.g., sudo apt install ipcalc)"exit 1
fi# 逐行处理输入文件
while IFS= read -r line; docidr=$(echo "$line" | sed 's/[[:space:]]//g')  # 去除所有空白字符if [[ -z "$cidr" ]]; thencontinuefi# 使用 ipcalc 验证 CIDR 合法性(无参数模式)if ipcalc "$cidr" 2>/dev/null | grep -q "^Network:"; thenecho "$cidr" >> "$OUTPUT_FILE"elseecho "Invalid CIDR removed: $cidr"fi
done < "$INPUT_FILE"echo "Valid CIDRs saved to: $OUTPUT_FILE"

执行方法

chmod +x check_cidr.sh

./check_cidr.sh ipv4 output.txt

http://www.xdnf.cn/news/7000.html

相关文章:

  • 重庆 ICPC 比赛游记
  • Vue 3.0中响应式依赖和更新
  • list重点接口及模拟实现
  • 从复杂系统(杂多集合的实例)到智慧系统(理想集合的建构)
  • docker迅雷自定义端口号、登录用户名密码
  • 【嵌入式项目-MCU代码2】
  • Bitmap、Roaring Bitmap、HyperLogLog对比介绍
  • BootCDN介绍(Bootstrap主导的前端开源项目免费CDN加速服务)
  • LLM笔记(二)LLM数据基础-分词算法(2)
  • Linux面试题集合(1)
  • 前端扫盲HTML
  • 深入理解构造函数,析构函数
  • 威布尔比例风险模型(Weibull Proportional Hazards Model, WPHM)详解:原理、应用与实施
  • MATLAB进行深度学习网络训练
  • WSL 安装 Debian 12 后,如何安装图形界面 X11 ?
  • 【论文#目标检测】End-to-End Object Detection with Transformers
  • 在Maven中使用Ant插件
  • 【和春笋一起学C++】(十四)指针与const
  • 50个Python常用的模块,配对应的官网文档!!
  • 专业技术知识和技能,机械泵场效应管短路维修方法主要步骤方法
  • Linux_ELF文件
  • 【EDA软件】【联合Modelsim仿真使用方法】
  • 数据结构*优先级队列(堆)
  • 【笔记】正弦量的相量表示
  • 字体样式集合
  • (4)python爬虫--JsonPath
  • 框架之下再看HTTP请求对接后端method
  • 深度学习模型基本框架
  • Node.js 源码概览
  • 软件调试纵横谈-16-堆概要