diff --git a/docs/getting-started/install/other/nginxproxymanager.md b/docs/getting-started/install/other/nginxproxymanager.md index 69b40c52..ddc84c73 100644 --- a/docs/getting-started/install/other/nginxproxymanager.md +++ b/docs/getting-started/install/other/nginxproxymanager.md @@ -126,3 +126,119 @@ docker compose up -d ![Nginx Proxy Manager SSL](/img/nginx-proxy-manager/npm-ssl.png) 至此,我们已经完成了在 Nginx Proxy Manager 配置 Halo 反向代理并添加 SSL 证书的全过程。 + +## 进阶配置:性能与安全(可选) + +前文已完成基础反向代理与 SSL,对大多数博客已经够用。本节介绍在 NPM 中追加性能优化与安全响应头配置,两个目标: + +- **性能**:让 JavaScript、字体、JSON 等静态资源也参与 gzip 压缩;调大 proxy buffer 避免响应落盘 +- **安全**:补齐 [securityheaders.com](https://securityheaders.com) 认可的安全响应头,默认可拿到 A 评级 + +:::info +本节所有配置均为反代层通用优化,与具体主题无关,适用于任何 Halo 实例。 +::: + +### 在 NPM 中找到自定义配置入口 + +1. 进入 NPM 仪表盘,在 Hosts → Proxy Hosts 点开 Halo 的代理记录进行编辑 +2. 切换到 **Advanced** 标签页 +3. 把下面的内容粘贴到 **Custom Nginx Configuration** 文本框 +4. 保存后 NPM 会自动 reload nginx,无需重建容器 + +### 推荐的自定义配置 + +```nginx +# ---- gzip 压缩:补齐 NPM 默认未覆盖的 JS、字体、JSON 等 MIME 类型 ---- +gzip on; +gzip_vary on; +gzip_proxied any; +gzip_comp_level 6; +gzip_min_length 1024; +gzip_types + text/css + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/rss+xml + application/atom+xml + image/svg+xml + font/ttf + font/otf + font/woff + font/woff2; +# 若目录下存在 .gz 预压缩文件则优先使用 +gzip_static on; + +# ---- proxy buffer:避免较大响应被临时写入磁盘 ---- +proxy_buffers 16 32k; +proxy_buffer_size 64k; +proxy_busy_buffers_size 128k; + +# ---- 安全响应头:加 always 确保错误页也会返回 ---- +add_header X-Content-Type-Options "nosniff" always; +add_header X-Frame-Options "SAMEORIGIN" always; +add_header X-XSS-Protection "1; mode=block" always; +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; +# HSTS 请在确认 HTTPS 稳定运行后再启用,见下文说明 +# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + +# ---- RSS 路径别名:Halo 默认 RSS 为 /rss.xml ---- +rewrite ^/rss$ /rss.xml permanent; +rewrite ^/feed$ /rss.xml permanent; +``` + +:::tip +`gzip_types` 不要再列 `text/html`,nginx 默认已经对其启用 gzip,重复声明会产生 `duplicate MIME type` 警告。 +::: + +### 关于 HSTS + +`Strict-Transport-Security` 会告诉浏览器未来只能通过 HTTPS 访问当前域名。一旦启用且 `max-age` 较长,浏览器会缓存该策略直到过期,期间无法回退到 HTTP。因此建议: + +- 在 HTTPS 证书可正常续签、基础设施稳定运行 1–2 周后再启用 +- 先从 `max-age=300`(5 分钟)起步验证,确认无误再逐步调大到 `63072000`(2 年) +- `preload` 表示提交到浏览器内置 HSTS 列表,**提交后撤销非常困难**,确有必要再加 + +### 验证配置是否生效 + +```bash +# 查看安全响应头 +curl -I https://your-halo-domain.example.com/ \ + | grep -iE "x-content-type|x-frame|x-xss|referrer-policy|permissions-policy" + +# 检查 JavaScript 是否启用了 gzip +curl -IH "Accept-Encoding: gzip" \ + https://your-halo-domain.example.com/themes//source/main.js \ + | grep -i content-encoding +``` + +浏览器侧也可以在 DevTools → Network → Response Headers 中确认。 + +### 常见问题 + +#### 能拿到 securityheaders.com A+ 吗? + +上面的配置能稳定拿到 **A 评级**。追求 **A+** 的硬指标是配置 `Content-Security-Policy`(CSP),在博客场景下收益较低: + +- 多数 Halo 主题依赖若干第三方 CDN(字体、评论系统、统计、表情等),每个都需要加入 CSP 白名单 +- 主题模板中常见内联脚本,需使用 `'unsafe-inline'`(会明显削弱 CSP 的价值)或改造为 nonce 模式 +- 管理后台「代码注入」功能注入的脚本同样受 CSP 约束,白名单收敛难度较高 + +如确有 A+ 需求,建议按以下路径落地: + +1. 先使用 `Content-Security-Policy-Report-Only`,不阻断页面,仅在浏览器控制台打印违规 +2. 观察 1–2 周,根据 violation 报告收敛白名单 +3. 白名单稳定后再转为生产 `Content-Security-Policy` + +作为参考,GitHub 本身的 securityheaders.com 评级也是 A,对博客类站点而言 A 已足够。 + +#### NPM 界面中的「缓存资源」开关要开启吗? + +建议保持关闭。Halo 自身已通过 `ETag`、`Last-Modified` 等机制对静态资源提供合理的缓存策略,NPM 层再叠一层缓存可能导致主题升级或资源替换后不能立即生效。性能提升主要来自本节的 gzip 与 proxy buffer 优化。 + +#### 为什么要调大 proxy buffer? + +NPM 默认的 proxy buffer 较小,当 Halo 返回的响应体超过 buffer 总量时,nginx 会把剩余数据临时写入磁盘后再转发。调大到 `16 32k`(共 512 KB)能覆盖绝大多数 HTML/JSON 响应,避免磁盘 I/O 成为瓶颈。 diff --git a/versioned_docs/version-2.24/getting-started/install/other/nginxproxymanager.md b/versioned_docs/version-2.24/getting-started/install/other/nginxproxymanager.md index 69b40c52..ddc84c73 100644 --- a/versioned_docs/version-2.24/getting-started/install/other/nginxproxymanager.md +++ b/versioned_docs/version-2.24/getting-started/install/other/nginxproxymanager.md @@ -126,3 +126,119 @@ docker compose up -d ![Nginx Proxy Manager SSL](/img/nginx-proxy-manager/npm-ssl.png) 至此,我们已经完成了在 Nginx Proxy Manager 配置 Halo 反向代理并添加 SSL 证书的全过程。 + +## 进阶配置:性能与安全(可选) + +前文已完成基础反向代理与 SSL,对大多数博客已经够用。本节介绍在 NPM 中追加性能优化与安全响应头配置,两个目标: + +- **性能**:让 JavaScript、字体、JSON 等静态资源也参与 gzip 压缩;调大 proxy buffer 避免响应落盘 +- **安全**:补齐 [securityheaders.com](https://securityheaders.com) 认可的安全响应头,默认可拿到 A 评级 + +:::info +本节所有配置均为反代层通用优化,与具体主题无关,适用于任何 Halo 实例。 +::: + +### 在 NPM 中找到自定义配置入口 + +1. 进入 NPM 仪表盘,在 Hosts → Proxy Hosts 点开 Halo 的代理记录进行编辑 +2. 切换到 **Advanced** 标签页 +3. 把下面的内容粘贴到 **Custom Nginx Configuration** 文本框 +4. 保存后 NPM 会自动 reload nginx,无需重建容器 + +### 推荐的自定义配置 + +```nginx +# ---- gzip 压缩:补齐 NPM 默认未覆盖的 JS、字体、JSON 等 MIME 类型 ---- +gzip on; +gzip_vary on; +gzip_proxied any; +gzip_comp_level 6; +gzip_min_length 1024; +gzip_types + text/css + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/rss+xml + application/atom+xml + image/svg+xml + font/ttf + font/otf + font/woff + font/woff2; +# 若目录下存在 .gz 预压缩文件则优先使用 +gzip_static on; + +# ---- proxy buffer:避免较大响应被临时写入磁盘 ---- +proxy_buffers 16 32k; +proxy_buffer_size 64k; +proxy_busy_buffers_size 128k; + +# ---- 安全响应头:加 always 确保错误页也会返回 ---- +add_header X-Content-Type-Options "nosniff" always; +add_header X-Frame-Options "SAMEORIGIN" always; +add_header X-XSS-Protection "1; mode=block" always; +add_header Referrer-Policy "strict-origin-when-cross-origin" always; +add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; +# HSTS 请在确认 HTTPS 稳定运行后再启用,见下文说明 +# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + +# ---- RSS 路径别名:Halo 默认 RSS 为 /rss.xml ---- +rewrite ^/rss$ /rss.xml permanent; +rewrite ^/feed$ /rss.xml permanent; +``` + +:::tip +`gzip_types` 不要再列 `text/html`,nginx 默认已经对其启用 gzip,重复声明会产生 `duplicate MIME type` 警告。 +::: + +### 关于 HSTS + +`Strict-Transport-Security` 会告诉浏览器未来只能通过 HTTPS 访问当前域名。一旦启用且 `max-age` 较长,浏览器会缓存该策略直到过期,期间无法回退到 HTTP。因此建议: + +- 在 HTTPS 证书可正常续签、基础设施稳定运行 1–2 周后再启用 +- 先从 `max-age=300`(5 分钟)起步验证,确认无误再逐步调大到 `63072000`(2 年) +- `preload` 表示提交到浏览器内置 HSTS 列表,**提交后撤销非常困难**,确有必要再加 + +### 验证配置是否生效 + +```bash +# 查看安全响应头 +curl -I https://your-halo-domain.example.com/ \ + | grep -iE "x-content-type|x-frame|x-xss|referrer-policy|permissions-policy" + +# 检查 JavaScript 是否启用了 gzip +curl -IH "Accept-Encoding: gzip" \ + https://your-halo-domain.example.com/themes//source/main.js \ + | grep -i content-encoding +``` + +浏览器侧也可以在 DevTools → Network → Response Headers 中确认。 + +### 常见问题 + +#### 能拿到 securityheaders.com A+ 吗? + +上面的配置能稳定拿到 **A 评级**。追求 **A+** 的硬指标是配置 `Content-Security-Policy`(CSP),在博客场景下收益较低: + +- 多数 Halo 主题依赖若干第三方 CDN(字体、评论系统、统计、表情等),每个都需要加入 CSP 白名单 +- 主题模板中常见内联脚本,需使用 `'unsafe-inline'`(会明显削弱 CSP 的价值)或改造为 nonce 模式 +- 管理后台「代码注入」功能注入的脚本同样受 CSP 约束,白名单收敛难度较高 + +如确有 A+ 需求,建议按以下路径落地: + +1. 先使用 `Content-Security-Policy-Report-Only`,不阻断页面,仅在浏览器控制台打印违规 +2. 观察 1–2 周,根据 violation 报告收敛白名单 +3. 白名单稳定后再转为生产 `Content-Security-Policy` + +作为参考,GitHub 本身的 securityheaders.com 评级也是 A,对博客类站点而言 A 已足够。 + +#### NPM 界面中的「缓存资源」开关要开启吗? + +建议保持关闭。Halo 自身已通过 `ETag`、`Last-Modified` 等机制对静态资源提供合理的缓存策略,NPM 层再叠一层缓存可能导致主题升级或资源替换后不能立即生效。性能提升主要来自本节的 gzip 与 proxy buffer 优化。 + +#### 为什么要调大 proxy buffer? + +NPM 默认的 proxy buffer 较小,当 Halo 返回的响应体超过 buffer 总量时,nginx 会把剩余数据临时写入磁盘后再转发。调大到 `16 32k`(共 512 KB)能覆盖绝大多数 HTML/JSON 响应,避免磁盘 I/O 成为瓶颈。