1. 为什么在 Ubuntu 20.04 上装 Nginx 不是“点几下就完事”,而是必须亲手过一遍的基建动作
你可能刚买了一台全新的云服务器,系统镜像选的是 Ubuntu 20.04 LTS——这个版本在 2024 年仍被大量生产环境采用,稳定、长期支持、软件源成熟。你打开终端,敲下
sudo apt update && sudo apt install nginx
,回车,提示“安装成功”,
systemctl status nginx
显示 active (running),浏览器访问
http://你的IP
出现 “Welcome to nginx!” 页面……看起来一切顺利。
但这就是终点吗?不。这恰恰是真正工作的起点。
我见过太多人卡在这一步之后:前端静态资源放进去却 404,反向代理后端服务时请求超时,HTTPS 配置完浏览器报“不安全”,日志里全是
connect() failed (111: Connection refused)
,甚至
sudo ufw allow 'Nginx Full'
执行后防火墙依然拦着 80 端口——查了半天发现 ufw 规则没生效,因为默认策略是 deny,而
ufw status verbose
显示的是 inactive。更隐蔽的是,
nginx.conf
里一句
include /etc/nginx/conf.d/*.conf;
被注释掉了,你新建的
myapp.conf
根本没被加载;或者
worker_processes auto;
在 4 核机器上跑出 8 个 worker,CPU 轮询反而拖慢响应。
这些不是“小问题”,而是 Ubuntu 20.04 + Nginx 组合中高频、高隐蔽性、高破坏力的“默认陷阱”。它们不会在安装阶段报错,却会在你部署第一个真实业务(比如一个 Vue 打包后的 dist 目录、一个 FastAPI 的
/api
接口、甚至一个简单的 JSON 验证码接口)时集中爆发。而 Ubuntu 20.04 的特殊性在于:它默认启用 systemd,但很多老教程还在用
chkconfig
思维;它默认禁用 IPv6,但 Nginx 编译时又默认监听
[::]:80
;它的
ufw
默认不启用,可一旦启用,规则顺序和协议匹配逻辑又和 iptables 有微妙差异。
所以,这篇内容不是教你怎么“装上”,而是带你亲手走通一条
从裸机到可交付 Web 服务
的完整链路:每一步命令背后是什么逻辑,每个配置项改了会触发什么连锁反应,哪些地方 Ubuntu 20.04 和 CentOS 7 表现不同,哪些热词(比如
sudo systemctl edit
、
nginx.conf
结构、
ufw allow samba command not found
这类错误提示)其实暴露的是更底层的认知断层。你不需要背命令,但需要知道——当
nginx -t
报错时,该先看哪一行;当
curl -I http://localhost
返回 502,该立刻检查哪三个文件;当
systemctl restart nginx
没反应,该用哪条
journalctl
命令挖出真正的 root cause。
这不是一份安装说明书,而是一份 Ubuntu 20.04 上 Nginx 的“生存地图”。
2. 安装前的三重确认:别让系统状态成为后续所有故障的隐形推手
很多人跳过这一步,直接
apt install
,结果装完发现
nginx -v
输出的是 1.18.0,而业务要求必须是 1.22+(因为要支持
proxy_http_version 1.1
的某些新特性),或者发现
nginx -V
里压根没有
--with-http_v2_module
,导致 HTTP/2 无法启用。这不是 Nginx 的问题,是你没看清 Ubuntu 20.04 官方源的“出厂设置”。
2.1 Ubuntu 20.04 官方源的 Nginx 版本与模块清单
Ubuntu 20.04 LTS 的
nginx
包来自
focal-updates
源,截至 2024 年中,其稳定版本为
1.18.0-6ubuntu1.5
。这个版本足够稳定,但有几个关键事实必须清楚:
-
不包含
ngx_http_geoip2_module:如果你需要基于 GeoIP2 的地域分流,官方源不提供,必须手动编译或换源; -
--with-http_ssl_module是启用的 :HTTPS 支持没问题,但 OpenSSL 版本是 1.1.1f,不支持 TLS 1.3 的某些新 cipher suite(如TLS_AES_128_GCM_SHA256),需手动升级 OpenSSL 或换用 PPA; -
--with-http_v2_module是启用的 :HTTP/2 支持开箱即用,但默认配置未开启,需在server块中显式写listen 443 ssl http2;; -
--with-http_realip_module是启用的 :这对获取真实客户端 IP 至关重要,尤其在反向代理场景下,但默认real_ip_header是X-Real-IP,而很多前端框架(如 Nuxt)发请求时用的是X-Forwarded-For,这里就埋下了 502 的伏笔。
验证方式很简单,装完后执行:
nginx -V 2>&1 | grep -E "(version|configure arguments)"
你会看到类似输出:
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f 31 Mar 2020
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx ... --with-http_ssl_module --with-http_v2_module ...
提示:
nginx -V(大写 V)显示编译参数,nginx -v(小写 v)只显示版本号。很多新手混淆两者,导致误判模块可用性。
2.2 系统级依赖与冲突预检:ufw、systemd、SELinux 的“三重门”
Ubuntu 20.04 默认不启用 SELinux(它用的是 AppArmor),这点和 CentOS 7 完全不同,所以
setsebool
、
sestatus
这类命令在这里毫无意义,强行运行只会报错。但
ufw
和
systemd
是真·主角。
-
ufw 状态必须明确 :执行
sudo ufw status verbose。如果输出Status: inactive,说明防火墙根本没开,此时sudo ufw allow 'Nginx Full'是无效操作。正确流程是:先sudo ufw enable(会提示是否继续,输入y),再sudo ufw allow 'Nginx Full'。而'Nginx Full'这个应用配置文件,实际位于/etc/ufw/applications.d/nginx,它定义了开放 80/tcp 和 443/tcp。如果你看到sudo ufw allow samba command not found这类错误,99% 是因为ufw本身没启用,或者你打错了应用名(比如写成samba而不是Samba,大小写敏感)。 -
systemd 服务单元文件的“隐藏路径” :Ubuntu 20.04 的 Nginx 服务由
/lib/systemd/system/nginx.service管理。这个文件里有一行关键配置:ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'。意思是每次systemctl start nginx前,都会先执行nginx -t做语法检查。如果nginx.conf有语法错误,systemctl start会直接失败,并在journalctl -u nginx里留下nginx: [emerg]错误。这是 systemd 的保护机制,但新手常误以为是“服务没启动”,反复systemctl restart,却不知问题出在配置文件。 -
磁盘空间与 inodes 预检 :
df -h看/分区剩余空间,df -i看 inodes 使用率。Nginx 日志(尤其是 access.log)在高并发下会快速消耗 inodes。我曾遇到一个案例:df -h显示还有 20GB 空间,但df -i显示 inodes 100% 耗尽,导致nginx -t执行时提示open() "/var/log/nginx/error.log" failed (24: Too many open files)—— 这其实是 inodes 耗尽的典型伪装错误。解决方案不是调大ulimit,而是清理旧日志:sudo find /var/log/nginx -name "*.log.*" -mtime +30 -delete。
2.3 网络栈基础:IPv4/IPv6 双栈的“静默开关”
Ubuntu 20.04 默认启用 IPv6,但很多云厂商(如阿里云、腾讯云)的内网网络并不支持 IPv6,导致 Nginx 启动时尝试监听
[::]:80
失败,进而整个服务启动失败。错误日志在
journalctl -u nginx
中表现为:
nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
这不是 Nginx 的 bug,是系统网络栈和云平台的兼容性问题。解决方法有两个:
-
临时禁用 IPv6 监听
:在
/etc/nginx/sites-enabled/default的server块中,把listen [::]:80 default_server;这行注释掉,只保留listen 80 default_server;; -
永久禁用系统 IPv6(谨慎)
:编辑
/etc/sysctl.conf,添加:
然后net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1sudo sysctl -p生效。但此操作会影响所有 IPv6 应用,仅推荐在纯 IPv4 环境下使用。
注意:
ipv6 双栈 服务器 nginx 日志这个热词,本质是在问——当服务器同时支持 IPv4 和 IPv6 时,如何让 Nginx 日志区分来源?答案是:在log_format中加入$remote_addr(它会自动显示 IPv4 地址或 IPv6 地址),无需额外配置。但前提是你的网络栈和 Nginx 都真正支持双栈。
3. 从零构建可验证的 Nginx 服务:不只是
apt install
,而是五步闭环
安装命令
sudo apt install nginx
只是第一步。真正的服务就绪,需要完成一个闭环:安装 → 配置 → 测试 → 启动 → 验证。漏掉任何一环,都可能在上线后半夜收到告警。
3.1 第一步:安装与基础服务控制(
systemctl
的正确姿势)
执行标准安装:
sudo apt update
sudo apt install nginx
安装完成后,
不要立刻
systemctl start nginx
。先做三件事:
-
检查服务单元状态 :
systemctl list-unit-files | grep nginx # 应看到 nginx.service enabled systemctl is-enabled nginx # 应返回 enabled -
理解
systemctl的四个核心命令 :-
sudo systemctl start nginx:启动服务(一次性的,重启后不自动); -
sudo systemctl enable nginx:设置开机自启(写入/etc/systemd/system/multi-user.target.wants/nginx.service符号链接); -
sudo systemctl daemon-reload:当修改了/lib/systemd/system/nginx.service文件后,必须执行此命令让 systemd 重新读取配置; -
sudo systemctl edit nginx:这是热词sudo systemctl edit 的编辑器如何使用的正解。它会创建一个覆盖目录/etc/systemd/system/nginx.service.d/override.conf,用于安全地覆盖原服务文件的某几行(比如修改Environment="NGINX_ENV=prod"),而不用直接编辑原始文件,避免apt upgrade时被覆盖。执行后,系统会自动调用默认编辑器(通常是nano),你只需在里面写:
保存退出即可。这是比直接改[Service] Environment="NGINX_ENV=prod"/lib/systemd/system/nginx.service更安全、更符合 Linux 最佳实践的做法。
-
-
首次启动并观察日志 :
sudo systemctl start nginx sudo systemctl status nginx # 必须看到 "active (running)" 且无红色 error 字样 sudo journalctl -u nginx -n 20 --no-pager # 查看最近 20 行日志,确认无 emerg/fatal 级别错误
3.2 第二步:配置文件结构解析(
nginx.conf
的“宪法”地位)
Ubuntu 20.04 的 Nginx 配置采用“主配置 + 模块化包含”的设计,其结构是:
/etc/nginx/nginx.conf ← 主配置文件,定义全局指令(user, worker_processes, events, http)
├── /etc/nginx/conf.d/ ← 存放通用配置片段,如 gzip、log_format(默认被 include)
├── /etc/nginx/sites-available/ ← 存放所有站点配置文件(未激活)
└── /etc/nginx/sites-enabled/ ← 存放已激活站点的符号链接(指向 sites-available)
关键点在于
/etc/nginx/nginx.conf
开头的
include
指令:
http {
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
这意味着:
-
如果你在
/etc/nginx/conf.d/下新建一个custom.conf,它会被自动加载; -
/etc/nginx/sites-enabled/下的文件必须是符号链接,不能是普通文件。sudo ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp是标准做法; -
sites-available和sites-enabled的分离,是为了方便多站点管理。停用一个站点,只需sudo rm /etc/nginx/sites-enabled/myapp,无需删除配置文件。
提示:
nginx配置文件详解这个热词,核心就是理解nginx.conf的层级关系。http块下的指令对所有server生效;server块下的指令只对该虚拟主机生效;location块下的指令只对该路径生效。location /api { proxy_pass http://backend; }和location / { root /var/www/html; }是完全独立的,前者不会影响后者。
3.3 第三步:编写第一个可验证的
server
块(告别 Welcome 页面)
删掉
/etc/nginx/sites-enabled/default
(或重命名为
default.bak
),新建
/etc/nginx/sites-available/hello
:
server {
listen 80;
server_name _; # 匹配任意域名,适合测试
root /var/www/hello;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 添加一个健康检查端点
location /healthz {
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
然后创建符号链接并测试:
sudo mkdir -p /var/www/hello
echo "<h1>Hello from Ubuntu 20.04 + Nginx</h1>" | sudo tee /var/www/hello/index.html
sudo ln -sf /etc/nginx/sites-available/hello /etc/nginx/sites-enabled/hello
sudo nginx -t # 必须通过!这是语法检查的黄金标准
sudo systemctl reload nginx # 优雅重载,不中断现有连接
验证:
curl -I http://localhost # 应返回 200 OK
curl http://localhost/healthz # 应返回 "OK"
curl -I http://localhost/nonexistent # 应返回 404 Not Found
这一步的价值在于:你亲手构建了一个最小、可验证、可调试的 Nginx 服务实例。它不依赖任何外部服务,所有行为都由你定义,是后续所有复杂配置(反向代理、HTTPS、负载均衡)的绝对基石。
3.4 第四步:防火墙(ufw)的精准放行(
ufw allow
的底层逻辑)
sudo ufw allow 'Nginx Full'
是快捷方式,但它的底层逻辑是:
-
读取
/etc/ufw/applications.d/nginx文件; -
该文件定义了两个端口组:
80/tcp和443/tcp; -
ufw将其转换为 iptables 规则,插入到INPUT链中。
但生产环境往往需要更精细的控制。例如,你只想允许特定 IP 访问管理后台:
sudo ufw allow from 192.168.1.100 to any port 8080
或者,你想禁止所有对 22 端口(SSH)的公网访问,只允许内网:
sudo ufw deny 22
sudo ufw allow from 10.0.0.0/8 to any port 22
验证 ufw 规则是否生效:
sudo ufw status numbered # 显示带编号的规则列表
sudo ufw status verbose # 显示详细状态,包括默认策略
注意:
ufw规则的 顺序很重要 。ufw按照规则编号从上到下匹配,第一个匹配的规则生效。所以deny规则要放在allow规则之后,否则会被提前拦截。
3.5 第五步:日志与监控的“第一道防线”
Nginx 默认日志在
/var/log/nginx/
:
-
access.log:记录每一次 HTTP 请求(IP、时间、URL、状态码、响应大小); -
error.log:记录 Nginx 自身错误(配置错误、权限问题、上游连接失败)。
但默认的
access.log
格式太简陋。编辑
/etc/nginx/nginx.conf
,在
http
块中添加:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
然后在
server
块中指定:
access_log /var/log/nginx/access.log main;
$request_time
是客户端请求总耗时(单位秒),
$upstream_response_time
是 Nginx 转发给后端并收到响应的时间(对反向代理至关重要)。当你看到
access.log
里某行
request_time=0.001
但
upstream_response_time=5.234
,就知道瓶颈在后端,而不是 Nginx 本身。
实时监控日志:
# 实时跟踪错误日志
sudo tail -f /var/log/nginx/error.log
# 实时统计每秒请求数(QPS)
sudo awk '{print $4}' /var/log/nginx/access.log | cut -d: -f2 | sort | uniq -c | sort -nr | head -10
# 查找 502 错误(上游连接失败)
sudo grep " 502 " /var/log/nginx/access.log
4. 常见故障的“七步排查法”:从
502 Bad Gateway
到
Connection refused
当你的 Nginx 服务不再返回 “Welcome”,而是抛出各种 HTTP 状态码或
curl
直接超时,你需要一套标准化的排查流程。这不是靠运气,而是按顺序排除可能性。
4.1 第一步:确认 Nginx 进程与端口监听状态
# 检查进程是否存在且运行正常
ps aux | grep nginx | grep -v grep
# 检查 80/443 端口是否被监听(注意 -t 表示 TCP,-n 表示数字端口,-p 表示显示进程)
sudo ss -tlnp | grep ':80\|:443'
# 如果没看到 nginx,说明服务没起来;如果看到的是其他进程(如 apache2),说明端口被占用了
常见陷阱:
sudo netstat -tulpn | grep :80
在 Ubuntu 20.04 上可能因
net-tools
未安装而失败,
ss
是更现代、更轻量的替代品。
4.2 第二步:语法检查与配置加载验证
# 严格检查语法(-t),并显示使用的配置文件路径(-T)
sudo nginx -t -T
# 如果报错,错误信息会精确到第几行第几列,例如:
# nginx: [emerg] unknown directive "proxy_set_header" in /etc/nginx/sites-available/myapp:12
# 这说明你在第 12 行写错了指令名,应该是 `proxy_set_header`,而不是 `proxy_header_set`。
提示:
nginx -t是最廉价、最高效的“编译期”检查。养成习惯:每次修改配置文件后,必先nginx -t,再systemctl reload。
4.3 第三步:服务状态与日志深挖(
journalctl
的高级用法)
# 查看 Nginx 服务的全部日志(从启动到现在)
sudo journalctl -u nginx --no-pager
# 查看最近 50 行,并实时跟踪(-f)
sudo journalctl -u nginx -n 50 -f
# 查看上次启动的日志(非常有用,避免滚动日志干扰)
sudo journalctl -u nginx -b
# 按优先级过滤(只看错误和警告)
sudo journalctl -u nginx -p err..warning
journalctl
的
-b
参数(boot)是关键。当你
systemctl restart nginx
后,
-b
会只显示本次启动以来的日志,极大提升排查效率。
4.4 第四步:网络连通性与防火墙穿透测试
假设你配置了反向代理到
http://127.0.0.1:8000
,但浏览器访问 Nginx 返回 502:
# 1. 先确认后端服务是否真的在运行
curl -I http://127.0.0.1:8000
# 2. 如果返回 502,检查后端服务是否监听在 127.0.0.1(而非 localhost 或 0.0.0.0)
sudo ss -tlnp | grep ':8000'
# 3. 检查 ufw 是否拦住了本地回环(loopback)流量?一般不会,但需确认
sudo ufw status verbose | grep -A 5 "Default"
# 4. 用 telnet 测试端口连通性(比 curl 更底层)
telnet 127.0.0.1 8000
# 如果连接失败,说明后端没起来或监听地址不对;如果连接成功,说明网络层通畅。
4.5 第五步:Nginx 内部代理链路诊断(
proxy_pass
的灵魂)
502 Bad Gateway
的根源,90% 在于
proxy_pass
配置。一个经典错误是:
location /api {
proxy_pass http://127.0.0.1:8000/api; # 错误!末尾的 /api 会导致路径重复
}
当用户请求
/api/users
,Nginx 会转发到
http://127.0.0.1:8000/api/api/users
,后端自然 404。
正确写法是:
location /api {
proxy_pass http://127.0.0.1:8000/; # 末尾必须有 /
}
这样
/api/users
会被转发到
http://127.0.0.1:8000/users
。
另一个关键是
proxy_set_header
:
location /api {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
-
Host $host:确保后端收到的 Host 头和浏览器请求一致; -
X-Real-IP和X-Forwarded-For:传递真实客户端 IP,后端可通过request.headers.get('X-Real-IP')获取; -
X-Forwarded-Proto:告诉后端当前是 HTTP 还是 HTTPS,避免后端生成http://链接。
4.6 第六步:文件权限与 SELinux/AppArmor(Ubuntu 的真相)
Ubuntu 20.04 用的是 AppArmor,不是 SELinux。如果你看到
nginx: [emerg] open() "/var/www/myapp/index.html" failed (13: Permission denied)
,原因很可能是:
-
Nginx 工作进程用户是
www-data,而/var/www/myapp目录的所有者是ubuntu用户,且权限是750,www-data组没有读取权限; -
解决方案:
sudo chown -R www-data:www-data /var/www/myapp或sudo chmod -R 755 /var/www/myapp。
AppArmor 的日志在
/var/log/audit/audit.log
,但 Ubuntu 默认不安装
auditd
。更简单的方法是临时禁用 AppArmor 策略来验证:
sudo aa-disable /etc/apparmor.d/usr.sbin.nginx
sudo systemctl restart nginx
如果问题消失,说明是 AppArmor 策略限制,需编辑
/etc/apparmor.d/usr.sbin.nginx
添加对应路径权限。
4.7 第七步:终极武器——
strace
动态追踪
当所有常规手段失效,
strace
是最后的真相探测器。它能告诉你 Nginx 进程在内核层面到底在做什么:
# 找到主进程 PID
sudo ps aux | grep nginx | grep master
# 对主进程进行系统调用追踪(-p PID,-e trace=open,connect,sendto,recvfrom)
sudo strace -p 12345 -e trace=open,connect,sendto,recvfrom -s 100 -o /tmp/nginx.strace.log
然后在另一个终端触发一次请求(
curl http://localhost
),再
cat /tmp/nginx.strace.log
。你会看到 Nginx 尝试
open()
哪些配置文件、
connect()
哪个上游地址、
sendto()
什么数据。这是定位
Connection refused
类错误的终极手段。
5. 进阶实战:从静态服务到生产就绪的四大跃迁
装好 Nginx 只是起点。要让它真正扛起生产流量,还需完成四次关键跃迁。这些不是“可选项”,而是现代 Web 服务的标配。
5.1 跃迁一:HTTPS 全站加密(Let's Encrypt + Certbot)
Ubuntu 20.04 官方源自带
certbot
:
sudo apt install certbot python3-certbot-nginx
为域名
example.com
申请证书:
sudo certbot --nginx -d example.com -d www.example.com
Certbot 会自动:
-
修改
/etc/nginx/sites-available/example.com,添加listen 443 ssl和证书路径; -
添加
listen 80的return 301 https://$host$request_uri;强制跳转; -
配置自动续期的 systemd timer(
certbot.timer)。
关键细节:
-
证书存放在
/etc/letsencrypt/live/example.com/; -
fullchain.pem是证书链(供 Nginx 的ssl_certificate使用); -
privkey.pem是私钥(供ssl_certificate_key使用); -
Certbot 的续期命令是
sudo certbot renew --dry-run(测试)和sudo certbot renew(真实执行)。
注意:
nginx反向代理和 HTTPS 结合时,proxy_pass后端如果是 HTTP,Nginx 作为 TLS 终结点,后端无需 HTTPS;但如果后端也要求 HTTPS(如内部微服务),则需在proxy_pass中写https://backend:443,并配置proxy_ssl_trusted_certificate。
5.2 跃迁二:反向代理与负载均衡(
upstream
模块实战)
定义一个上游集群:
upstream backend_cluster {
server 127.0.0.1:8000 weight=3 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8001 weight=1 max_fails=3 fail_timeout=30s;
keepalive 32;
}
server {
listen 80;
location /api {
proxy_pass http://backend_cluster;
proxy_http_version 1.1;
proxy_set_header Connection '';
# 其他 proxy_set_header...
}
}
-
weight:权重轮询,8000接收 3/4 流量; -
max_fails/fail_timeout:连续 3 次失败后,30 秒内不将请求发给该节点; -
keepalive 32:为每个 worker 进程维护最多 32 个到上游的空闲长连接,大幅提升性能。
验证负载均衡效果:
# 在两个后端服务中,分别返回不同的标识
# curl http://localhost/api -> "Backend A"
# curl http://localhost/api -> "Backend B"
# 多次请求,观察响应是否按权重比例切换
5.3 跃迁三:静态资源优化与缓存策略(
gzip
与
expires
)
在
http
块中添加:
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 静态资源强缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
-
gzip_types列出了所有会被压缩的 MIME 类型,务必包含application/javascript(而非过时的application/x-javascript); -
expires 1y设置一年过期时间,配合Cache-Control: public, immutable,让浏览器彻底离线缓存,极大减少请求数; -
immutable是关键,它告诉浏览器:这个资源的 URL 永远不会变,因此无需发送If-None-Match请求验证。
5.4 跃迁四:安全加固与漏洞防护(针对 CVE-2025-23419 等)
虽然
f5 nginx plus
的漏洞(如
CVE-2025-23419
)不直接影响开源版,但开源 Nginx 也有自己的风险点:
-
禁用危险模块 :在
nginx.conf的http块中,添加:# 禁用 WebDAV(CVE-2026-27654 高危漏洞相关) location / { dav_methods off; create_full_put_path off; } -
限制请求体大小与频率 :
client_max_body_size 10M; # 防止大文件上传耗尽内存 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; # 每秒最多 10 次请求 location /api { limit_req zone=api burst=20 nodelay; } -
隐藏 Nginx 版本号 :
server_tokens off; # 在 http 或 server 块中这会让响应头中的
Server: nginx/1.18.0变成Server: nginx,增加攻击者利用已知漏洞的难度。
提示:
nginx升级到1.30.2要注意什么这个热词,核心是:新版 Nginx 移除了mp4模块,flv模块行为变更,http_v2模块默认启用但需ssl,以及resolver指令语法变化。升级前务必阅读官方CHANGES文件,并在测试环境充分验证。
6. 个人经验总结:那些文档里不会写的“血泪教训”
最后,分享几个我在 Ubuntu 20.04 上部署 Nginx 时,踩过、修过、记下来的“非技术性”但极其重要的经验。
6.1 关于
sudo systemctl edit
的编辑器选择
sudo systemctl edit nginx
默认调用
nano
,但很多资深用户习惯用
vim
。想改成
vim
,只需:
sudo update-alternatives --config editor
# 然后选择 vim.basic
或者临时指定:
sudo EDITOR=vim systemctl edit nginx
但切记:
systemctl edit
创建的
override.conf
文件,其语法是 systemd 的 unit file 语法,不是 Nginx 配置语法。写错格式(比如漏了
[Service]
头)会导致
systemctl daemon-reload
失败,进而
systemctl start nginx
报错。所以,永远先
sudo systemctl cat nginx
看看 override 是否被正确加载。
6.2
nginx.conf
的
include
顺序是“法律”
include /etc/nginx/conf.d/*.conf;
和
include /etc/nginx/sites-enabled/*;
的顺序决定了配置的加载优先级。
conf.d
中的
gzip.conf
会先于
sites-enabled
中的
myapp.conf
加载,因此
gzip
指令对
myapp
生效。但如果你在
myapp.conf
中又写了
gzip off;
,它就会覆盖
conf.d
中的设置。这种“后加载覆盖先加载”的
1万+

被折叠的 条评论
为什么被折叠?



