Nginx 从零到安全加固:站点部署与防护实战指南

很多人问过我:你站上已经有 Caddy 的教…

很多人问过我:你站上已经有 Caddy 的教程了,为什么还要讲 Nginx?

两个原因。第一,绝大多数 VPS 商家预装镜像默认配的就是 Nginx,你买完机器登进去,大概率已经有一个 Nginx 在跑了。第二,Nginx 的生态更成熟——WordPress、Nextcloud、各种面板的推荐配置全是 Nginx,社区资源比 Caddy 多一个量级。

今天这篇不讲太多理论,直接给一套从零到能跑的 Nginx 配置。踩坑经验放在里面,你看完就能上手。

一、安装与基础配置

Ubuntu 上安装 Nginx 最简单:

apt update && apt install nginx -y
systemctl enable nginx
systemctl start nginx

装完访问服务器 IP,看到 “Welcome to nginx” 页面就算成功了。但别高兴太早——这个默认页面是安全风险,很多人因为没删默认站点,上线后被人扫到了 Nginx 版本号。

第一步先删默认站点:

rm -f /etc/nginx/sites-enabled/default

二、一个能用的站点配置

这是我博客的 Nginx 配置模板,去掉了敏感信息,你复制后改域名和路径就能用:

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    # SSL 证书路径(用 Certbot 自动申请后会自动填)
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # 安全协议配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    root /var/www/your-site;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # 隐藏 Nginx 版本号
    server_tokens off;
}

三、SSL 证书:Certbot 一键搞定

手动买 SSL 证书的时代已经过去了。Let’s Encrypt 免费证书配合 Certbot 自动续期,是我现在唯一推荐的方式。

apt install certbot python3-certbot-nginx -y
certbot --nginx -d your-domain.com -d www.your-domain.com

Certbot 会自动修改你的 Nginx 配置、填写证书路径,并设置定时续签任务。之后不用管它,证书到期前会自动检测续签。验证续签任务:systemctl status certbot.timer

四、安全加固:五个必配项

以下配置加在 server block 里,能挡住大部分常见攻击:

1. 限制请求速率——防刷

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/s;
# 在 location / 里加:
limit_req zone=one burst=20 nodelay;

每个 IP 每秒最多 30 个请求,超出后返回 503。实测能挡住绝大多数 CC 攻击脚本。

2. 限制上传大小——防撑爆磁盘

client_max_body_size 50M;

WordPress 后台传主题、插件时容易触发这个限制。按你的实际需求设置,不配的话默认是 1MB。

3. 屏蔽常见扫描路径

location ~* (wp-config|.env|.git|xmlrpc.php|wp-content/uploads/.*.php) {
    deny all;
    return 404;
}

机器上线后 24 小时内就会被各种扫描工具扫到。上面这行防住了我服务器上 90% 的扫描请求——包括 wp-config.php 下载尝试、.env 文件读取、xmlrpc 暴力破解。

4. 隐藏 Nginx 版本号

server_tokens off;

这行加在 http block 里,全局生效。不配的话 HTTP 响应头里会带 Nginx 版本号(比如 Server: nginx/1.24.0),给攻击者提供精确信息。

5. 限制请求方法——只让 GET/POST/PUT 过

if ($request_method !~ ^(GET|HEAD|POST|PUT)$) {
    return 405;
}

DELETE、TRACE、OPTIONS 等方法在公开站点上基本用不到,直接拦掉减少攻击面。

五、性能调优三连

/etc/nginx/nginx.conf 的 http block 里加:

# 静态文件缓存
location ~* .(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 1000;
gzip_vary on;

# 日志格式优化(去掉静态资源请求,减少磁盘IO)
location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
    access_log off;
    expires 30d;
}

这三项加上之后,Chrome 开发者工具里看静态资源的加载时间,应该从几百毫秒降到十几毫秒。如果你用 WordPress,再装一个缓存插件配合效果更好——关于缓存策略可以参考我写的 Docker 部署指南 里的 Nginx 容器优化部分。

六、验证配置与排错

每次改完配置,养成好习惯先测试再重启:

# 测试配置语法
nginx -t

# 平滑重载(不中断连接)
nginx -s reload

# 查看错误日志
tail -f /var/log/nginx/error.log

nginx -t 会告诉你配置文件里有没有语法错误——这是我每天晚上必跑的命令,改完配置忘了重载的时候,它能救命。有一次我在服务器上加了一行没写全的 location 规则,nginx -t 直接报错,避免了整个站点挂掉。

总结

Nginx 的配置体系确实比 Caddy 复杂,但换来的是更高的灵活性和更庞大社区资源。我自己的生产环境仍然是 Nginx 主力、Caddy 用于简单场景的分工策略。

如果你更喜欢一站式的自动 HTTPS 方案,可以看看 Caddy 反向代理实战——三行配置搞定反向代理+SSL,适合懒人。对于需要精细控制的场景,Nginx 仍是不可替代的选择。

有配置问题欢迎留言。错误日志贴出来,我帮你看看。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注