Linux安全技术
ubuntu14.04 BIND漏洞修复
查询版本
named -v
BIND 9.9.5-3-Ubuntu (Extended Support Version)
查看可安装的BIND版本
apt-cache policy bind9
如果有较新的版本用下面命令安装
sudo apt-get install bind9
可更新到9.11.19
在 Ubuntu 14.04 中卸载 Bind9 可以按照以下步骤进行:
一、停止 Bind9 服务
如果 Bind9 正在运行,先停止服务:
plaintext
复制
sudo service bind9 stop
二、卸载 Bind9 软件包
使用 apt-get 命令卸载:
plaintext
复制
sudo apt-get remove bind9
这将删除 Bind9 软件包,但可能会留下一些配置文件。
如果想要彻底清除包括配置文件在内的所有相关内容,可以使用 purge 选项:
plaintext
复制
sudo apt-get purge bind9
三、检查是否卸载干净
可以使用以下命令查看系统中是否还有与 Bind9 相关的软件包:
plaintext
复制
dpkg -l | grep bind9
如果没有输出任何内容,说明 Bind9 已被完全卸载。
也可以检查相关的目录,如 /etc/bind 是否还存在。如果存在,可以手动删除(但要谨慎操作,确保没有重要数据):
plaintext
复制
sudo rm -rf /etc/bind
请注意,在卸载任何软件时,确保你了解其后果,并备份重要的数据和配置文件。同时,卸载 Bind9 可能会影响依赖于域名解析服务的其他应用程序或服务。如果需要重新安装或使用其他域名解析服务,应做好相应的规划和配置。
设置zookeeper白名单
一、白名单方式
# 设置zookeeper白名单
# /usr/local/zookeeper-3.4.13/bin/zkCli.sh -server 127.0.0.1:2181
> setAcl /zookeeper ip:127.0.0.1:cdrwa
> setAcl /dubbo ip:127.0.0.1:cdrwa
> getAcl /zookeeper
> getAcl /dubbo
二、用户账号认证
1 加密用户密码
# echo -n admin:shuncom2004 | openssl dgst -binary -sha1 | openssl base64
j9pfb5lKAqerIC8/RmfV2Iq+1HQ=
2 设置权限
# /usr/local/zookeeper-3.4.13/bin/zkCli.sh -server 127.0.0.1:2181
> setAcl /zookeeper digest:admin:j9pfb5lKAqerIC8/RmfV2Iq+1HQ=:cdrwa
> getAcl /zookeeper
'digest,'admin:j9pfb5lKAqerIC8/RmfV2Iq+1HQ=
: cdrwa
> ls /zookeeper
Authentication is not valid : /zookeeper
# 授权登录
> addauth digest admin:shuncom2004
> ls /zookeeper
[quota]
三、老平台端口防火墙
# vsftpd相关
firewall-cmd --add-port=33880/tcp --permanent
firewall-cmd --add-port=10001-10005/tcp --permanent
firewall-cmd --add-port=30080/tcp --permanent
# 驱动
firewall-cmd --add-port=6011/tcp --permanent
firewall-cmd --add-port=6013/tcp --permanent
firewall-cmd --add-port=6014/tcp --permanent
firewall-cmd --add-port=6012/udp --permanent
# tomcat
firewall-cmd --add-port=8080/tcp --permanent
# shuncom-connect.jar
firewall-cmd --add-port=8088/tcp --permanent
firewall-cmd --add-port=8089/tcp --permanent
firewall-cmd --add-port=8094/tcp --permanent
firewall-cmd --add-port=8099/tcp --permanent
firewall-cmd --add-port=8091/tcp --permanent
# connect2-server.jar
firewall-cmd --add-port=8074/tcp --permanent
firewall-cmd --add-port=9097/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all
OpenSSH_6.6.1p1升级到openssh-9.1p1
1.1 升级zlib
tar -xzf zlib-1.2.11.tar.gz && cd zlib-1.2.11
升级openssh用到的目录,确保目录底下有lib目录(库文件)
./configure --prefix=/usr/local/zlib && make -j 8 && make install
更新动态链接库
echo "/usr/local/zlib/lib" >> /etc/ld.so.conf
ldconfig -v
1.2 升级openssl
tar -xzf openssl-OpenSSL_1_1_0k.tar.gz
注意加参数--shared,才能在/usr/local/openssl目录生成lib等文件,后续升级openssh会用到
./config --prefix=/usr/local/openssl --shared && make -j 8 && make install
mv /usr/bin/openssl /usr/bin/openssl_bak && mv /usr/include/openssl/ /usr/include/openssl_bak/
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl && ln -s /usr/local/openssl/include/openssl/ /usr/include/openssl
(注意此处软链接需要按住实际路径)
更新动态链接库
echo "/usr/local/openssl/lib" > /etc/ld.so.conf.d/openssl.conf
ldconfig -v
1.3 升级openssh
tar -xzf openssh-9.1p1.tar.gz
mv /etc/ssh/ /etc/ssh_bak/ && mv /etc/init.d/ssh /etc/init.d/ssh_bak && mv /usr/bin/ssh /usr/bin/ssh_bak && cd openssh-9.1p1/
不加参数--with-pam,否则会报错configure: error: PAM headers not found
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-md5-passwords --with-zlib=/usr/local/zlib --with-ssl-dir=/usr/local/openssl --with-privsep-path=/var/lib/sshd
make -j 8 && make install
1.4 升级openssh 9.8p1
tar -xzf openssl-1.1.1w.tar.gz
cd openssl-1.1.1w
./config --prefix=/usr/local/openssl --shared && make -j 8 && make install
mv /usr/bin/openssl /usr/bin/openssl_bak && mv /usr/include/openssl/ /usr/include/openssl_bak/
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl && ln -s /usr/local/openssl/include/openssl/ /usr/include/openssl
(注意此处软链接需要按住实际路径)
更新动态链接库
echo "/usr/local/openssl/lib" > /etc/ld.so.conf.d/openssl.conf
ldconfig -v
tar -xzf openssh-9.8p1.tar.gz
cd openssh-9.8p1
./configure --prefix=/usr --sysconfdir=/etc/ssh --with-md5-passwords --with-zlib=/usr/local/zlib --with-ssl-dir=/usr/local/openssl --with-privsep-path=/var/lib/sshd
make -j 8 && make install
查看是否升级成功
ssh -V
拷贝源文件目录中的sshd.init
cp -a contrib/redhat/sshd.init /etc/init.d/ssh &&\
vim /etc/ssh/sshd_config
修改配置中的以下参数,使之和原来配置信息保持一致
PermitRootLogin yes
PasswordAuthentication yes
修改sshd_config文件立即生效
service ssh reload && service ssh restart && service ssh status
跨源资源共享(CORS)配置不当导致安全漏洞
要避免 跨源资源共享(CORS) 配置不当导致安全漏洞,可以按照以下措施配置您的 Web 服务器或应用程序,以实现更安全的跨域资源共享设置。
关键安全措施
1. 明确指定允许的域名
避免通配符:Access-Control-Allow-Origin: * 允许任何来源访问资源,这是一个常见的安全风险。
正确配置:指定允许访问的可信域名。例如:
Access-Control-Allow-Origin: https://trusted-domain.com
2. 限制凭证的跨域传递
默认情况下禁用凭证:跨源请求的凭证(如 cookies 和 HTTP 认证)通常不需要被传递。
仅在必要时启用:如果必须使用凭证跨域,则需设置 Access-Control-Allow-Credentials: true,并且不能使用通配符:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://trusted-domain.com
3. 限制允许的 HTTP 方法
只允许必要的 HTTP 方法,避免暴露不必要的操作。例如:
Access-Control-Allow-Methods: GET, POST
4. 限制允许的请求头
控制客户端可以发送哪些自定义头,避免滥用。例如:
Access-Control-Allow-Headers: Content-Type, Authorization
5. 设置预检请求的缓存时间
使用 Access-Control-Max-Age 限制预检请求的缓存时间,避免长期缓存不安全的策略。例如:
Access-Control-Max-Age: 600
6. 严格控制资源的跨域访问范围
对于敏感资源,应限制 CORS 的使用,避免在未经验证的来源加载敏感数据。
Nginx 示例配置
以下是 Nginx 中的安全 CORS 配置示例:
server {
listen 80;
server_name api.example.com;
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://trusted-domain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' '600';
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://backend-server;
}
}
Apache 示例配置
以下是 Apache 中的安全 CORS 配置示例:
ServerName api.example.com
Header set Access-Control-Allow-Origin "https://trusted-domain.com"
Header set Access-Control-Allow-Methods "GET, POST"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Max-Age "600"
# 允许预检请求返回 204
Header always set Content-Length "0"
Header always set Content-Type "text/plain"
Require all granted
后端动态 CORS 配置示例
在某些情况下,您可能需要动态确定允许的域名。以下是使用 Python Flask 实现的示例:
from flask import Flask, request, jsonify
app = Flask(__name__)
ALLOWED_ORIGINS = ["https://trusted-domain.com"]
@app.after_request
def add_cors_headers(response):
origin = request.headers.get('Origin')
if origin in ALLOWED_ORIGINS:
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Methods'] = 'GET, POST'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response
@app.route('/api/data', methods=['GET', 'POST'])
def api_data():
return jsonify({"message": "Hello, World!"})
if __name__ == "__main__":
app.run()
额外建议
定期审查和更新 CORS 配置:确保仅允许当前必要的域名、方法和请求头。
启用 HTTPS:确保跨域访问时数据在传输中被加密。
结合 CSRF 防护:对于跨域请求中涉及用户认证的操作,结合 CSRF 令牌验证机制。
通过以上措施,可以有效避免 CORS 配置不当带来的安全风险。
nginx-1.24.0升级到1.27.0
不需要卸载 nginx-1.24.0,你可以直接安装 nginx-1.27.0 并在需要时切换版本。但如果你希望移除旧版本以释放空间,可以选择手动删除 nginx-1.24.0。
sudo /usr/local/nginx-1.24.0/sbin/nginx -s stop
在 Ubuntu 14.04 上,你可以通过编译并以二进制方式安装 Nginx 1.27.0,同时指定安装路径并启用 SSL 模块。以下是具体步骤:
1. 安装依赖
首先,确保你的系统已安装必要的依赖项:
sudo apt-get update
sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev
2. 下载并解压 Nginx 源码
cd /usr/local/src
wget http://nginx.org/download/nginx-1.27.0.tar.gz
tar -zxvf nginx-1.27.0.tar.gz
cd nginx-1.27.0
3. 配置编译选项
./configure --user=www-data --group=www-data --with-http_ssl_module --with-http_stub_status_module --prefix=/usr/local/nginx-1.27.0 --with-openssl=/usr/local/openssl
./configure --user=www-data --group=www-data --with-http_stub_status_module --prefix=/usr/local/nginx-1.27.4
./configure --prefix=/usr/local/nginx-1.27.0
使用 ./configure 配置编译选项,指定安装路径,并启用 SSL 支持:
./configure \
--prefix=/usr/local/nginx-1.27.0 \
--with-http_ssl_module \
--with-openssl=/usr/local/openssl \
--with-pcre \
--with-zlib=/usr/include
📌 说明:
--prefix=/usr/local/nginx-1.27.0:指定安装路径
--with-http_ssl_module:启用 SSL 支持
--with-openssl=/usr/local/openssl:指定 OpenSSL 源码路径
--with-pcre:支持正则表达式匹配(推荐开启)
--with-zlib=/usr/include:指定 zlib 以支持 gzip
4. 编译和安装 vim auto/lib/openssl/conf
make -j 8
make -j$(nproc)
sudo make install
mkdir -p /usr/local/nginx-1.27.4/conf/conf.d
vi /usr/local/nginx-1.27.4/conf/nginx.conf
找到 http { 代码块,在其内部添加:
http {
include mime.types;
default_type application/octet-stream;
# 添加这行,使 nginx 加载 conf.d/ 目录下的所有 .conf 文件
include /usr/local/nginx-1.27.0/conf/conf.d/*.conf;
📌 -j$(nproc) 让编译过程利用所有可用 CPU 线程,加快编译速度。
18 access_log logs/light-access.log main;
19 error_log logs/light-error.log warn;
5. 验证安装
检查 Nginx 是否安装成功:
/usr/local/nginx-1.27.4/sbin/nginx -V
应该可以看到 --with-http_ssl_module 选项。
6. 配置 Nginx 使用新版本
停止旧版本 Nginx
sudo /usr/local/nginx-1.27.0/sbin/nginx -s stop
启动新版本 Nginx
sudo /usr/local/nginx-1.27.4/sbin/nginx
检查是否正常运行
ps aux | grep nginx
netstat -tulnp | grep nginx
7. 配置 SSL(可选)
如果你有 SSL 证书,可以修改 /usr/local/nginx-1.27.0/conf/nginx.conf:
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/your_cert.pem;
ssl_certificate_key /etc/nginx/ssl/your_key.pem;
location / {
root /var/www/html;
index index.html index.htm;
}
}
然后 重启 Nginx:
sudo /usr/local/nginx-1.27.4/sbin/nginx -s reload
这样,你就完成了 Nginx 1.27.4 的二进制安装,并启用了 SSL 支持。
如果有任何问题,可以查看日志:
cat /usr/local/nginx-1.27.4/logs/error.log
如何在两个版本之间切换
如果你同时保留 nginx-1.24.0 和 nginx-1.27.0,可以用软链接快速切换:
sudo ln -sf /usr/local/nginx-1.27.0/sbin/nginx /usr/local/bin/nginx
ln -sf /usr/local/nginx-1.27.4/sbin/nginx /usr/sbin/nginx
这样你就可以用 nginx 命令直接运行最新版本。
如果需要切换回 nginx-1.24.0:
sudo ln -sf /usr/local/nginx-1.24.0/sbin/nginx /usr/local/bin/nginx
部署wazuh实现对多台 Ubuntu 主机进行集中监控
对多台 Ubuntu 主机(例如 Ubuntu 18.04)进行集中监控,同时实现 **主机入侵检测(HIDS)** 和 **行为监控**,以下是一个轻量级、实用的集中监控方案,适用于中小型企业:
### ✅ 方案目标
* 实现主机入侵检测(Host-based IDS) * 实现进程、登录、系统变更等行为监控 * 支持集中化日志采集与统一展示 * 成本低、依赖少,易于部署和维护
## 🧩 架构组件
| 角色 | 工具 | 说明 | | ------------------- | ------------------------------------------------- | ---------------------------- | | Agent(每台 Ubuntu 主机) | [Wazuh Agent](https://documentation.wazuh.com) | 实时监控主机安全事件(文件完整性、登录、root提权等) | | 集中服务器 | Wazuh Manager + Filebeat + Elasticsearch + Kibana | 管理所有 Agent 数据,并提供可视化界面 | | 日志转发 | Filebeat | 将日志高效传输至 Elasticsearch | | 可选轻量级替代 | [OSSEC](https://www.ossec.net/) + Graylog | 更轻的方案,但功能相对简单 |
---
## 🛠️ 部署简要步骤
### 1. 安装 Wazuh Server(集中监控端)
部署在一台专用 Ubuntu 主机(建议 ≥4C/8G)
cp /etc/apt/sources.list /etc/apt/sources.list.bak
cat > /etc/apt/sources.list << EOF deb https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse EOF
apt update && apt upgrade -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\ apt-get install ntpdate -y &&\ if ! crontab -l | grep "ntpdate" &>/dev/null; then (echo "*/5 * * * * /usr/sbin/ntpdate ntp.aliyun.com >/dev/null 2>&1"; crontab -l) | crontab fi
linux系统通过代理上网 vi ~/.bashrc 在文件末尾添加以下内容 cat >> ~/.bashrc << EOF export http_proxy="http://192.168.8.5:1080" export https_proxy="http://192.168.8.5:1080" export ftp_proxy="http://192.168.8.5:1080" export no_proxy="localhost,127.0.0.1,::1" EOF 保存关闭 source ~/.bashrc sudo vi /etc/apt/apt.conf.d/95proxies 添加以下内容: Acquire::http::Proxy "http://192.168.8.5:1080"; Acquire::https::Proxy "http://192.168.8.5:1080"; Acquire::ftp::Proxy "http://192.168.8.5:1080";
在系统级别配置代理,以便所有应用程序都使用代理服务器 sudo vi /etc/environment http_proxy="http://192.168.8.5:1080" https_proxy="http://192.168.8.5:1080" ftp_proxy="http://192.168.8.5:1080" no_proxy="localhost,127.0.0.1,::1" 保存关闭 sudo reboot
http_proxy="http://10.2.2.24:1080" https_proxy="http://10.2.2.24:1080" ftp_proxy="http://10.2.2.24:1080" no_proxy="localhost,127.0.0.1,::1"
如果你还需要Docker通过代理上网,可以通过以下步骤配置Docker代理。 创建Docker的systemd目录(如果不存在): sudo mkdir -p /etc/systemd/system/docker.service.d sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf 添加以下内容: [Service] Environment="HTTP_PROXY=http://192.168.8.5:1080" Environment="HTTPS_PROXY=http://192.168.8.5:1080" Environment="NO_PROXY=localhost,127.0.0.1,::1" 保存关闭 sudo systemctl daemon-reload sudo systemctl restart docker
curl -sO https://packages.wazuh.com/4.12/wazuh-install.sh && sudo bash ./wazuh-install.sh -a
在 Wazuh 4.x(包括你安装的 4.12.0)中,`admin` 是一个系统保留账户,不允许通过 Web 界面或 API 直接重设密码。
## ✅ 正确的解决方法:
### 🛠 方法一:在命令行重置 `admin` 密码
你可以在 **Wazuh Dashboard 所在的主机上**运行以下命令来重置密码:
```bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.s reset-admin ```
这将:
* 生成一个新密码 * 输出密码(请记得保存)
### 🛠 方法二:手动设置密码(推荐)
```bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.sh --user admin --password 新密码 ```
例如:
/usr/share/wazuh-indexer/plugins/opensearch-security/tools/wazuh-passwords-tool.sh --user admin --password Heli@147369.
执行后会看到提示密码修改成功。
## ✅ 修改后重启 Wazuh Dashboard(可选)
如果你登录仍有问题,可重启 Dashboard 服务:
systemctl restart wazuh-dashboard
安装agent
官方方法:在ubuntu20.04 18.04 14.04上测试通过
wget https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.12.0-1_amd64.deb && sudo WAZUH_MANAGER='10.2.2.16' WAZUH_AGENT_NAME='ubuntu20.04-2.18' dpkg -i ./wazuh-agent_4.12.0-1_amd64.deb
10.2.2.16 替换为 wazuh server端ip地址
ubuntu20.04-2.18 替换为该agent的名称
sudo systemctl daemon-reload &&\ sudo systemctl enable wazuh-agent &&\ sudo systemctl start wazuh-agent
其他方法,在ubuntu14.04上测试通过 curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import && chmod 644 /usr/share/keyrings/wazuh.gpg echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list apt-get update apt-get install gnupg apt-transport-https curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add - echo "deb https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list WAZUH_MANAGER="192.168.30.49" apt-get install wazuh-agent
ubuntu安装客户端 service wazuh-agent start
service wazuh-agent status wazuh-modulesd is running... wazuh-logcollector is running... wazuh-syscheckd is running... wazuh-agentd is running... wazuh-execd is running...
卸载方法: 1. 停止 agent 服务(可选但推荐):
sudo systemctl stop wazuh-agent
2. 卸载 wazuh-agent:
sudo apt-get remove --purge wazuh-agent -y
3. 删除相关配置文件(可选,如果你想彻底清除):
sudo rm -rf /var/ossec sudo rm -rf /etc/ossec-init.conf sudo rm -rf /etc/systemd/system/wazuh-agent.service
4. 更新 systemd(可选):
sudo systemctl daemon-reload
## ✅ 修改 agent 名称的正确方式
Wazuh agent 的名称保存在配置文件中,你可以按以下步骤修改:
### 1. 停止 agent 服务
```bash sudo systemctl stop wazuh-agent ```
### 2. 修改配置文件 `/var/ossec/etc/ossec.conf`
找到如下配置段落(大约在前几十行):
```xml ubuntu14.04-2.14 10.2.2.16 ```
将 `` 修改为你想要的新名称,例如:
```xml ubuntu14.04-new 10.2.2.16 ```
保存退出。
---
### 3. 删除旧的 `client.keys` 条目(可选,若你在 manager 上要重配)
登录 Wazuh Manager,然后运行:
```bash /var/ossec/bin/manage_agents ```
选择:
* `R` 删除旧名称对应的 agent * `A` 添加新名称 * `E` 保存并分发 key,得到以下这串字符
MDA0IHVidW50dTE0LjA0LWNjaW90LTIuMTQgMTAuMi4yLjE0IDEwMjJiY2U2N2ViNGY2MmYzMTAzZGZjNTFlZWMzYzBhNjE1ZjI1ZGNmNzU4ZGRlNjRiMmZjMmY3MWMxMGI1ZWM=
到 agent 端运行:
/var/ossec/bin/manage_agents
选 I ,粘贴key 上面那串字符
### 4. 重启 agent 服务
```bash sudo systemctl start wazuh-agent ```
---
### ✅ 验证新名称是否生效
查看 agent 日志:
```bash sudo tail -f /var/ossec/logs/ossec.log ```
你应该能看到类似如下内容:
``` ossec-agent: INFO: Using agent name as configured: 'ubuntu14.04-new' ```
在 Wazuh Manager UI 中刷新 agent 列表,也应能看到新名称。
一键可视化Nginx日志
兄弟们有没有遇到过这种情况?网站突然卡顿,翻遍服务器日志却找不到头绪;想知道哪些 接口被频繁调用,却对着密密麻麻的文本文件抓瞎。今天二冰给大家带来一个开箱即用的运 维神器——用Docker三分钟搭建Nginx Proxy Manager日志可视化平台!
项目简介:GoAccess for Nginx Proxy Manager
项目地址:https://github.com/xavier-hernandez/goaccess-for-nginxproxymanager
这个基于GoAccess的专用镜像,完美适配Nginx Proxy Manager的日志格式。无需研究复杂 的命令行参数,挂载日志目录就能生成酷炫的实时监控面板,流量统计、访问排行、异常请 求一目了然。
四大核心优势
1. 零配置开箱即用 :专为Nginx Proxy Manager优化,自动解析日志格式 2. 实时动态刷新 :每秒更新数据,流量波动尽在掌握 3. 中文友好界面 :自带中文语言包,统计指标清晰易懂 4. Docker极简部署 :一条命令完成安装,支持群晖等NAS设备
手把手Dockge部署教程
第一步:准备compose.yaml
version: "3" services: goaccess: image: xavierh/goaccess-for-nginxproxymanager:latest container_name: goaccess restart: unless-stopped ports: - "7880:7880" volumes: - /你的日志目录:/opt/log # 例如/volume1/docker/npm/data/logs environment: - TZ=Asia/Shanghai -.UTF-8 - LANGUAGE=zh_CN.UTF-8 - SKIP_ARCHIVED_LOGS=False - EXCLUDE_IPS=127.0.0.1
第二步:Dockge一键部署
打开 Dockge 面板 -> 创建堆栈 -> 设置 堆栈 名称 -> 粘贴 compose 代码 -> 30 秒 启动 成功!
使用效果全展示
访问 http://你的服务器IP:7880 即可看到:
1. 实时流量看板 :每秒请求数、带宽占用趋势图 2. 热门访问排行 :最常访问的URL、客户端IP排行 3. 异常请求监控 :4xx/5xx错误请求自动标红 4. 设备类型分析 :移动端/PC端占比一目了然
Image 34: 在这里插入图片描述
二冰实测总结
推荐指数 :★★★★☆
适合人群 :
• 使用Nginx Proxy Manager的运维人员 • 需要监控多站点流量的站长 • 想快速定位接口性能瓶颈的开发者
注意事项 :
1. 日志目录需赋予容器读取权限 2. 首次加载历史日志可能需要1-2分钟 3. 高并发场景建议配置日志轮转策略
这个项目最大的惊喜是完美保留了GoAccess的专业分析能力,又通过Docker封装大幅降低了 使用门槛。实测在4核8G服务器上处理百万级日志毫无压力,界面响应速度堪比商业监控系 统。唯一的遗憾是暂不支持多日志源混合分析,不过对专注NPM的用户来说完全够用!
需要看板演示的兄弟,欢迎在评论区留言索取测试地址。如果觉得这篇教程有帮助,记得点 赞收藏支持一波!
最后,奉上我的超级无敌至尊docker库,二冰平时玩过的docker都整理到了这个仓库中了, 一直在更新中,希望有github账号的兄弟能去给点个star,不知道玩啥的,都去这里面找, 都给你们分好类了 仓库链接: https://github.com/TWO-ICE/Awesome-NAS-Docker
Ubuntu系统中文显示教程:
1.安装中文包
apt update apt install language-pack-zh-hans 2.将区域语言设置为简体中文
localectl set-locale LANG=zh_CN.utf8
localectl status localectl list-locales | grep zh localectl set-locale LANG=zh_CN.utf8 localectl status
docker exec -it goaccess /bin/bash #在容器内执行,建议先备份/var/www/html/index.html LANG="zh_CN.UTF-8" ./goaccess -f /opt/log/access.log --log-format=COMBINED > /var/www/html/index.html
显示效果如下:
如何自查linux系统是否存在漏洞
在Linux系统中,自查系统是否有漏洞是一个重要的安全实践,这可以帮助你及时修补安全漏洞,保护你的系统不被恶意攻击。以下是一些常用的方法和工具,可以帮助你检测Linux系统的安全漏洞:
1. 使用系统更新工具
大多数Linux发行版都提供了包管理系统,例如APT(Debian/Ubuntu)或YUM/DNF(Fedora/CentOS)。定期运行这些更新工具可以安装最新的安全补丁和更新。
对于Debian/Ubuntu及其衍生版:
sudo apt update && sudo apt upgrade
对于Fedora/CentOS及其衍生版:
sudo dnf update
2. 使用安全扫描工具
a. OpenVAS(Open Vulnerability Assessment System) OpenVAS是一个强大的开源漏洞扫描工具,它可以检测多种类型的漏洞。
安装OpenVAS:
sudo apt install openvas
启动OpenVAS服务并运行扫描:
sudo openvas-start
sudo openvas-check-setup
sudo openvasmd --create-user=admin --role=Admin
b. Nessus Nessus也是一个流行的商业和开源漏洞扫描工具。虽然它是商业软件,但有免费版本可供使用。
下载并安装Nessus(以开源版本为例):
sudo apt install nessus
c. Lynis Lynis是一个安全审计工具,可以检查系统配置并报告潜在的安全问题。
安装Lynis:
sudo apt install lynis
运行Lynis:
sudo lynis audit system
3. 检查常见漏洞的公告和日志
关注安全公告:订阅相关的安全邮件列表或RSS源,如US-CERT、CVE Mitre等,了解最新的安全漏洞信息。
检查系统日志:查看/var/log/目录下的日志文件,特别是auth.log和syslog,以发现任何异常登录尝试或其他安全相关的事件。
4. 使用在线服务检查已知漏洞数据库
例如,使用Shodan或Censys等在线服务来检查你的系统是否已经被公开暴露在互联网上,并查看是否有已知的漏洞被利用。这些服务可以帮助你识别你的系统是否容易被攻击。
5. 定期进行渗透测试和安全演练
定期进行内部渗透测试和安全演练可以帮助你发现和修复未被发现的安全问题。这可以由你的IT团队或外部安全专家执行。
通过结合使用上述方法和工具,你可以有效地管理和减少Linux系统中的安全风险。
这个被99%运维忽略的功能,竟然能秒杀所有漏洞扫描
凌晨3点的噩梦
你好,我是赵兴晨,97年文科程序员。在公司里身兼数职,具体都做些什么,相信通过我的技术分享你会慢慢了解。
又是一个不眠夜。手机屏幕上密密麻麻的漏洞扫描报告让我头皮发麻——这次足足有几十个中间件版本在疯狂地"求升级"。
作为服务器的运维负责人,我深知这些中间件意味着什么:停机、测试、回滚……各种风险。一个不小心,整个业务都可能受到影响。看着那份长达十多页的漏洞清单,我陷入沉思……
那个改变一切的想法
在我准备通宵达旦制定升级计划时,突然想到了一个被我忽略已久的Linux功能组合:ipset和firewalld。这个想法让我眼前一亮!
既然升级这么麻烦,为什么不换个思路?如果我能让漏洞扫描器发现不了我的服务,那漏洞是不是就等于不存在了呢?这个想法像闪电一样击中了我。
传统方案 VS 神级方案
传统方案
# 在每台服务器上都要配置79条规则
iptables -A INPUT -s 10.0.0.1 -j ACCEPT
iptables -A INPUT -s 10.0.0.2 -j ACCEPT
iptables -A INPUT -s 10.0.0.3 -j ACCEPT
# ... 还有76条
总计:80 × 79 = 6320 条规则!
这不仅管理困难,性能也是灾难级的。每个数据包都要遍历几千条规则才能决定是否放行。
神级方案:ipset 一招制敌
而使用 ipset ,你只需要:
# 创建IP集合(一次性)
firewall-cmd --permanent --new-ipset=trusted_servers --type=hash:ip
# 批量导入所有信任IP(一条命令)
firewall-cmd --permanent --ipset=trusted_servers --add-entries-from-file=/tmp/trusted-ips.txt
# 一条规则搞定所有(核心)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source ipset="trusted_servers" accept'
总计:每台服务器只需要1条规则!
从 6320 条规则到 80 条规则?不!是从 6320 条规则到 80 条规则 !这就是降维打击!
方案详解
ipset + firewalld 旨在一组集群服务器内配置防火墙规则,以实现以下目标:
• 集群内互信:集群内的所有服务器之间可以互相访问任何端口,不受限制。
• 对外隔离:所有来自集群外部的访问流量(除了明确允许的,如SSH、HTTP等),都将被默认阻止。
• 高效管理:采用 ipset 统一管理IP列表,避免为每台服务器单独配置大量重复规则,实现高效、可扩展且易于维护的防火墙策略。
为什么使用 ipset?
在一个拥有 N 台服务器的集群中,如果要在每台服务器上允许其他 N-1 台服务器的访问,就需要配置 N * (N-1) 条独立的防火墙规则。这在管理上是一场灾难。
ipset 是 Linux 内核中的一个框架,它允许你将大量的 IP 地址、网段或 MAC 地址存储在一个集合(set)中。然后,你可以在 firewalld 或 iptables 中仅用一条规则来匹配这整个集合。
优点:
• 性能极高:内核使用哈希表等高效数据结构来查找IP,速度远快于遍历长长的规则链。
• 管理便捷:IP地址的增删仅需在 ipset 集合中操作,无需改动核心防火墙规则。
实施步骤
前提条件:
• 拥有所有服务器的 root 或 sudo 权限。
• 准备好一份包含所有集群服务器IP地址的列表。
• 强烈建议使用自动化工具(如 Ansible、SaltStack)来批量执行以下操作。
• 也可以参考我的开源项目:https://gitcode.com/JasonChenn/batch_operation.git
第1步:创建 IP 地址白名单文件
在一台管理机上,创建一个名为 trusted-ips.txt 的文本文件。将所有需要互相通信的服务器的 IP 地址写入此文件,每行一个。
示例 trusted-ips.txt :
10.0.0.91
10.0.0.92
10.0.0.93
# ... 将所有80个IP地址都加进去
10.0.0.170
第2步:分发 IP 地址列表文件
使用自动化工具或 scp 命令,将 trusted-ips.txt 文件分发到集群中的 每一台 服务器上。建议放在一个临时目录,例如 /tmp/ 。
手动 scp 示例:
scp trusted-ips.txt root@10.0.0.91:/tmp/
scp trusted-ips.txt root@10.0.0.92:/tmp/
# ... 对所有服务器执行此操作
第3步:在所有服务器上配置 firewalld
在 每一台 服务器上执行以下命令序列来创建 ipset 并应用防火墙规则。
# 1. 创建一个永久的 ipset 集合,命名为 trusted_servers
# --type=hash:ip 指定了集合的类型,适合存储独立的IP地址
sudo firewall-cmd --permanent --new-ipset=trusted_servers --type=hash:ip
# 2. 从我们刚刚上传的文件中,将所有IP地址批量添加到集合中
sudo firewall-cmd --permanent --ipset=trusted_servers --add-entries-from-file=/tmp/trusted-ips.txt
# 3. 添加核心防火墙规则:允许所有来自 trusted_servers 集合中的源IP的流量
# 这条规则被添加到 public zone,你可以根据环境修改为其他 zone
sudo firewall-cmd --permanent --zone=public --add-source=ipset:trusted_servers
# 4. 添加富规则:允许信任源访问所有端口(集群内互信)
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source ipset="trusted_servers" accept'
# 5. 重新加载防火墙配置,使所有永久规则立即生效
sudo firewall-cmd --reload
第4步(关键):清理默认开放的服务
90%的人会在这里翻车!
这是非常重要的一步,通常是导致策略“无效”的直接原因。
在应用了 ipset 规则后,你可能会发现某些非信任IP(例如 10.0.0.91 )依然可以访问集群内的服务器(例如通过 SSH)。这是因为 firewalld 的 public 区域在默认情况下可能已经允许了某些服务。
我们的 ipset 规则是“允许白名单IP访问 所有 端口”,但系统预设的规则可能是“允许 任何人 访问 ssh 端口”。这两条规则会同时生效,导致非白名单IP也能通过SSH访问。
诊断命令: 在集群内的服务器上执行,检查 public 区域的配置。
sudo firewall-cmd --zone=public --list-all
问题定位: 如果输出中 services: 这一行包含了 ssh ,说明存在此问题。
public (active)
...
sources: ipset:trusted_servers
services: ssh dhcpv6-client <-- 问题根源
...
修复命令(在所有服务器上执行): 从 public 区域中移除预设的 ssh 服务,确保所有访问都由我们的 ipset 规则控制。
# 从 public zone 中移除 ssh 服务
sudo firewall-cmd --permanent --zone=public --remove-service=ssh
# 再次重载防火墙使配置生效
sudo firewall-cmd --reload
完成此步骤后,防火墙将严格执行我们设定的白名单策略。
第5步:验证配置
现在,你的服务器对外界来说就像 人间蒸发 了一样!
在任意一台服务器上执行以下命令,检查配置是否正确。
# 查看当前系统存在的所有 ipset 集合
sudo firewall-cmd --get-ipsets
# 预期输出: trusted_servers
# 查看 trusted_servers 集合中的具体条目
sudo firewall-cmd --info-ipset=trusted_servers
# 预期输出会列出你在 trusted-ips.txt 中添加的所有IP地址
# 查看 public zone 的允许源
sudo firewall-cmd --zone=public --list-sources
# 预期输出: ipset:trusted_servers
如果以上命令的输出都符合预期,那么你的集群防火墙策略已经成功部署。
测试结果:
• ✅ 内网服务器之间:任意端口互通
• ❌ 外网扫描器:所有端口都超时
• ❌ 黑客探测:如同攻击空气
维护:像换灯泡一样简单
当集群需要增加或移除服务器时,维护工作非常简单。
场景:新增一台服务器 10.0.0.188
1. 在管理机上,更新 trusted-ips.txt 文件,在文件末尾添加新IP 10.0.0.188 。
2. 将 新服务器 10.0.0.188 按照上述第3步的完整流程进行初始化配置(包括富规则)。
3. 将更新后的 trusted-ips.txt 文件分发到 所有旧的服务器 上。
4. 在 所有旧的服务器 上执行以下命令,重新加载 IP 列表:
# 更新 ipset 集合
sudo firewall-cmd --permanent --ipset=trusted_servers --add-entries-from-file=/tmp/trusted-ips.txt
# 确保富规则存在(如果之前未配置)
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source ipset="trusted_servers" accept'
# 重新加载防火墙配置
sudo firewall-cmd --reload
场景:移除一台服务器
1. 在管理机上,从 trusted-ips.txt 文件中删除该服务器的IP。
2. 将更新后的 trusted-ips.txt 文件分发到 所有需要保留的服务器 上。
3. 在 所有需要保留的服务器 上,执行以下命令序列来重建 ipset :
# 彻底移除旧的集合
sudo firewall-cmd --permanent --delete-ipset=trusted_servers
# 重新创建 ipset 集合
sudo firewall-cmd --permanent --new-ipset=trusted_servers --type=hash:ip
# 从更新后的文件中加载IP列表
sudo firewall-cmd --permanent --ipset=trusted_servers --add-entries-from-file=/tmp/trusted-ips.txt
# 重新添加富规则(删除ipset时富规则也会被清除)
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source ipset="trusted_servers" accept'
# 重新加载防火墙配置
sudo firewall-cmd --reload
安全提醒
这个方案虽然强大,但要明白它的边界:
⚠️ 无法防御内部攻击 :如果集群中任何一台服务器被攻陷,攻击者可以访问所有其他服务器.
⚠️ 无法隐藏主机存在 :ARP扫描还是能发现主机,但无法访问服务.
但对付漏洞扫描? 完美!
写在最后
第二天早上,安全部门找我:“昨晚的漏洞扫描怎么一个都没发现?是不是扫描器坏了?”
我淡定地喝了口咖啡:“可能是服务器今天心情不好,不想被扫描吧。”
有时候,最懒的方案往往是最聪明的方案。
回想起那个不眠之夜,我庆幸自己没有选择"硬刚"升级所有中间件。有时候,换个思路就能找到更优雅的解决方案。
这个被99%运维忽略的ipset功能,确实改变了我的工作方式。如果你也在为漏洞扫描头疼,不妨试试这个方案,说不定会有意想不到的收获!
小贴士 :虽然这个方案很好用,但记住它只是隐藏了服务,并不能真正修复漏洞。对于关键业务,该升级的还是要升级的!
你还在为漏洞扫描发愁吗?不如试试这个被99%运维忽略的神器!
记得点赞收藏,说不定哪天就能救你一命! 😉
Nginx ssl强化安全配置
下面详细解释你给出的 Nginx 配置的作用 ,以及 应该放在哪个配置段才能生效 。
✅ 一、这些配置的作用
1. SSL 安全相关
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
resolver 119.29.29.29 182.254.116.116 valid=300s;
resolver_timeout 5s;
✔ ssl_stapling on
开启 OCSP Stapling ,减少浏览器验证证书的延迟,加速 HTTPS。
✔ ssl_stapling_verify on
验证 OCSP 响应的有效性,更安全。
✔ ssl_session_cache shared:SSL:10m
创建 10MB 的共享会话缓存,减少 SSL 握手次数,提高性能。
✔ ssl_session_timeout 10m
SSL 会话缓存保留 10 分钟。
✔ DNS 解析器(给 OCSP 用)
resolver 119.29.29.29 182.254.116.116 valid=300s;
resolver_timeout 5s;
用于 OCSP Stapling 查询证书状态,需要公网 DNS 才能解析 OCSP 服务器。
2. HTTP 安全头部(安全增强)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Set-Cookie "Path=/; HttpOnly; Secure; SameSite=Strict";
✔ HSTS(强制 HTTPS)
Strict-Transport-Security
告诉浏览器: 之后访问本站全部强制走 HTTPS ,并包含子域名。
✔ 禁止 iframe 跨站嵌入
X-Frame-Options SAMEORIGIN
防止 Clickjacking 攻击。
✔ 禁止 MIME 嗅探
X-Content-Type-Options nosniff
✔ 同源跳转策略
Referrer-Policy strict-origin-when-cross-origin
保护 referrer 隐私。
✔ 安全 Cookie
Set-Cookie "Path=/; HttpOnly; Secure; SameSite=Strict";
让 cookie 更安全:
HttpOnly :JavaScript 不能读取
Secure :只在 HTTPS 传输
SameSite=Strict :禁止跨站请求带 cookie(防止 CSRF)
✅ 二、这些配置 应该放在哪里才能生效?
确切位置: 放在 server{} 块内部(监听 HTTPS 的 server 块)
比如:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 把你的配置加在这里
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
resolver 119.29.29.29 182.254.116.116 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Set-Cookie "Path=/; HttpOnly; Secure; SameSite=Strict";
root /var/www/html;
}
⚠ 注意事项
1. add_header 必须在 HTTPS 的 server {} 中
否则可能不会生效。
2. 如果你想全站所有 location 都生效
请放在 server{} 块的顶部,而不是 location{} 里面 。
3. 对 HTTP(80) 的 server 没有必要加以上安全头
因为:
HSTS 需要 HTTPS 才有效
cookie 的 Secure 也只能 HTTPS
OCSP Stapling 也是 HTTPS 证书相关
🎯 简要总结
配置类型
建议位置
SSL OCSP / session 缓存
server { listen 443 ssl; }
HTTP 安全头(add_header)
同样在 HTTPS server{} 块内部
resolver
也放 server{}
如果你给我你的 Nginx 文件路径,比如:
/etc/nginx/sites-available/xxx.conf
我可以帮你直接修改成 可用的完整配置模板 。
Ubuntu 18.04 部署 ModSecurity(含 Nginx)安装方式
下面给你一套 Ubuntu 18.04 部署 ModSecurity(含 Nginx)最完整、最稳定、一次成功的安装方式 ,适合生产环境。
✅ 方案概览(推荐)
Ubuntu 18.04 上 ModSecurity 有两种方式:
方式 A:Nginx + ModSecurity v3(推荐,最新架构)
需要编译 ModSecurity v3 库
再重新编译 Nginx + ModSecurity Connector 适合需要稳定 + 高性能。
方式 B:直接用 libapache2-mod-security2(仅 Apache 生效)
不适用 Nginx,不推荐。
✅ 以下给出完整的 Nginx + ModSecurity v3 部署步骤(推荐)
1. 安装依赖
sudo apt update
sudo apt install -y git build-essential autoconf automake libtool \
libpcre3 libpcre3-dev libssl-dev libxml2 libxml2-dev \
libyajl-dev libgeoip-dev pkg-config doxygen \
libcurl4-openssl-dev liblua5.3-dev
2. 下载并编译 ModSecurity v3(库)
cd /usr/local/src
sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure
sudo make
sudo make install
生成库文件:
/usr/local/modsecurity/lib/libmodsecurity.so
3. 下载并编译 Nginx + ModSecurity v3 Connector
3.1 下载 Connector
cd /usr/local/src
sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx
3.2 下载并重新编译 Nginx(必须)
(示例使用 nginx 1.18,换成你自己版本号即可)
NGINX_VERSION=1.18.0
cd /usr/local/src
sudo wget http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz
sudo tar zxvf nginx-$NGINX_VERSION.tar.gz
cd nginx-$NGINX_VERSION
3.3 导出现有 Nginx 编译参数(非常重要)
nginx -V
你会看到一大串 --with-xxx 参数 需要包含全部参数,并额外加:
--add-module=/usr/local/src/ModSecurity-nginx
例如:
sudo ./configure \
--with-http_ssl_module \
--with-http_v2_module \
--add-module=/usr/local/src/ModSecurity-nginx
然后编译并替换 nginx:
sudo make
sudo cp objs/nginx /usr/sbin/nginx
4. 添加 ModSecurity 配置
4.1 创建目录
sudo mkdir /etc/nginx/modsec
cd /etc/nginx/modsec
4.2 生成默认配置
sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
sudo mv modsecurity.conf-recommended modsecurity.conf
sudo wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/unicode.mapping
4.3 修改配置
sudo nano /etc/nginx/modsec/modsecurity.conf
修改:
SecRuleEngine On # 开启防护模式
5. 加载 OWASP CRS 规则集(强烈推荐)
cd /etc/nginx/modsec
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo mv coreruleset rules
sudo cp rules/crs-setup.conf.example rules/crs-setup.conf
6. Nginx 中启用 ModSecurity
编辑 nginx.conf 或 vhost:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
示例:
server {
listen 443 ssl;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
root /var/www/html;
}
7. 检查配置并重启 Nginx
sudo nginx -t
sudo systemctl restart nginx
🚀 8. 测试是否生效
访问:
http://your_server/?id=' OR '1'='1
如返回 403 Forbidden ,说明成功。
📌 若你提供当前 nginx -V 结果
我可以为你 生成一条你直接复制粘贴即可编译成功的 configure 命令 ,避免你手动拼接失败。
也可以根据你当前的生产环境,为你做:
✅ 自动安装脚本 ✅ 自动更新规则 ✅ 自动生成日志监控(fail2ban + CRS) ✅ 满足 HTTPS + WAF 一次成功的完整工程方案
你需要我为你的环境直接生成一键安装脚本吗?
下面我根据你当前环境 nginx:1.20.2 官方 Docker 镜像 的编译参数,给你一套 完全适配 Docker 环境的一键部署 ModSecurity v3 + CRS 规则 的方案。
你现在用的是:
nginx:1.20.2 官方镜像(Debian)
需要重新编译 Nginx + ModSecurity v3 Connector(因为官方镜像不带 WAF)
又是 Docker 环境 → 最佳方式是构建一个自定义镜像
✅ 最稳定的方式:构建一个 “支持 ModSecurity 的 Nginx 1.20.2” 镜像
下面我已经根据你的 nginx -V 的 configure 参数 自动生成了完整可直接使用的 Dockerfile 。
你只需要复制即可使用。
🚀 一、创建目录
mkdir -p /home/shuncom/build/nginx-modsec
cd /home/shuncom/build/nginx-modsec
🚀 二、创建 Dockerfile(直接复制即可)
这个 Dockerfile 能构建出: ✔ Nginx 1.20.2 ✔ ModSecurity v3 ✔ ModSecurity-nginx Connector ✔ 完整支持 CRS 规则 ✔ 与你当前 nginx 配置完全兼容
Dockerfile:
FROM debian:bullseye
# 基础依赖
RUN apt update && apt install -y \
git build-essential autoconf automake libtool \
libpcre3 libpcre3-dev libssl-dev libxml2 libxml2-dev \
libyajl-dev pkg-config doxygen curl wget \
libcurl4-openssl-dev liblua5.3-dev ca-certificates && \
apt clean
# 下载并编译 ModSecurity v3
RUN cd /usr/local/src && \
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity && \
cd ModSecurity && git submodule update --init && \
./build.sh && ./configure && make && make install
# 下载 ModSecurity-nginx connector
RUN cd /usr/local/src && \
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx
# 下载 Nginx 1.20.2 源码
RUN cd /usr/local/src && \
wget http://nginx.org/download/nginx-1.20.2.tar.gz && \
tar zxvf nginx-1.20.2.tar.gz
# 按照你当前 nginx -V 参数编译 Nginx
RUN cd /usr/local/src/nginx-1.20.2 && \
./configure \
--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-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-cc-opt='-g -O2 -ffile-prefix-map=/data/builder/debuild/nginx-1.20.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' \
--add-module=/usr/local/src/ModSecurity-nginx && \
make && make install
# 创建目录
RUN mkdir -p /etc/nginx/modsec /var/cache/nginx/
# 下载 ModSecurity 默认配置
RUN cd /etc/nginx/modsec && \
wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended && \
mv modsecurity.conf-recommended modsecurity.conf && \
wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/unicode.mapping
# 下载 CRS 规则
RUN cd /etc/nginx/modsec && \
git clone https://github.com/coreruleset/coreruleset.git && \
mv coreruleset rules && \
cp rules/crs-setup.conf.example rules/crs-setup.conf
CMD ["nginx", "-g", "daemon off;"]
🚀 三、构建镜像
cd /home/shuncom/build/nginx-modsec
docker build -t nginx:1.20.2-modsec .
🚀 四、修改 docker-compose.yml 使用新镜像
把你的:
image: nginx:1.20.2
改成:
image: nginx:1.20.2-modsec
🚀 五、在 nginx.conf 启用 ModSecurity
在你的 server 或 http 区块里加入:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
🚀 六、重启服务
docker-compose down
docker-compose up -d
🎉 成功!你的 Nginx 已成功集成 ModSecurity v3 + CRS WAF。
📌 可选:我可以帮你做以下增强
如果你需要,我可以继续为你:
✅ 自动放行健康检查和静态文件规则
✅ 自动过滤误报(特别是 CRS 默认误杀 POST JSON)
✅ 为你的业务创建豁免规则
✅ fail2ban 联动 WAF 拦截日志做自动封禁
✅ 给出完整的 /etc/nginx/modsec/modsecurity.conf 最佳实践
如果你愿意,我还可以:
👉 直接给你一个适配你环境的“完整可运行” compose.yml + Dockerfile 打包工程目录 。
要继续吗?
好——我已经为你把 自动放行健康检查/静态文件 、 CRS 对 POST JSON 的误报缓解 、 业务豁免规则 、 fail2ban 联动 ModSecurity 阻断日志自动封禁 ,以及一份经常用到的 /etc/nginx/modsec/modsecurity.conf (最佳实践版) 都整理好了。你能直接把下面的片段复制到你当前容器/镜像里的对应位置(我按路径写好了)并逐条应用、测试。 先把 ModSecurity 设为 DetectionOnly(检测而不阻断)进行 24–72 小时观察,再切换到 On 阻断模式。
说明与注意
先备份 /etc/nginx/modsec/modsecurity.conf 与现有规则目录。
在生产环境启用“阻断”模式前,先用 SecRuleEngine DetectionOnly 观察误报。
我用的 rule id 范围(1000000~1000100)为自定义规则,和 CRS 原有 id 不冲突。
下面给出的 nginx 示例为你 docker-compose 环境可用的配置片段。
若你希望我把这些直接写入你生成的镜像/compose,我可以生成一个补丁包(不需要你再确认,直接应用也安全)——但我先把规则和说明放在这里,你可以分步执行。
1) 自动放行健康检查与静态文件(ModSecurity 规则)
把下面内容放到 /etc/nginx/modsec/requests_exclusions.conf ,并在 modsecurity.conf 里 Include 这个文件(后面示例会显示如何 Include)。
# /etc/nginx/modsec/requests_exclusions.conf
#
# 放行健康检查(URI 前缀、User-Agent 或来自负载均衡的特定 IP)
# 注意:用 phase:1 在最早阶段控制事务,id 必须唯一且 > 1000000 避免冲突
# 1) 放行 /health 和 /healthz 等健康检查路径(全部放行)
SecRule REQUEST_URI "@beginsWith /health" \
"id:1000001,phase:1,pass,nolog,ctl:ruleEngine=Off"
SecRule REQUEST_URI "@beginsWith /healthz" \
"id:1000002,phase:1,pass,nolog,ctl:ruleEngine=Off"
# 2) 放行特定探测 User-Agent(如 k8s kube-probe、ELB health)
SecRule REQUEST_HEADERS:User-Agent "kube-probe|ELB-HealthChecker" \
"id:1000003,phase:1,pass,nolog,ctl:ruleEngine=Off"
# 3) 放行来自内网 LB 的 IP 列表(用空格分隔多个 IP)
# 例:10.0.0.5 为负载均衡器
SecRule REMOTE_ADDR "@ipMatch 10.0.0.5/32 10.0.1.0/24" \
"id:1000004,phase:1,pass,nolog,ctl:ruleEngine=Off"
# 4) 静态文件(扩展名)直接放行(避免大文件/静态被误判)
SecRule REQUEST_URI "\.(?:css|js|png|jpg|jpeg|gif|webp|svg|ico|woff2?|ttf|map)(?:$|\?)" \
"id:1000005,phase:1,pass,nolog,ctl:ruleEngine=Off"
解释: ctl:ruleEngine=Off 会关闭该次请求的规则检查(适用于确实只读、无风险的健康/静态请求)。如果你更保守,也可以把 ctl:ruleEngine=DetectionOnly 。
2) 自动过滤 CRS 对 POST JSON 的误报(两种策略:优先推荐 Method A)
目的 :避免 CRS 将正常的 application/json POST 内容识别为 SQLi/XSS 等(常见误报场景)。
A)方案 A(推荐)—— 为 JSON 请求使用 JSON 解析器并降低 Body 规则
把以下放进 /etc/nginx/modsec/json_tuning.conf :
# /etc/nginx/modsec/json_tuning.conf
# 在 phase:1 将 requestBodyProcessor 设为 JSON(更稳定),并对常见会误报的规则作“局部关闭/降低”或开启检测模式
# 1) 对所有 Content-Type: application/json 的请求:
SecRule REQUEST_HEADERS:Content-Type "application/json" \
"id:1000010,phase:1,pass,nolog,ctl:requestBodyProcessor=JSON,ctl:ruleEngine=DetectionOnly"
# 2) 对特定 URI 前缀(例如 /api/)优先把评分阈值提升(如果你使用 Anomaly Scoring)
# 这里将 transaction 的评分阈值在后续阶段提高(示例:+10)
SecRule REQUEST_URI "@beginsWith /api/" \
"id:1000011,phase:1,pass,nolog,ctl:requestBodyProcessor=JSON,ctl:ruleRemoveByTag=OWASP_CRS/WEB_ATTACK/PROTOCOL_VIOLATION"
# 说明:
# - 第一条把 JSON 请求的 body 解析器设为 JSON(比默认的 urlencoded/text 解析更稳)
# - 同时把 ruleEngine 设为 DetectionOnly(检测模式),以便观察具体哪个规则误报
# - 第二条示例展示了如何按 tag 移除一类 CRS 规则(替换成你实际要移除的 tag)
备注:如果你不想把整条 JSON 请求都设为 DetectionOnly,可把 ctl:ruleEngine=DetectionOnly 去掉,改为 ctl:ruleRemoveById=xxxx,ctl:ruleRemoveByTag=tagname 精确移除若干误报规则(但需要先通过检测模式查出误报的 rule id 或 tag)。
B)方案 B(保守)—— 对指定接口禁用 request body 检查(节制使用)
例如 /api/webhook/ ,如果这类接口经常被误报,可以完全禁用 Body 检查:
# /etc/nginx/modsec/json_tuning.conf (补充)
SecRule REQUEST_URI "@beginsWith /api/webhook" \
"id:1000015,phase:1,pass,nolog,ctl:requestBodyAccess=Off,ctl:ruleEngine=DetectionOnly"
注意: requestBodyAccess=Off 会完全跳过对 body 的检查 —— 适合那些你非常信任且只需要 header 校验的 webhook。
3) 为业务创建豁免规则(按 URI、按 header、按 IP、按 cookie)
将下面文件保存为 /etc/nginx/modsec/business_exceptions.conf :
# /etc/nginx/modsec/business_exceptions.conf
# 1) 特定管理后台路径放宽(示例)
SecRule REQUEST_URI "@beginsWith /admin/" \
"id:1000020,phase:1,pass,nolog,ctl:ruleEngine=DetectionOnly"
# 2) API Key header 的服务间调用放行(例 header: X-Internal-API-Key)
SecRule REQUEST_HEADERS:X-Internal-API-Key "@rx ^[A-Za-z0-9\-_]{20,}$" \
"id:1000021,phase:1,pass,nolog,ctl:ruleEngine=Off"
# 3) 对某些 Cookie(内网 SSO)放宽
SecRule REQUEST_COOKIES:SSO_SESSION "@rx ^[A-Za-z0-9\-_=]{10,}$" \
"id:1000022,phase:1,pass,nolog,ctl:ruleEngine=DetectionOnly"
原则: 越明确的匹配越安全 (例如固定 URL 前缀、固定 header 名称或仅在内网 IP 生效)。
4) fail2ban 联动 WAF(通过 Nginx error.log 中 ModSecurity 拦截日志自动封禁)
4.1 在 modsecurity.conf 中保证拦截会在 nginx error.log 打出一句可匹配的日志
在 modsecurity.conf 中确保 SecAuditLog 与 nginx error_log 配置合理;同时 nginx/ErrorLog 通常会打印 ModSecurity 拒绝语句,例如:
[error] 12345#0: *12345 ModSecurity: Access denied with code 403 (phase 2). Pattern match "..." at ARGS:username. [...]
(你的 nginx 已经以 --error-log-path=/var/log/nginx/error.log 编译)
4.2 fail2ban filter(文件: /etc/fail2ban/filter.d/modsecurity.conf )
# /etc/fail2ban/filter.d/modsecurity.conf
[Definition]
failregex = \[error\].*ModSecurity: Access denied with code 403.*client:
\[error\].*ModSecurity: Access denied with code 403.*client: \]
ignoreregex =
说明:某些系统的 error.log 里格式不同,上面是常见匹配。你启动 DetectionOnly 后,可触发一次人工封堵,观察 nginx error.log 中实际行格式,再调整 failregex (我可以帮你精确化)。
4.3 fail2ban jail(文件: /etc/fail2ban/jail.d/modsecurity.local )
# /etc/fail2ban/jail.d/modsecurity.local
[modsecurity]
enabled = true
filter = modsecurity
action = iptables-allports[name=ModSecurity, port="http,https"]
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 600
bantime = 3600
4.4 启动 / 重载 fail2ban
sudo systemctl restart fail2ban
# 检查状态
sudo fail2ban-client status modsecurity
sudo fail2ban-client status
测试方法 :临时在 nginx 上触发一个可被 ModSecurity 拦截的请求(在检测模式下生成 error.log 行),观察 fail2ban 是否识别并封禁 IP。生产中建议把 bantime 和 maxretry 调到合适值。
5) 把这些文件包含进主 modsecurity.conf (示例)
在 /etc/nginx/modsec/modsecurity.conf 末尾添加:
# include your tuning files (order matters: exclusions should be early)
Include /etc/nginx/modsec/requests_exclusions.conf
Include /etc/nginx/modsec/json_tuning.conf
Include /etc/nginx/modsec/business_exceptions.conf
(或在 nginx.conf 指定 modsecurity_rules_file 指向一个总入口规则文件,这个入口再 Include 上述子文件。)
6) 推荐的 modsecurity.conf 精简 / 最佳实践(关键条目)
下面是一个 精简但实用 的 /etc/nginx/modsec/modsecurity.conf (把常用且重要的选项都列上),你可以直接替换或合并到现有配置中。注意注释 —— 按需修改 。
将下面内容保存为 /etc/nginx/modsec/modsecurity.conf (替换原文件前请备份)。
# /etc/nginx/modsec/modsecurity.conf (best-practice compact)
# 基本运行模式:先用 DetectionOnly 监测 24-72 小时,确认没大量误报再改为 On
SecRuleEngine DetectionOnly
# 日志与审计
SecAuditEngine RelevantOnly
SecAuditLog /var/log/modsec_audit.log
# Parts: A (request headers), B (request body), F (response headers), H (audit log trailer)...
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLogStorageDir /var/log/modsec_audit/
# 全局默认动作(Anomaly scoring 推荐)
SecDefaultAction "phase:1,log,pass"
SecDefaultAction "phase:2,log,deny,status:403"
# 请求体/响应体访问控制(默认开启请求体检查)
SecRequestBodyAccess On
SecRequestBodyLimit 13107200 # 12.5 MB (根据业务调整)
SecRequestBodyNoFilesLimit 131072 # 非文件 body 限制(128KB)
SecRequestBodyInMemoryLimit 131072 # 128KB
# 最大文件上传限制(CRS 有时也需要)
SecUploadDir /var/cache/modsecurity/uploads
SecRequestBodyLimitAction Reject
# 响应体分析(默认关闭,除非特定需求)
SecResponseBodyAccess Off
# 若开启,限制大小以免 OOM
SecResponseBodyLimit 5242880 # 5 MB
# utf-8 / unicode 映射
SecUnicodeMapFile /etc/nginx/modsec/unicode.mapping
# 安全策略:允许临时禁用某些规则
# (自定义 rules 文件在后面 Include)
# 兼容 CRS:指定 CRS path(CRS 安装后)
Include /etc/nginx/modsec/rules/*.conf
# 方便调试(生产建议关闭调试)
#SecDebugLog /var/log/modsec_debug.log
#SecDebugLogLevel 3
# 速率限制集成点(如与你的 nginx limit_req 联动)
# 若使用 Anomaly Scoring,设定阈值(示例)
#SecAction "id:900000,phase:1,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.score=0"
# 自定义 include(放在最后,保证你自定义的排除/豁免被加载)
Include /etc/nginx/modsec/requests_exclusions.conf
Include /etc/nginx/modsec/json_tuning.conf
Include /etc/nginx/modsec/business_exceptions.conf
说明:
SecAuditEngine RelevantOnly :只记录含有触发或异常的事务,避免太大日志。也可改为 On 全记录(日志量大)。
SecRequestBodyLimit 必须高于你 APP 最大 POST 大小(例如文件上传)。
SecResponseBodyAccess Off 推荐默认关闭(响应体检查 CPU/内存消耗较高)。
7) nginx 侧的配置(把 modsecurity 打开并指定配置文件)
在你的 nginx.conf http {} 或具体 server{} 中加入:
# 在 http {} 顶部(或 server/ location)
load_module modules/ngx_http_modsecurity_module.so;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
(你在镜像里编译时,已经用 modsecurity-nginx connector 集成,确保 load_module 路径与你镜像实际模块路径一致。官方编译为动态模块时需要 load_module;静态编译可直接用 modsecurity on; )
8) 从 DetectionOnly 到 On 的迁移步骤(建议流程)
在 modsecurity.conf 保持 SecRuleEngine DetectionOnly ,启动并观察 48–72 小时。
收集误报: /var/log/modsec_audit.log 与 nginx error.log。找出误报的 rule id(记录会标出匹配 id)。
对高误报的 rule 使用 ctl:ruleRemoveById=ID 或写更精确的 SecRule 以排除。也可以把特定 URI 设为 ruleEngine=Off 。
调整 Anomaly Scoring 阈值(CRS 有 threshold )或把某些 router 设置为 DetectionOnly。
确认误报控制在可接受范围后,将 SecRuleEngine On 切换为阻断模式。
继续定期检查 audit logs,更新豁免规则。
9) 常见调优建议(实战小贴士)
把 health 与 static 放在最前面(phase:1),减轻 WAF 负担。
对 JSON heavy API:优先使用 JSON 解析器( ctl:requestBodyProcessor=JSON )。
大流量场景开启 SecAuditEngine RelevantOnly ,并把 SecAuditLog 存到独立磁盘或集中收集(ELK)。
配合 limit_req / limit_conn 做 L7 防刷,并用 fail2ban 及时封禁扫描源。
CRS 默认规则集经常更新,务必定期 git pull 并在预演环境运行测试。
保持规则 id 表的文档(哪些是你添加的、哪些被移除),便于审计。
10) 测试用例(快速验证)
健康检查: curl -I http://yourhost/health → 应该返回 200,不被 WAF 阻断
静态文件: curl -I http://yourhost/static/image.jpg → 200
JSON POST: curl -X POST -H 'Content-Type: application/json' -d '{"name":"a"}' http://yourhost/api/test → 应该不被误报(先确认 DetectionOnly 模式里没有规则触发)
模拟注入(仅检测模式): curl "http://yourhost/?id=' or 1=1 --" → 应触发日志(如果 DetectionOnly,会记录但不阻断)
如果你要,我可以 立刻 :
基于你当前 docker-compose 路径,生成一份补丁包,包括 Dockerfile 的小改动(把文件写入镜像)和 docker-compose.override.yml 的示例,或
根据你 48 小时检测日志(把一段 modsec_audit.log 的 sample 粘过来),我来直接帮你写精确的 ctl:ruleRemoveById 列表和 fail2ban 正则优化。
你想直接把这些规则放进容器(我给出准确命令)还是先试运行并把检测期的 audit 日志贴过来让我分析误报?
下面我给你总结一套 Nginx + ModSecurity v3 + CRS WAF 在实际生产环境中能实现的 完整安全能力 (涵盖 OWASP Top 10、常见 Web 攻击、Bot 防护、协议校验、日志与响应体系),便于你评估是否满足你的公司平台安全需求。
⭐ 总体来看:ModSecurity v3 + CRS = 企业级 Web 反向代理型 WAF
具备完整 应用层防护 (L7 Security),覆盖:
OWASP Top 10(SQL、XSS、文件包含、权限绕过…)
业务层安全保护(参数校验、攻击语义分析)
协议校验(HTTP RFC)
智能启发式攻击识别
日志、审计、行为分析
与 Nginx 完美集成,性能远优于 ModSec v2
🛡 一、网络 & 协议层安全
ModSecurity v3 + CRS 对 HTTP 协议提供严格校验:
✔ HTTP RFC 规范校验
检查 HTTP 头是否合法
检查非法方法(如 TRACE 、 CONNECT )
检查过长 URI、Header、Body
防止 Request Smuggling(请求走私)
防止 Response Splitting(响应拆分)
✔ 防御异常连接行为
FD(文件描述符)耗尽
无效 Content-Length
Chunked 伪造攻击
不完整的 multipart 请求
🧬 二、覆盖所有 OWASP Top 10 攻击类型
1. SQL 注入(SQLi)
CRS 能检测:
单引号、注释符尝试
UNION SELECT
OR 1=1
sleep(5) / 盲注
MySQL / PostgreSQL / MSSQL 语义特征
支持高级语义识别:绕过编码、空格替换、%00、HEX 编码、ASCII 编码等。
2. XSS 跨站脚本攻击
包括: