Nginx安全防护与HTTPS部署实战笔记

Nginx作为高性能的HTTP和反向代理服务器 广泛应用于生产环境 但默认配置存在诸多安全隐患 易遭受SQL注入 XSS CSRF DDoS等攻击 同时 HTTP协议传输数据明文可见 存在数据泄露风险

核心目标:通过配置加固提升Nginx抗攻击能力 通过HTTPS实现数据加密传输 符合生产环境安全规范

Nginx安全防护实战配置

安全防护核心思路:最小权限原则 禁用不必要功能 拦截恶意请求 隐藏敏感信息 限制请求频率

隐藏Nginx版本信息

默认情况下,Nginx响应头会暴露版本号及操作系统信息 攻击者可利用版本漏洞针对性攻击 需隐藏版本信息并自定义服务器标识

配置步骤:

  1. 编辑Nginx主配置文件(通常路径:/etc/nginx/nginx.conf)

  2. 在http块中添加以下配置: # 隐藏版本号 server_tokens off; # 自定义服务器响应头标识(避免暴露Nginx) server_tag "Web Server"; # 隐藏X-Powered-By头(若后端有PHP等服务 需同步配置) ``add_header X-Powered-By "Custom Server" always

  3. 重启Nginx生效:systemctl restart nginx

  4. 验证:使用curl -I 域名 查看响应头中无Server: nginx/版本号 且X-Powered-By为自定义内容

限制请求频率(防御DDoS/CC攻击)

通过limit_req模块限制单个IP的请求频率 防止恶意请求占用服务器资源 需先确保Nginx编译时启用了limit_req模块(默认启用)

配置步骤:

  1. 在http块中定义请求限制规则(全局生效): # 定义请求频率限制池(name=req_limit,容量10,每秒允许2个请求,超出放入队列等待) ``limit_req_zone $binary_remote_addr zone=req_limit:10m rate=2r/s; ``# 限制单个IP的并发连接数(全局限制,可根据业务调整) ``limit_conn_zone $binary_remote_addr zone=conn_limit:10m; ``limit_conn conn_limit 10

  2. 在server块或location块中应用限制规则(针对具体站点/接口): server { `` listen 80; `` server_name example.com; `` # 应用请求频率限制,burst=5表示队列容量5,nodelay表示超出后直接返回503,不等待 `` limit_req zone=req_limit burst=5 nodelay; `` # 限制并发连接数(局部可覆盖全局) `` limit_conn conn_limit 8; `` ... ``}

  3. 重启Nginx 验证 使用ab工具压测(ab -n 100 -c 10 域名) 超出频率后会返回503状态码

拦截恶意请求(防御SQL注入、XSS)

通过location匹配规则 拦截包含恶意字符(如SQL注入语句 XSS脚本)的请求 直接返回403禁止访问

配置步骤(在server块中添加)

复制代码
# 拦截SQL注入相关字符
location ~* (union|select|insert|update|delete|drop|alter|truncate|exec) {
    return 403 "Forbidden: Malicious Request";
}
# 拦截XSS相关脚本字符
location ~* (<|>|script|javascript|alert|eval) {
    return 403 "Forbidden: Malicious Script";
}
# 禁止访问敏感文件(如.git、.env、配置文件)
location ~* (\.git|\_env|.conf|.log) {
    deny all;
    return 403;
}
# 限制请求方法(只允许GET、POST,禁止PUT、DELETE等)
if ($request_method !~ ^(GET|POST)$) {
    return 405;
}

配置安全响应头(增强浏览器安全)

通过add_header配置安全相关响应头 防止XSS 点击劫持等攻击 提升浏览器层面的安全性 配置在http块或server块中

复制代码
# 防止XSS攻击:禁止页面加载未授权脚本
add_header X-XSS-Protection "1; mode=block" always;
# 防止点击劫持:禁止页面被嵌入iframe
add_header X-Frame-Options "SAMEORIGIN" always;
# 限制资源加载:只允许同源资源(可根据业务调整为具体域名)
add_header Content-Security-Policy "default-src 'self'" always;
# 强制HTTPS:告知浏览器后续请求优先使用HTTPS(配合HTTPS部署)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 禁止泄露Referer信息(可选,根据业务需求)
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# 禁止浏览器自动解析MIME类型(防止恶意文件伪装)
add_header X-Content-Type-Options "nosniff" always;

最小权限配置(降低服务器风险)

  1. 修改Nginx运行用户:默认使用root用户 风险较高 需创建专用低权限用户(如nginx)在nginx.conf的user指令中修改: user nginx nginx; # 用户名 组名

  2. 修改网站目录权限:网站根目录(如/usr/share/nginx/html)权限设置为755 文件权限设置为644 禁止777权限:chown -R nginx:nginx /usr/share/nginx/html ``chmod -R 755 /usr/share/nginx/html ``chmod -R 644 /usr/share/nginx/html/*

  3. 禁用不必要的模块:编辑nginx.conf 注释掉不需要的模块(如autoindex自动索引模块)减少攻击面: # autoindex on; # 注释掉自动索引 避免暴露目录结构

HTTPS部署实战(Let's Encrypt免费证书)

HTTPS基于SSL/TLS协议 实现数据传输加密 需先获取SSL证书(推荐Let's Encrypt免费证书 有效期3个月 可自动续期) 部署流程分为:安装Certbot工具 获取证书 配置Nginx HTTPS 设置自动续期

环境准备

  1. 确保服务器已开放80、443端口(防火墙配置): # 开放80、443端口 ``firewall-cmd --permanent --add-port=80/tcp ``firewall-cmd --permanent --add-port=443/tcp ``# 重新加载防火墙 ``firewall-cmd --reload

  2. 确保域名已解析到当前服务器IP(公网环境 内网可使用自签名证书)

安装Certbot工具(获取免费证书)

  1. 安装EPEL源(CentOS系统):yum install epel-release -y

  2. 安装Certbot及Nginx插件: yum install certbot python3-certbot-nginx -y

获取Let's Encrypt证书

bash 复制代码
certbot --nginx -d example.com -d www.example.com
  1. 执行命令后,输入邮箱(用于证书到期提醒)同意服务条款 选择是否开启HTTPS重定向(推荐选择2 自动将HTTP请求重定向到HTTPS)

  2. 执行成功后 证书会自动保存到/etc/letsencrypt/live/example.com/目录下 包含以下文件

    1. fullchain.pem:完整证书链(包含服务器证书和根证书)

    2. privkey.pem:服务器私钥(请勿泄露)

    3. cert.pem:服务器证书

    4. chain.pem:根证书链

手动优化HTTPS配置(可选,增强安全性)

bash 复制代码
server {
    listen 443 ssl http2; # 启用HTTP/2,提升传输效率
    server_name example.com www.example.com;

    # SSL证书配置
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # 优化SSL协议(禁用不安全的SSLv2、SSLv3、TLSv1、TLSv1.1)
    ssl_protocols TLSv1.2 TLSv1.3;
    # 优化加密套件(优先使用安全的加密算法)
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    # 启用会话复用,提升性能
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    # 启用OCSP stapling,提升证书验证速度
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    # 安全响应头(可沿用之前的配置)
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 网站根目录及默认页面
    root /usr/share/nginx/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

# HTTP请求重定向到HTTPS(Certbot自动生成,可优化)
server {
    listen 80;
    server_name example.com www.example.com;
    # 永久重定向,告知浏览器后续优先使用HTTPS
    return 301 https://$host$request_uri;
}

设置证书自动续期

Let's Encrypt证书有效期为90天 需设置自动续期 避免证书过期导致服务不可用 通过crontab设置定时任务

  1. 执行以下命令 添加定时任务: crontab -e

  2. 添加以下内容(每天凌晨2点自动续期,续期成功后重启Nginx):0 2 * * * certbot renew --quiet --renew-hook "systemctl restart nginx"

  3. 验证定时任务:crontab -l 查看是否添加成功

--quiet表示静默续期 不输出日志 --renew-hook表示续期成功后执行的命令(重启Nginx使证书生效)

HTTPS验证

  1. 重启Nginx:systemctl restart nginx

  2. 浏览器访问https://example.com 查看地址栏是否有"小锁"图标 点击可查看证书信息

  3. 使用在线工具(如SSL Labs)检测HTTPS安全性 保评分达到A+

常见问题排查

Nginx重启失败

  • 问题原因:配置文件语法错误 端口被占用 权限不足

  • 排查方法: # 检查配置文件语法 ``nginx -t ``# 查看端口占用情况(80/443) ``netstat -tulnp | grep 80 ``netstat -tulnp | grep 443 ``# 查看Nginx日志(错误日志路径通常为/var/log/nginx/error.log) ``tail -f /var/log/nginx/error.log

HTTPS访问失败(提示证书无效)

  • 问题原因:证书路径配置错误 私钥与证书不匹配 域名与证书绑定不一致

  • 排查方法:

    • 检查证书路径是否正确(fullchain.pem和privkey.pem的路径)

    • 验证私钥与证书是否匹配: openssl rsa -noout -modulus -in /etc/letsencrypt/live/example.com/privkey.pem | openssl md5 ``openssl x509 -noout -modulus -in /etc/letsencrypt/live/example.com/cert.pem | openssl md5两次输出的md5值需一致 否则私钥与证书不匹配

    • 检查域名是否与证书绑定(Certbot获取证书时指定的域名需与访问域名一致)

安全防护配置后误拦正常请求

  • 问题原因:正则匹配规则过于严格 拦截了正常业务请求

  • 排查方法:查看Nginx访问日志(/var/log/nginx/access.log)找到返回403的请求 分析请求路径和参数 调整正则规则(如添加例外情况)

相关推荐
buhuimaren_2 小时前
Nginx核心功能
nginx
kiku18183 小时前
Nginx安全
nginx·web安全·https
上海云盾-小余5 小时前
等保 2.0 全攻略:企业合规建设与安全防护一站式指南
安全
萌兰三太子6 小时前
企业级 AI 智能体平台安全沙箱在 E2B 中的实现
人工智能·安全
卢傢蕊6 小时前
Nginx安全防护与HTTPS部署实战
nginx·安全·https
岁岁种桃花儿6 小时前
kubenetes从入门到上天系列第十九篇:Kubernetes安装Nginx ingress controller
java·nginx·kubernetes
胖头鱼的鱼缸(尹海文)7 小时前
数据库管理-第411期 OpenClaw进阶实战:升级+网关安全+飞书对接一次性搞定(20260315)
安全·飞书·openclaw
kc胡聪聪7 小时前
nginx安全
nginx
yhdata7 小时前
年复合增速11.5%!智慧安全巡检机器人,锚定未来六年高成长新航向
人工智能·安全·机器人