当前位置: 首页 > news >正文

Ubuntu 20.04 Nginx生产部署:ufw、systemctl与nginx.conf协同配置指南

1. 项目概述:为什么在 Ubuntu 20.04 上装 Nginx 不是“点几下就完事”的事

Nginx 是我过去十年里部署频率最高的服务之一——从给客户搭静态官网、反向代理后端 API,到给嵌入式设备做轻量级 Web 控制台,再到给边缘计算节点做 TLS 终结和请求路由,它几乎是我工具箱里最常被掏出的那把瑞士军刀。但很多人第一次在 Ubuntu 20.04 上敲sudo apt install nginx的时候,以为这就完成了;结果打开浏览器看到 “Welcome to nginx!” 页面,就关掉终端去写周报了。这就像买了辆保时捷却只让它在停车场原地怠速——你没动过油门,也没调过悬挂,更不知道它的差速锁在哪。

Ubuntu 20.04 是一个长期支持(LTS)版本,内核稳定、软件源成熟,但它默认安装的 Nginx 版本是1.18.0(截至 2024 年底仍为官方仓库主版本),这个版本发布于 2020 年 4 月,距今已超四年。它不支持 HTTP/3(QUIC)、不内置对 OpenSSL 3.0 的完整兼容、缺少proxy_http_version 1.1在某些 upstream 场景下的自动降级逻辑优化,更重要的是——它没有集成ngx_http_geoip2_module这类现代地理围栏必需的模块。而这些,恰恰是真实业务中绕不开的硬需求:比如你要做灰度发布,靠 IP 段区分用户群;比如你要防爬虫,得根据 ASN 判定请求来源是否异常;比如你要给海外用户提供低延迟访问,必须启用 HTTP/3 + Brotli 压缩组合。

更关键的是,Ubuntu 20.04 默认启用了ufw(Uncomplicated Firewall),但它对 Nginx 的规则管理极其“不智能”:sudo ufw allow 'Nginx Full'看似省事,实则会同时放行 80 和 443 端口,哪怕你当前只跑 HTTP 服务;而一旦你后续配置了 HTTPS,又忘了删掉 80 端口的规则,就等于主动暴露了一个未加密的入口,给中间人攻击留了活口。这不是理论风险——我在三个不同客户的生产环境里都复现过这类配置漂移导致的证书链校验失败问题,根源全在 ufw 规则与 Nginx 实际监听状态不同步。

还有systemctl——它不是chkconfig的翻版,也不是 Windows 服务管理器的 Linux 马甲。sudo systemctl edit nginx这个命令,表面看只是编辑服务单元,实则牵扯到覆盖片段(drop-in)机制、依赖图重载、启动顺序仲裁等一整套 systemd 内部逻辑。我见过太多人用nano直接改/lib/systemd/system/nginx.service,结果系统升级后被包管理器覆盖,服务突然无法 reload;也有人在ExecStartPre里写了sleep 2试图“等网络就绪”,却不知 systemd 有After=network-online.target这种语义化依赖,根本不需要手写延时。

至于nginx.conf,它从来就不是一份“拿来即用”的模板。Ubuntu 官方包自带的原始配置文件(位于/etc/nginx/nginx.conf)只有 62 行,其中 37 行是注释,真正生效的指令不到 25 条。它连最基本的client_max_body_size 100M;都没设,意味着你上传一个 10MB 的图片就会直接返回 413;它默认关闭gzip_vary on;,导致 CDN 缓存时无法区分压缩/未压缩版本;它把include /etc/nginx/sites-enabled/*;放在 http 块末尾,看似合理,实则一旦你在 sites-enabled 里写了server { listen 80; }却忘了加default_server,Nginx 就会把所有未匹配域名的请求全部打给第一个加载的 server 块——而这个“第一个”取决于文件系统排序,不是你写的顺序。

所以,这篇内容不是教你怎么“安装 Nginx”,而是带你亲手拆开 Ubuntu 20.04 这台车的引擎盖,看清 Nginx、ufw、systemctl、nginx.conf 四者之间真实的咬合关系。你会知道:什么时候该用apt而不是源码编译;为什么ufw allow 443ufw allow 'Nginx Full'更安全;systemctl daemon-reloadsystemctl restart nginx的执行顺序为什么不能颠倒;以及如何从原始nginx.conf出发,一行一行补全生产环境必需的 17 项核心参数。这不是教程,是我在 237 次 Nginx 部署中踩出来的路径标记。

2. 核心设计思路:为什么选择 APT 安装而非源码编译?四个不可妥协的前提

在 Ubuntu 20.04 上部署 Nginx,第一步永远不是敲命令,而是回答一个问题:这次部署的核心约束是什么?我把过去所有项目归为四类典型场景,每种场景对应一套完全不同的技术选型逻辑:

2.1 场景一:内部管理系统(Intranet Admin Panel)

典型特征:服务只对局域网开放,无公网 IP,不涉及 HTTPS,前端是 Vue/React 打包后的静态资源,后端是 Python Flask 或 Node.js 提供的 REST API。这种场景下,我坚持用apt install nginx,理由非常具体:

  • Ubuntu 官方仓库的 Nginx 1.18.0 已通过 Canonical 的 LTS 安全审计,所有 CVE 补丁(如 CVE-2021-23017、CVE-2022-41741)都会随sudo apt upgrade自动推送,无需人工干预;
  • apt安装的二进制文件路径、日志位置、配置目录全部遵循 FHS(Filesystem Hierarchy Standard)标准,/var/log/nginx//etc/nginx/sites-available/这些路径被 Ansible、SaltStack 等自动化工具深度适配,改用源码安装会导致整个运维流水线断裂;
  • 最关键的是:apt安装的 Nginx 启动脚本(/usr/sbin/nginx)内置了-t参数的自动语法检查逻辑,每次systemctl reload nginx前都会强制执行nginx -t,而源码编译的二进制默认不带此行为,必须手动在 systemd unit 里加ExecReload=/usr/local/nginx/sbin/nginx -s reload+ExecStartPre=/usr/local/nginx/sbin/nginx -t,稍有疏忽就可能 reload 一个语法错误的配置,导致服务中断。

提示:如果你的内部系统需要 WebSocket 支持(比如用 Nginx 反向代理 Socket.IO),请务必在location /socket.io/块中添加三行:

proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

这不是可选项——这是 WebSocket 协议握手的强制要求。漏掉任何一行,客户端连接都会卡在pending状态。

2.2 场景二:对外提供 HTTPS 的 SaaS 服务(Public SaaS)

典型特征:有独立域名,需 Let's Encrypt 免费证书,要支持 HTTP/2、OCSP Stapling、HSTS,且未来可能接入 WAF 或 CDN。这种场景下,我依然用apt,但会额外启用 Nginx 官方提供的mainline 仓库(非 stable)。原因很现实:

  • Ubuntu 20.04 的nginx-full包虽然包含大多数模块(http_ssl_module,http_gzip_module,http_realip_module),但它不包含http_v2_module的完整实现——准确地说,它支持 HTTP/2,但不支持 ALPN 协商中的h2字符串优先级控制,这会导致某些旧版 Android WebView 无法建立 HTTP/2 连接;
  • mainline 仓库(http://nginx.org/packages/mainline/ubuntu/)提供的 Nginx 1.25.x 版本,不仅完整支持 ALPN,还修复了ssl_buffer_size在高并发下内存泄漏的问题(CVE-2023-37021),而这个问题在 1.18.0 中依然存在;
  • mainline 仓库的.deb包与 Ubuntu 系统深度集成:dpkg -i安装后,systemctl管理方式完全不变,ufw规则语法也不变,唯一变化的是/usr/sbin/nginx -v输出的版本号——这意味着你无需修改任何 CI/CD 脚本、监控告警规则或文档,就能获得新特性。

操作上,只需三步:

# 1. 导入 Nginx 官方 GPG 密钥 curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg # 2. 添加 mainline 仓库(注意:focal 对应 Ubuntu 20.04) echo "deb [arch=amd64 signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu/ focal nginx" | sudo tee /etc/apt/sources.list.d/nginx.list # 3. 更新并安装(会自动卸载旧版) sudo apt update && sudo apt install nginx

注意:不要执行sudo apt dist-upgrade,因为 mainline 仓库的nginx包版本号(如 1.25.3)高于 Ubuntu 官方仓库(1.18.0),dist-upgrade可能触发不必要的内核或库升级,破坏系统稳定性。只用apt install nginx即可精准替换。

2.3 场景三:需要定制模块的嵌入式设备(Embedded Device)

典型特征:ARM64 架构的工控机、树莓派集群、Jetson Nano 边缘节点,内存 ≤2GB,存储 ≤16GB,要求最小化体积、禁用所有非必要模块(如http_perl_module,http_xslt_module),且必须静态链接 OpenSSL 以避免运行时依赖冲突。这种场景下,必须源码编译,但绝不是网上那些“下载 tar.gz → ./configure → make → make install”的粗暴流程。

我的编译策略基于三个硬性原则:

  1. 交叉编译而非本地编译:在 x86_64 开发机上用aarch64-linux-gnu-gcc编译,生成 ARM64 二进制,避免在资源受限设备上耗尽 swap 空间;
  2. 模块按需启用:只启用--with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-file-aio --with-threads这五个模块,禁用所有 Perl/XSLT/GeoIP 相关模块(它们会引入额外的动态库依赖);
  3. OpenSSL 静态链接:下载 OpenSSL 3.0.12 源码,./config no-shared --prefix=/opt/openssl编译安装,然后在 Nginx configure 中指定--with-openssl=/path/to/openssl/src --with-openssl-opt="no-shared"

最终生成的 Nginx 二进制大小可控制在 1.2MB 以内(对比apt版本的 3.8MB),内存占用峰值降低 40%,且彻底摆脱对系统 OpenSSL 库的依赖——这对需要长期离线运行的工业设备至关重要。

2.4 场景四:合规审计驱动的金融系统(Compliance-Audited Finance System)

典型特征:受 PCI DSS、等保三级等规范约束,要求所有组件版本可追溯、配置项可审计、日志留存 ≥180 天、TLS 加密套件必须满足TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256强制要求。这种场景下,我采用APT + 配置即代码(Configuration as Code)混合模式:

  • apt安装 Nginx,确保基础二进制来自可信源;
  • 所有配置文件(nginx.conf,sites-enabled/*.conf)全部由 Git 仓库托管,每次变更必须经 PR Review + 自动化测试(用nginx -t+curl -I http://localhost检查健康端点);
  • 关键安全参数(如ssl_ciphers,ssl_prefer_server_ciphers,add_header Strict-Transport-Security)全部写死在配置中,禁用任何运行时环境变量注入;
  • 日志路径统一指向/var/log/nginx/audit/,并通过logrotate配置每日切割、压缩、保留 180 天,且logrotate配置本身也纳入 Git 管理。

这套方案的价值在于:当审计员要求提供“Nginx 配置变更记录”时,你直接给他一个 Git commit history 链接;当他问“如何证明 TLS 配置符合 PCI DSS 要求”,你打开nginx.conf文件,第 87 行就是ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256';,旁边还有一行注释# PCI DSS 4.1 compliant cipher suite, validated 2024-03-15

这四种场景没有优劣之分,只有适用与否。你的项目属于哪一类?答案决定了你接下来敲的每一个命令。

3. 核心细节解析:ufw、systemctl、nginx.conf 三者的协同陷阱与避坑指南

在 Ubuntu 20.04 上,Nginx 不是孤立运行的。它像一台精密仪器,ufw是它的物理防护罩,systemctl是它的中央控制器,nginx.conf是它的神经中枢。三者任何一个环节出错,整台机器就会失灵。我整理了过去三年中高频出现的 12 类协同故障,按发生概率排序,并给出根因分析和实操解法。

3.1 ufw 规则与 Nginx 监听状态不同步:最隐蔽的“服务正常但无法访问”问题

现象:sudo systemctl status nginx显示 active (running),sudo ss -tlnp | grep :443确认 Nginx 正在监听 443 端口,但外部 curl 返回Connection refusedtimeout

根因分析:ufw的规则是静态的,而 Nginx 的监听端口是动态的。当你执行sudo ufw allow 'Nginx Full',ufw 会创建两条规则:

200 ALLOW Anywhere 80 200 ALLOW Anywhere 443

但如果 Nginx 配置中listen 443 ssl;被注释掉,或者ssl_certificate路径错误导致 Nginx 启动时跳过 443 监听,ufw 规则依然存在——防火墙开着,但服务没在监听,结果就是“端口开着,服务没在”。

实操解法:永远用端口粒度而非服务名粒度管理 ufw 规则。执行:

# 先删除所有 Nginx 相关规则 sudo ufw delete allow 'Nginx Full' sudo ufw delete allow 'Nginx HTTP' sudo ufw delete allow 'Nginx HTTPS' # 再根据 Nginx 实际监听端口添加 sudo ss -tlnp | grep nginx | awk '{print $5}' | cut -d':' -f2 | sort -u | while read port; do sudo ufw allow $port done

这段脚本会实时读取 Nginx 进程监听的所有端口(包括 8080、8443 等自定义端口),并为每个端口添加精确规则。它比ufw allow 443多了一步动态发现,但比ufw allow 'Nginx Full'少了 90% 的误放行风险。

提示:如果你的 Nginx 配置了多个 SSL 证书(SNI),且监听同一个 443 端口,ufw 规则依然只需allow 443——因为 SNI 是应用层协议,防火墙只管传输层端口。

3.2 systemctl reload 与 nginx -s reload 的本质区别:一次 reload 失败引发的雪崩

现象:修改sites-enabled/myapp.conf后执行sudo systemctl reload nginx,命令无报错,但新配置未生效;进一步执行sudo nginx -s reload报错nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)

根因分析:systemctl reload nginx实际执行的是systemctl kill --signal=SIGUSR2 nginx,它会触发 Nginx 的“优雅重启”流程:主进程 fork 新工作进程,新进程加载新配置并尝试绑定端口,成功后通知旧进程退出。但如果新配置中listen 443 ssl;ssl_certificate路径错误(比如证书文件被chmod 600锁定,而 Nginx worker 进程以www-data用户运行),新进程无法读取证书,绑定失败,但主进程不会退出,导致新旧进程共存,端口被双占。

nginx -s reload是直接向主进程发送SIGUSR2,行为一致,但systemctl版本会在 reload 前自动执行nginx -t语法检查,nginx -s reload不会——这就是为什么后者报错更早。

实操解法:永远遵循三步 reload 法则

  1. sudo nginx -t:强制语法检查,确认配置无误;
  2. sudo systemctl reload nginx:触发优雅重启;
  3. sudo systemctl status nginx:检查输出中是否有Reloading nginx configuration成功日志,以及Active: active (running)状态。

如果第 1 步失败,立刻sudo journalctl -u nginx --since "1 hour ago" | grep -i error查看详细错误;如果第 2 步失败,执行sudo nginx -V 2>&1 | grep -o 'configure arguments.*'查看编译参数,确认--with-http_ssl_module是否启用。

3.3 nginx.conf 原始配置的致命缺陷:从 62 行到生产就绪的 17 项必改参数

Ubuntu 20.04 的原始/etc/nginx/nginx.conf是一个精简到极致的骨架,但它漏掉了生产环境必需的 17 个关键参数。我按重要性排序,逐条说明修改理由和实操值:

参数原始值推荐值修改理由实操验证方法
worker_processesauto2(双核 CPU)或4(四核)auto在容器或虚拟机中可能识别为 1 个 CPU,导致并发能力不足;固定值便于压测建模ab -n 1000 -c 200 http://localhost/对比 QPS
worker_connections7684096默认值仅支持约 1500 并发连接(768×2),现代 Web 应用轻松突破此限`ss -s
keepalive_timeout6530过长的 keepalive 会占用 worker 进程,导致新连接排队;30 秒足够浏览器复用连接curl -I http://localhost/查看Connection: keep-aliveKeep-Alive: timeout=30
client_max_body_size未设置100M未设置时默认为 1MB,上传大文件直接 413curl -F "file=@large.zip" http://localhost/upload
client_header_timeout6010防止慢速 HTTP 头攻击(Slowloris),10 秒足够正常客户端发送完整头timeout 5s curl -v http://localhost/模拟超时
client_body_timeout6012同上,针对请求体传输超时同上
send_timeout6010防止响应发送卡住,10 秒足够传输 10MB 以内响应`dd if=/dev/zero bs=1M count=50
gzipoffon启用 Gzip 压缩,减少带宽消耗curl -H "Accept-Encoding: gzip" -I http://localhost/查看Content-Encoding: gzip
gzip_varyoffon告诉 CDN 和代理缓存压缩/未压缩版本,避免缓存污染同上,检查Vary: Accept-Encoding
gzip_typestext/plain text/css application/jsontext/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript补全常见 MIME 类型,避免 JS/CSS 未压缩同上,检查不同后缀文件的Content-Encoding
ssl_protocolsTLSv1.2 TLSv1.3TLSv1.2 TLSv1.3(显式写出)防止未来 Nginx 版本默认启用 TLSv1.1openssl s_client -connect localhost:443 -tls1_1应失败
ssl_ciphersHIGH:!aNULL:!MD5:!RC4:!kRSATLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384强制使用前向保密(PFS)和 AEAD 加密套件nmap --script ssl-enum-ciphers -p 443 localhost
ssl_prefer_server_ciphersoffon确保服务器选择最强 cipher,而非客户端推荐同上
ssl_session_cacheshared:SSL:10mshared:SSL:50m10m 仅支持约 4000 个会话,50m 支持 20000+openssl s_client -connect localhost:443 -reconnect查看Session-ID:是否复用
ssl_session_timeout5m4h延长会话复用时间,减少 TLS 握手开销同上,观察多次 reconnect 的Session-ID是否相同
add_header X-Frame-Options未设置DENY防止点击劫持(Clickjacking)curl -I http://localhost/查看响应头
add_header X-Content-Type-Options未设置nosniff防止 MIME 类型嗅探攻击同上

修改方法:在/etc/nginx/nginx.confhttp { }块内,所有参数必须放在include /etc/nginx/sites-enabled/*;之前,否则会被子配置覆盖。例如:

http { # ... 其他参数 add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/sites-enabled/*; # 必须放在这里 }

注意:add_header指令在location块中会覆盖serverhttp块中的同名指令,而不是追加。所以全局安全头必须在httpserver级别设置,不能放在location /api/里。

3.4 systemctl edit 的正确姿势:为什么 90% 的人用错了这个命令

sudo systemctl edit nginx是修改 Nginx 服务行为的高级功能,但它不是让你直接改/lib/systemd/system/nginx.service。它的底层机制是创建drop-in 片段(drop-in snippet),即在/etc/systemd/system/nginx.service.d/override.conf中写覆盖配置。

常见错误:

  • 错误1:执行sudo systemctl edit nginx后,在 nano 里直接写ExecStart=/usr/sbin/nginx -g "daemon off;"——这会覆盖整个ExecStart,导致systemctl start nginx失败,因为原始ExecStart包含-c /etc/nginx/nginx.conf参数,你删掉了;
  • 错误2:在override.conf中写[Service]两次,导致语法错误;
  • 错误3:修改后忘记执行sudo systemctl daemon-reload,导致修改不生效。

正确做法(以添加启动前健康检查为例):

# 1. 创建 drop-in 片段 sudo systemctl edit nginx # 2. 在打开的编辑器中输入(注意:只能有一个 [Service] 块) [Service] ExecStartPre=/bin/sh -c 'while ! curl -f http://localhost/healthz 2>/dev/null; do sleep 1; done' # 3. 保存退出后,必须重载 systemd 配置 sudo systemctl daemon-reload # 4. 验证是否生效 sudo systemctl cat nginx | grep -A5 "ExecStartPre"

这个ExecStartPre的作用是:在 Nginx 主进程启动前,循环检查http://localhost/healthz端点(通常由后端服务提供),直到返回 HTTP 200 才继续。它比After=network-online.target更精准,因为网络通了不代表后端服务已就绪。

提示:systemctl edit默认使用的编辑器是nano,如果你想改成vim,执行export EDITOR=vim再运行命令即可。但切记:sudo会重置环境变量,所以必须sudo EDITOR=vim systemctl edit nginx

4. 实操全流程:从零开始部署一个 HTTPS 前端项目(含 Let's Encrypt 自动续期)

现在,我们把前面所有知识点串起来,完成一个真实场景:将一个 Vue CLI 打包的前端项目(dist/目录)部署到 Ubuntu 20.04,通过 Nginx 提供 HTTPS 访问,并自动申请和续期 Let's Encrypt 证书。整个过程不依赖 Docker,纯原生系统配置。

4.1 环境准备与基础安装

首先确认系统状态:

# 检查 Ubuntu 版本 lsb_release -a | grep "Release\|Codename" # 检查内核和架构(确保是 amd64 或 aarch64) uname -m # 更新系统(关键:修复已知安全漏洞) sudo apt update && sudo apt full-upgrade -y # 安装基础工具(ufw、curl、wget、unzip 必备) sudo apt install -y ufw curl wget unzip gnupg2 ca-certificates

安装 Nginx(采用 mainline 仓库,获取最新特性):

# 导入 Nginx 官方密钥 curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg # 添加 mainline 仓库 echo "deb [arch=amd64 signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu/ focal nginx" | sudo tee /etc/apt/sources.list.d/nginx.list # 安装(会自动卸载旧版) sudo apt update && sudo apt install -y nginx # 验证版本 sudo nginx -v # 应输出 nginx version: nginx/1.25.3 # 启动并设为开机自启 sudo systemctl enable nginx && sudo systemctl start nginx

4.2 配置 ufw 防火墙:最小权限原则

# 重置 ufw(清除所有规则) sudo ufw reset # 设置默认策略:拒绝所有入站,允许所有出站 sudo ufw default deny incoming sudo ufw default allow outgoing # 只放行必要端口:SSH(22)、HTTPS(443)、HTTP(80,用于 Let's Encrypt 验证) sudo ufw allow 22 sudo ufw allow 443 sudo ufw allow 80 # 启用 ufw(注意:启用后 SSH 连接不会断,因为 22 端口已放行) sudo ufw --force enable # 查看规则 sudo ufw status verbose

提示:ufw allow 80是临时的,Let's Encrypt 验证完成后可以sudo ufw delete allow 80,但建议保留,因为很多监控探针(如 Prometheus blackbox exporter)会通过 HTTP 80 端口探测服务健康状态。

4.3 部署前端静态文件

假设你的前端项目打包后生成dist/目录,将其上传到服务器/var/www/myapp/

# 创建网站根目录 sudo mkdir -p /var/www/myapp # 上传 dist 目录(示例:用 scp) # scp -r ./dist/* user@your-server:/var/www/myapp/ # 设置正确权限(Nginx 以 www-data 用户运行) sudo chown -R www-data:www-data /var/www/myapp sudo chmod -R 755 /var/www/myapp # 验证文件可读 sudo -u www-data ls -la /var/www/myapp/

4.4 配置 Nginx Server Block:HTTPS + HTTP/2 + 安全头

创建/etc/nginx/sites-available/myapp

# /etc/nginx/sites-available/myapp server { listen 80; server_name myapp.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name myapp.example.com; # SSL 证书(Let's Encrypt 自动生成) ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem; # SSL 优化(来自前文 3.3 节) ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:50m; ssl_session_timeout 4h; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; # 安全头(来自前文 3.3 节) add_header X-Frame-Options DENY always; add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Download-Options noopen always; add_header X-Permitted-Cross-Domain-Policies none always; add_header Referrer-Policy no-referrer-when-downgrade always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none'; base-uri 'self'; form-action 'self';" always; # 前端路由(Vue Router history 模式) root /var/www/myapp; index index.html; location / { try_files $uri $uri/ /index.html; } # API 反向代理(如果后端在 http://localhost:3000) # location /api/ { # proxy_pass http://localhost:3000/; # proxy_http_version 1.1; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection "upgrade"; # 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; # } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # 健康检查端点 location /healthz { return 200 "OK"; add_header Content-Type text/plain; } }

启用配置:

# 创建符号链接 sudo ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp # 测试配置语法 sudo nginx -t # 重新加载 Nginx sudo systemctl reload nginx

4.5 申请 Let's Encrypt 证书:Certbot + Nginx 插件

安装 Certbot:

sudo apt install -y certbot python3-certbot-nginx # 申请证书(自动修改 Nginx 配置,添加 443 监听和证书路径) sudo certbot --nginx -d myapp.example.com --non-interactive --
http://www.gsyq.cn/news/1567205.html

相关文章:

  • 2026江诗丹顿官方售后网点权威核验完整版报告出炉,全国60余家维修网点详细地址公布 - 江诗丹顿中国服务中心
  • MC68HC908AT32键盘中断与定时器模块实战:从寄存器配置到避坑指南
  • 基于NXP Kinetis与MCAT的无传感器PMSM FOC全流程调试指南
  • MC68HC908AT32定时器与ADC模块实战:寄存器配置、中断与低功耗设计详解
  • 2026年6月跑遍广州全域,终于找到靠谱黄金回收实体门店渠道 - 生活测评君
  • 舟山黄金贵金属回收|六家靠谱店铺全城推荐 - 新芸鼎珠宝首饰
  • VisualCppRedist AIO:一站式解决Windows程序运行库依赖难题
  • BGU6101宽频带LNA设计实战:从核心参数到PCB布局调优
  • 2026榆林本地正规瓷砖空鼓维修服务商盘点|无损免拆砖修复,全域上门售后有保障 - 宅安选房屋修缮
  • 如何用PCL2启动器打造你的专属Minecraft游戏体验:完整免费指南
  • U-Boot调试核心技巧:硬件断点设置与地址映射实战解析
  • 如何用智能脚本轻松激活Windows和Office系统
  • Hermes Agent实战:5分钟接入飞书/钉钉的本地大模型调度中枢
  • 免费Windows桌面分区工具NoFences:如何快速整理混乱的桌面图标
  • i.MX6 MIPI-CSI2接口驱动实战:从原理到OV5640图像采集全解析
  • UserAgent-Switcher远程配置功能:如何实现浏览器指纹的统一管理
  • 2026年6月花海厂家有哪些,花海景观/百日草种子/牧草种子/狗牙根种子/早熟禾种子/紫花苜蓿种子,花海实力厂家哪家好 - 品牌推荐师
  • RimWorld性能优化终极指南:如何用Performance-Fish告别游戏卡顿
  • 如何在5分钟内免费体验英雄联盟所有皮肤:R3nzSkin国服特供版完整指南
  • 渐进式蒸馏实现单步音频驱动数字人生成:原理、实现与部署
  • Video2X深度学习视频超分辨率技术:多算法架构与性能优化实践
  • 跨音速腔体流动特性与被动控制策略研究
  • 北京恋爱期间赠与合同纠纷律所:如何认定大额转账性质与返还标准? - 品牌2026
  • 连云港黄金贵金属回收宝藏店铺推荐 | 港城全境覆盖 变现无忧 - 新芸鼎珠宝首饰
  • 线下实地走访实录:2026年6月格拉苏蒂官方售后网点深度考察报告,全国超60家门店全覆盖实地勘测 - 亨得利腕表服务中心
  • 2026黄石市家里卫生间漏水、阳台漏水、楼顶漏水、阳台漏水、地下室渗水、阳光房漏水各种房屋漏水情况不用愁!本地防水补漏公司为您排忧解难!精准推荐附近专业防水团队 - 伶鹿到家
  • 北京延庆区同居财产分割律师事务所排名:民宿经营权分割 - 品牌2026
  • 2026 贵阳职业装定制哪家好|本地 6 家工厂直营实测・政企 / 中小微 / 新人全场景攻略 - 贵州服装测评君
  • Ubuntu 16.04下LAMP部署WordPress全链路解析
  • 构建可审计的本地AI开发工作流:Codex/Claude/Gemini CLI实战指南