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 仍是不可替代的选择。
有配置问题欢迎留言。错误日志贴出来,我帮你看看。
