Nginx 安全防护与Https 部署实战
目录
一、核心安全配置
1. 编译安装 Nginx
2. 隐藏版本号
3. 限制危险请求方法
4. 请求限制(CC 攻击防御)
(1)使用 Nginx 的 limit_req 模块限制请求速率
(2)压力测试验证
5. 防盗链
二、高级防护
1. 动态黑名单
2. nginx https 配置
(1)https 概念
概述
HTTP 为什么不安全?
安全通信的四大原则
HTTPS 通信原理简述
数字证书,解决公钥传输信任问题
https 总结
(2)nginx 配置 https 证书
使用 openssl 生成证书和私钥生成证书和私钥:
nginx 启用https:
通过浏览器验证:
一、核心安全配置
1. 编译安装 Nginx
(1)安装支持软件
dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker git wget tar
(2)创建运行用户、组和日志目录
useradd -M -s /sbin/nologin nginx //创建用户
mkdir -p /var/log/nginx //创建日志目录
chown -R nginx:nginx /var/log/nginx //设置文件属性
(3)编译安装 Nginx
tar zxf nginx-1.26.3.tar.gz //解压源码包
cd nginx-1.26.3 //进入./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx.pid --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream //编译
make && make install //编译安装##为主程序 nginx 创建链接文件
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
编译选项解析:
./configure # 配置编译参数
--prefix=/usr/local/nginx # 安装目录
--pid-path=/var/run/nginx.pid # PID文件路径
--user=nginx --group=nginx # 运行用户/组
--with-http_ssl_module # 支持HTTPS
--with-http_v2_module # 支持HTTP/2
--with-http_realip_module # 获取客户端真实IP(代理场景)
--with-http_stub_status_module # 启用状态监控页
--with-http_gzip_static_module # 发送预压缩静态文件
--with-pcre # 支持正则表达式
--with-stream # 支持TCP/UDP四层代理
(4)添加 Nginx 系统服务
vim /lib/systemd/system/nginx.service
### /lib/systemd/system 目录下都是系统服务
[Unit]
Description=my nginx
After=network.target[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/sbin/nginx
ExecStop=/usr/local/sbin/nginx -s stop
ExecReload=/usr/local/sbin/nginx -s reload[Install]
WantedBy=multi-user.targetsystemctl start nginx //启动服务
systemctl daemon-reload //重载文件重新读取
netstat -anpt | grep nginx //检查是否启动成功
2. 隐藏版本号
目的:防止攻击者利用特定版本漏洞。
# 修改 nginx.conf
vim /usr/local/nginx/conf/nginx.confhttp { server_tokens off; # 隐藏版本号
} nginx -t //测试文件
nginx -s reload //重新加载 Nginx 配置文件# 验证
curl -I 本机IP //查看Nginx信息
3. 限制危险请求方法
目的:禁用非常用 HTTP 方法(如 DELETE
、PUT
),防止恶意操作。
# 修改配置文件
server { listen 80; server_name example.com; # 仅允许 GET、POST、HEAD 方法 ; "!~" 取反if ($request_method !~ ^(GET|POST|HEAD)$ ) { return 405; # Method Not Allowed } # 处理 OPTIONS 方法(防止跨站请求伪造) if ($request_method = 'OPTIONS') { return 444; # 无响应关闭连接 }
} # 验证
curl -XPUT -I 本机IP ##结果返回错误,无法访问# 查看 access.log 日志
cat /usr/local/nginx/logs/access.log
4. 请求限制(CC 攻击防御)
目的:限制单个 IP 的请求频率和并发连接数,防御 CC 攻击。
CC 攻击即 Challenge Collapsar(挑战黑洞)攻击,是一种常见的网络攻击手段。它通过模拟多个正常用户向目标服务器发送大量合法请求,耗尽服务器资源,导致服务器无法正常响应其他正常请求,从而使网站或服务瘫痪。
(1)使用 Nginx 的 limit_req 模块限制请求速率
#编辑配置文件
http {#定义限制区 (10MB 内存/每秒10请求)limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;#其他全局配置。。。。。server {location / {root html;index index.html index.php;limit_req zone=req_limit burst=20 nodelay;}}
参数说明:
- “limit_req_zone” 表示启用请求限制区域的配置指令。
- “$binary_remote_addr” 是一个变量,这里代表客户端的 IP 地址,以二进制形式存储,用于标识每个客户端。
- “zone=req_limit:10m” 指定义一个名为 “req_limit” 的共享内存区域,该区域大小为 10MB,这个区域用于存储请求限制相关的状态信息,比如每个 IP 地址的请求计数等。
- “rate=10r/s” 表示限制速率为每秒 10 个请求,即每个 IP 地址在每秒内最多只能发起 10 个请求。如果超过这个速率,后续的请求可能会被限流处理,比如返回错误响应等。
- “limit_req” 表示启用请求限制功能。
- “zone=req_limit” 指定使用名为 “req_limit” 的限制区域,这个区域通常在配置文件的其他地方定义,包含了一系列关于请求限制的参数设置,比如时间周期、请求速率等。
- “burst=20” 指允许的突发请求数量为 20 个。即在短时间内,系统除了按正常速率处理请求外,还能额外处理这 20 个突发的请求。例如,正常情况下每秒只允许处理 10 个请求,但如果有突发情况,系统可以在瞬间处理 20 个请求。
- “nodelay” 表示不延迟处理请求。一般来说,当请求速率超过限制时,可能会进行排队延迟处理,而加上这个参数后,超出限制的请求会立即被处理,不会等待。
(2)压力测试验证
#安装 ab 测试工具
dnf -y install httpd-tools #发起测试请求(共发300个请求。每次发起30个请求)
ab -n 300 -c 30 http://192.168.10.101(本机)#查看日志access.log 发现大量请求日志状态码
tail -300 /usr/local/nginx/logs/access.log |grep -c
//返回结果 503
5. 防盗链
目的:防止其他网站盗用图片、视频等资源。
#配置Nginx 防盗链,修改配置文件
server { listen 80; server_name example.com;
#新添加location 块location ~* \.(jpg|png|gif|jpeg|bmp|swf|flv|webp|ico|mp4)$ { root html; # 允许空 Referer(直接访问)和本站域名 valid_referers none blocked aaa.com *.aaa.net; if ($invalid_referer) { # 返回 403 或重定向到警告图片 return 403; } # 资源路径配置 root /var/www/static; }
} ##重启服务
注释:~* \. (jpg|gif|...)$ : 正则表达式,表示匹配不区分大小写 。
valid_referers :设置信任网站。
后面的网址或者域名: referer 中包含相关字符串的网址。
if 语句:如果链接的域名不在,valid_referers 所列出的列表中。$invalid_referer 为1,则执行后面操作,即进行重写或返回403页面。
二、高级防护
1. 动态黑名单
目的:根据实时条件(如频繁失败请求)自动封禁恶意 IP,防御暴力破解和 DDoS 攻击。
-
编辑黑名单文件
vim /usr/local/nginx/conf/blockips.conf 192.168.1.0/24 1; #封禁整个网段 192.168.10.201 1; #封禁 IP##IP地址后的数字含义 0 ""; # 允许 1 403; # 完全封禁 2 444; # 静默断开 3 503; # 服务不可用
-
定义黑名单存储:
# 在 http 块中定义共享内存区 http { geo $blocked_ip { default 0; include /etc/nginx/conf.d/blocked_ips.conf; # 黑名单 IP 列表 } }
-
动态更新黑名单(结合脚本与日志分析):
# 示例脚本(block_ip.sh):检测日志中失败次数超限的 IP #!/bin/bash LOG_FILE="/var/log/nginx/access.log" BLOCK_FILE="/etc/nginx/conf.d/blocked_ips.conf" FAIL_LIMIT=10 # 允许的最大失败次数 # 提取过去 5 分钟内失败请求超过 10 次的 IP grep " 403 " $LOG_FILE | awk '$1 >= "$(date -d '5 minutes ago' +%H:%M:%S)" {print $1}' | sort | uniq -c | awk -v limit=$FAIL_LIMIT '$1 > limit {print "deny " $2 ";"}' > $BLOCK_FILE # 重载 Nginx 配置 nginx -s reload
-
应用黑名单:
http { ....geo $blocked_ip { #geo 内置模块指令,专门处理IP地址相关的逻辑default 0; #默认允许访问include /usr/local/nginx/conf/blockips.conf; #包含黑名单}server { location / { #判断标记值if ($blocked_ip) { return 403; # 封禁黑名单 IP } # 其他配置... } }
2. nginx https 配置
(1)https 概念
-
概述
HTTPS(HTTP Secure)是 HTTP 的安全版本,通过 SSL/TLS 加密 保护数据传输的机密性和完整性。
-
HTTP 为什么不安全?
明文传输:数据可被中间人窃听(如密码、Cookie)。
无身份验证:无法验证服务器真实性,易受钓鱼攻击。
-
安全通信的四大原则
- 保密性:确保数据在传输过程中不被第三方获取。
- 完整性:保证数据在传输过程中不被篡改。
- 身份验证:确认通信双方的真实身份。
- 不可否认性:防止通信双方事后否认曾经进行过的通信。
-
HTTPS 通信原理简述
客户端发起请求:请求 HTTPS 连接。
服务端返回证书:包含公钥和域名信息。
客户端验证证书:确认证书有效且由受信任机构签发。
密钥协商:通过非对称加密生成会话密钥。
对称加密通信:使用会话密钥加密后续数据传输。
-
数字证书,解决公钥传输信任问题
数字证书是由权威的证书颁发机构(CA)颁发的,用于证明服务器或客户端的身份。
数字证书中包含了服务器或客户端的公钥、证书颁发机构的信息、证书有效期等信息。
客户端在接收到服务器的数字证书后,可以通过验证证书的签名来确认服务器的身份和公钥的真实性。
-
https 总结
HTTPS 通过加密和身份验证机制,解决了 HTTP 协议的安全问题,为用户提供了更安全的网络通信环境。在实际应用中,建议使用由权威 CA 颁发的证书来提高网站的安全性和可信度。同时,还可以通过配置 SSL/TLS 协议版本和加密算法等参数来进一步增强 HTTPS 的安全性。
优势 注意事项 数据加密防窃听 证书需定期更新(Let's Encrypt 证书有效期为 90 天) 身份认证防钓鱼 选择强加密协议(禁用 SSLv3、TLSv1.0) 提升 SEO 排名 配置 HSTS 增强安全性 符合 GDPR 等合规要求 监控证书到期时间,避免服务中断
(2)nginx 配置 https 证书
-
使用 openssl 生成证书和私钥生成证书和私钥:
#创建证书储存目录 mkdir -p /etc/nginx/ssl# 生成自签名证书(有效期 365 天) openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx-selfsigned.key -out /etc/nginx/ssl/nginx-selfsigned.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=localhost"
参数解释:
openssl req
:调用 OpenSSL 的证书请求(request)功能。
-x509
:表示生成 X.509 格式的自签名证书,而不是证书请求。
-nodes
:生成的私钥不加密,即没有密码保护。
-days 365
:指定证书的有效期为 365 天。
-newkey rsa:2048
:生成一个 2048 位的 RSA 私钥,并创建一个新的证书请求。
-keyout /etc/nginx/ssl/nginx-selfsigned.key
:指定生成的私钥保存路径为/etc/nginx/ssl/nginx-selfsigned.key
。
-out /etc/nginx/ssl/nginx-selfsigned.crt
:指定生成的自签名证书保存路径为/etc/nginx/ssl/nginx-selfsigned.crt
。
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=localhost"
:设置证书的主题(subject)信息,C=CN
表示国家为中国,ST=Beijing
表示省份为北京,L=Beijing
表示城市为北京,O=MyOrg
表示组织为 MyOrg,CN=localhost
表示通用名称为localhost。这条命令常用于为 Nginx 服务器快速生成自签名证书,以实现 HTTPS 通信,但自签名证书不被浏览器等客户端默认信任。
-
nginx 启用https:
server { listen 443 ssl; #监听HTTPS端口server_name example.com; #域名或IP# 证书配置 指定证书和私钥路径ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt; ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key; # ssl加密协议与套件优化 (可选,提升安全性)ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; #将HTTP请求重定向到HTTPSreturn 301 https://$host$request_uri;# 强制 HTTP 跳转到 HTTPS if ($scheme = http) { return 301 https://$host$request_uri; #“301” 表示永久重定向} # 其他配置... (如根目录)location / {root /usr/local/nginx/html;index index.html;} } ##重启服务
通过浏览器验证:
-
访问
https://example.com
,检查地址栏是否有锁标志。 -
使用工具 SSL Labs Test 检测配置安全性。