一、核心安全配置
1. 编译安装 Nginx
-
(1)安装支持软件
安装编译所需的基础工具和依赖库:
bashyum install -y gcc make pcre pcre-devel zlib zlib-devel openssl openssl-devel -
(2)创建运行用户、组和日志目录
为 Nginx 创建一个无登录权限的专用用户和组,并创建日志目录:
bashgroupadd nginx useradd -M -s /sbin/nologin -g nginx nginx mkdir -p /var/log/nginx chown -R nginx:nginx /var/log/nginx -
(3)编译安装 Nginx
下载源代码,配置编译选项(禁用不需要的模块,添加需要的模块),编译并安装:
bashwget http://nginx.org/download/nginx-1.24.0.tar.gz tar zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 ./configure \ --user=nginx \ --group=nginx \ --prefix=/usr/local/nginx \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --without-http_autoindex_module \ --without-http_ssi_module make && make install--user和--group指定运行用户/组,--prefix指定安装目录,--with-*添加模块,--without-*禁用模块。 -
(4)添加 Nginx 系统服务
创建 Systemd 服务文件
/usr/lib/systemd/system/nginx.service:ini[Unit] Description=The nginx HTTP and reverse proxy server After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target然后启用并启动服务:
bashsystemctl daemon-reload systemctl enable nginx systemctl start nginx
2. 隐藏版本号
编辑 Nginx 主配置文件 /usr/local/nginx/conf/nginx.conf:
nginx
http {
server_tokens off; # 在 http 块中添加此行
...
}
重新加载配置生效:nginx -s reload。 这样在错误页面和响应头中将不会显示 Nginx 版本号。
3. 限制危险请求方法
在需要限制的虚拟主机配置(server 块)中添加:
nginx
server {
...
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
...
}
444 是 Nginx 特有的状态码,表示关闭连接而不发送响应头。这限制了只允许 GET, HEAD, POST 方法。
4. 请求限制(cc攻击防御)
-
(1)使用 Nginx 的
limit_req模块限制请求速率在
http块中定义共享内存区和速率限制参数:nginxhttp { limit_req_zone $binary_remote_addr zone=req_per_ip:10m rate=10r/s; # 每秒10次请求 ... }在需要限制的
server或location块中应用:nginxserver { location / { limit_req zone=req_per_ip burst=20 nodelay; # 突发20个请求,无延迟排队 ... } }burst允许突发请求数,nodelay表示立即处理突发请求但超出限制后直接返回 503。 -
(2)压力测试实验
使用
ab(ApacheBench) 进行测试:bashab -n 1000 -c 100 http://your-domain.com/ # 模拟1000个请求,100个并发观察 Nginx 日志 (
/var/log/nginx/access.log) 和错误日志 (/var/log/nginx/error.log),查看是否有 503 错误或限制生效的记录。
5. 防盗链
-
(1)什么是防盗链
防盗链 (Hotlink Protection) 是指防止其他网站未经授权直接链接引用您服务器上的资源(如图片、视频、文件),消耗您的带宽和服务器资源。
-
(2)配置防盗链
在需要保护的
location块(通常是图片、资源文件)中配置:nginxlocation ~* \.(jpg|gif|png|css|js)$ { valid_referers none blocked server_names *.your-domain.com ~\.google\. ~\.bing\. ~\.baidu\. ~\.qq\.; # 白名单域名 if ($invalid_referer) { return 403; # 或者 rewrite ^ /path/to/denied-image.png; } }valid_referers定义了合法的来源域名(包括空none、被防火墙标记为blocked的、本机server_names、以及正则匹配的搜索引擎)。$invalid_referer变量在来源不合法时为1。
二、高级防护
1. 动态黑名单
-
(1)编辑黑名单配置文件
创建一个文件(如
/usr/local/nginx/conf/blocklist.conf)存放黑名单 IP:nginx# blocklist.conf geo $blocked_ip { default 0; 192.168.1.100 1; # 手动添加的 IP 10.0.0.50 1; }使用
geo模块创建变量$blocked_ip,被列出的 IP 其值为1。 -
(2)编辑主配置文件
在主配置文件
nginx.conf的http块中包含黑名单文件:nginxhttp { include blocklist.conf; ... }在需要应用黑名单的
server块中:nginxserver { if ($blocked_ip) { return 444; # 或者 403 } ... }如果
$blocked_ip为1,则拒绝访问。 -
(3)使用封禁 IP 测试访问
从被封禁的 IP 地址尝试访问服务器,应该被拒绝或返回 444/403。
-
(4)自动添加黑名单
可以使用脚本分析日志(如
fail2ban),自动将频繁触发规则(如请求限制、扫描行为)的 IP 追加到blocklist.conf,然后通过nginx -s reload重新加载配置使其生效。脚本逻辑需谨慎设计,避免误封。
2. Nginx HTTPS 配置
2.1 https 概念
-
(1)http 为什么不安全
HTTP 协议传输的数据是明文的,包括 URL、请求头、请求体、响应内容。攻击者可以在网络传输的各个环节(如路由器、公共 Wi-Fi)进行窃听、篡改、冒充(中间人攻击)。
-
(2)安全通信的四大原则
- 保密性:只有通信双方能理解内容。
- 完整性:数据在传输过程中未被篡改。
- 认证:确认通信对方的身份。
- 不可否认性:发送方事后不能否认发送过信息。
-
(3)https 通信原理简述
HTTPS = HTTP + SSL/TLS。TLS 协议在 TCP 连接之上建立了一个加密的安全通道:
- 握手阶段 :
- 客户端发送支持的加密套件列表。
- 服务器选择加密套件,并发送其证书(包含公钥)。
- 客户端验证证书有效性(由可信 CA 签发)。
- 客户端生成一个随机对称密钥,用服务器的公钥加密后发送给服务器。
- 服务器用私钥解密得到对称密钥。
- 双方使用这个对称密钥进行后续通信加密。该密钥也称为会话密钥。
- 加密通信阶段:使用协商好的对称加密算法和会话密钥加密 HTTP 数据进行传输。
- 握手阶段 :
2.2 Nginx 配置 https 证书
-
(1)使用 openssl 生成证书和私钥
生产环境请使用正规 CA 颁发的证书! 以下为自签名证书生成步骤(仅用于测试):bashmkdir -p /usr/local/nginx/conf/ssl cd /usr/local/nginx/conf/ssl # 生成私钥 openssl genrsa -out server.key 2048 # 生成证书签名请求 (CSR) openssl req -new -key server.key -out server.csr # 按要求填写信息 # 生成自签名证书 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -
(2)Nginx 启用 https
在虚拟主机配置 (
server块) 中配置监听 443 端口并指定证书:nginxserver { listen 443 ssl http2; # 启用 HTTP/2 server_name your-domain.com; ssl_certificate /usr/local/nginx/conf/ssl/server.crt; # 证书路径 ssl_certificate_key /usr/local/nginx/conf/ssl/server.key; # 私钥路径 # 安全增强配置 (可选但推荐) ssl_protocols TLSv1.2 TLSv1.3; # 禁用不安全协议 ssl_ciphers HIGH:!aNULL:!MD5; # 强密码套件 ssl_prefer_server_ciphers on; # 服务器优先选择密码套件 ssl_session_cache shared:SSL:10m; # 会话缓存 ssl_session_timeout 10m; # 会话超时 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # HSTS location / { root html; index index.html index.htm; } }将 HTTP 请求重定向到 HTTPS (可选):
nginxserver { listen 80; server_name your-domain.com; return 301 https://$server_name$request_uri; # 永久重定向 } -
(3)测试
- 访问
http://your-domain.com,应自动跳转到https://your-domain.com。 - 浏览器地址栏应显示锁标识,点击可查看证书信息(自签名证书会有警告)。
- 使用在线工具(如 SSL Labs 的 SSL Server Test)进行安全评估。
- 访问
这份指南提供了 Nginx 安全配置的核心和高级防护措施的详细步骤。请根据您的实际环境和需求进行调整。安全配置是一个持续的过程,需要定期审查和更新。