nginx-proxy-manager 404 Host(Dead Host)完全指南:用错误页面优雅处理失效域名与 SEO 降权
【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager
导读
在 nginx-proxy-manager 中,404 Host(在代码与 API 中称为 dead-host)是一种只对外返回 404 状态码的主机配置。它通常用于两类场景:一是域名被搜索引擎收录后已经下线或不再提供服务,需要向爬虫明确声明页面不存在;二是希望把访问量汇总到一个可统计的入口,通过访问日志追踪「死链接」的点击次数与来源(referrer)。读完本文,你将掌握 404 Host 的概念、适用场景、Web 界面配置方法、底层 Nginx 配置生成原理,以及对应的 REST API 与数据模型。
本文的原始依据是仓库内置的波兰语帮助文档 frontend/src/locale/src/HelpDoc/pl/DeadHosts.md(英文版见 frontend/src/locale/src/HelpDoc/en/DeadHosts.md),并在此基础上结合后端源码、模板与前端表单进行了深度扩充。
什么是 404 Host
404 Host 就是「一个简单的主机配置,其职责是展示 404 页面」。与 Proxy Host(反向代理)、Redirection Host(重定向)不同,它不把流量转发到任何上游服务,也不返回 301/302 跳转,而是直接让 Nginx 对进入的请求返回 HTTP 404 状态码。
从实现上看,这个行为体现在后端模板 backend/templates/dead_host.conf 中——核心逻辑只有一句return 404;:
server { {% include "_listen.conf" %} {% include "_certificates.conf" %} {% include "_hsts.conf" %} {% include "_forced_ssl.conf" %} access_log /data/logs/dead-host-{{ id }}_access.log standard; error_log /data/logs/dead-host-{{ id }}_error.log warn; {{ advanced_config }} {% if use_default_location %} location / { {% include "_hsts.conf" %} return 404; } {% endif %} # Custom include /data/nginx/custom/server_dead[.]conf; }也就是说,当请求命中该主机配置的server_name时,Nginx 直接对根路径location /返回 404;同时允许通过「高级配置」(advanced_config)字段追加自定义 Nginx 指令,并支持通过include /data/nginx/custom/server_dead[.]conf加载自定义配置文件(注意该 include 使用了[.]语法,避免与自身递归匹配)。
为什么需要 404 Host:三大典型场景
原文档明确给出了两个核心动机,结合项目实践还可以补充第三个:
1. 为搜索引擎提供正确的信号
当你的域名出现在搜索引擎索引中,但站点已经下线、内容被移除或永久停止服务时,返回 404 是告诉爬虫「这些页面不再存在」的标准方式。相比直接让 DNS 失效或返回 200 空页,404 能更准确地引导搜索引擎清理索引、避免收录无效内容,从而保护站点权重不被稀释。
2. 提供比裸 404 更友好的错误页面
默认情况下 Nginx 的 404 页面非常简陋。通过 404 Host,你可以把域名「接住」,结合自定义的advanced_config或自定义 server 配置文件,输出更美观、更符合品牌形象的错误页,让访问失效 URL 的用户获得良好的退出体验,而不是看到一个技术感十足的报错页。
3. 集中追踪访问与来源(referrer)
这是原文档明确强调的另一个优势:404 Host 会为每个主机单独生成访问日志,你可以借此统计「死链接」被点击的次数,并查看这些流量的来源页面(referrer)。例如迁移站点后,哪些旧 URL 仍被外部引用、被哪些站点引用,都可以通过日志一目了然,辅助你决定是否需要补做重定向。
日志路径由模板中access_log /data/logs/dead-host-{{ id }}_access.log standard;决定——每个 404 Host 拥有独立的dead-host-<ID>_access.log与dead-host-<ID>_error.log文件,日志中记录的正是点击次数与 referrer 信息。
在 Web 界面中创建与配置 404 Host
入口
登录 nginx-proxy-manager 管理界面后,进入Hosts → 404 Hosts页面(对应前端路由文件 frontend/src/pages/Nginx/DeadHosts/index.tsx),点击「添加 404 Host」。列表页(frontend/src/pages/Nginx/DeadHosts/Table.tsx)会以表格展示每个主机的所有者、域名、SSL 证书和启用状态,并提供编辑、启用/禁用、删除操作。
表单字段详解
创建/编辑表单由 frontend/src/modals/DeadHostModal.tsx 实现,分为三个选项卡:
Details(详情)
- Domain Names(域名):该 404 Host 绑定的域名列表,支持通配符(如
*.example.com)。底层由DomainNamesField组件渲染。根据后端 schema backend/schema/common.json 中的domain_names定义,最多可填 100 个、不允许重复,且不能包含& | @ ! # % ^ ( ) ; : / \ } { = + ? < > , ~' "` 等特殊字符。
SSL(证书与安全)
- SSL Certificate(SSL 证书):可选择一个已有证书,或选择「New Certificate」即时签发新证书(表单通过
allowNew开启该选项)。 - Force SSL(强制 SSL):开启后所有 HTTP 请求都会被 301 重定向到 HTTPS。对应字段
ssl_forced,仅当主机绑定了证书且certificate_id > 0时生效,由模板 backend/templates/_forced_ssl.conf 生成include conf.d/include/force-ssl.conf;。 - HTTP/2 Support(HTTP/2 支持):开启后监听指令中启用
http2 on;(见 backend/templates/_listen.conf)。 - HSTS Enabled / HSTS Subdomains:启用 HTTP Strict Transport Security,模板 backend/templates/_hsts.conf 会输出
add_header Strict-Transport-Security $hsts_header always;(63072000 秒,即 2 年);「Subdomains」选项决定该策略是否覆盖所有子域名。注意:HSTS 与 Force SSL 一样,同样依赖证书存在且ssl_forced开启。
Advanced(高级)
- Nginx Config(Nginx 高级配置):以
advanced_config字段直接注入到该主机的 server 块中,适用于添加自定义返回头、自定义 404 页面内容等场景。后端在创建时会保证该字段默认为空字符串(见 backend/internal/dead-host.js 第 53-55 行),避免数据库字段无默认值的问题。
底层实现:数据模型与 REST API
数据库结构
404 Host 在数据库中对应dead_host表,最初由迁移 backend/migrations/20180618015850_initial.js 创建,后续通过 backend/migrations/20181113041458_http2_support.js(新增http2_support)、backend/migrations/20190104035154_disabled.js(新增enabled)、backend/migrations/20190218060101_hsts.js(新增hsts_enabled、hsts_subdomains)逐步演进。完整字段如下:
| 字段 | 类型 | 说明 |
|---|---|---|
id | integer | 主键 |
created_on/modified_on | datetime | 创建/修改时间 |
owner_user_id | integer | 所属用户 ID |
is_deleted | integer | 软删除标记(默认 0) |
domain_names | json | 域名数组(写入时自动排序) |
certificate_id | integer | 关联证书 ID(默认 0 表示无) |
ssl_forced | integer | 是否强制 SSL(默认 0) |
http2_support | integer | 是否启用 HTTP/2(默认 0) |
hsts_enabled | integer | 是否启用 HSTS(默认 0) |
hsts_subdomains | integer | HSTS 是否覆盖子域名(默认 0) |
enabled | integer | 是否启用(默认 1) |
advanced_config | text | 高级 Nginx 配置(默认空字符串) |
meta | json | 元数据 |
对象模型定义在 backend/models/dead_host.js,它基于 Objection.js,声明了dead_host表以及owner(所属用户)和certificate(SSL 证书)两个关联关系,布尔字段会在读写时自动做整型与布尔值转换。
REST API 端点
路由实现在 backend/routes/nginx/dead_hosts.js,所有端点都需要 JWT 认证:
| 方法与路径 | 功能 |
|---|---|
GET /api/nginx/dead-hosts | 获取全部 404 Host,支持?expand=certificate,owner与?query=搜索词 |
POST /api/nginx/dead-hosts | 创建 404 Host |
GET /api/nginx/dead-hosts/:host_id | 获取单个 404 Host |
PUT /api/nginx/dead-hosts/:host_id | 更新 404 Host |
DELETE /api/nginx/dead-hosts/:host_id | 删除 404 Host(软删除) |
POST /api/nginx/dead-hosts/:host_id/enable | 启用 |
POST /api/nginx/dead-hosts/:host_id/disable | 禁用 |
接口响应结构由 backend/schema/components/dead-host-object.json 定义,与上表字段一一对应。
后端处理流程
核心业务逻辑在 backend/internal/dead-host.js:
- 创建:校验权限(
dead_hosts:create)→ 逐个检查域名是否被其他主机占用(internalHost.isHostnameTaken)→ 写入数据库并记录审计日志 → 若选择了「新建证书」则调用createQuickCertificate即时签发并回填certificate_id→ 最后调用internalNginx.configure生成 Nginx 配置。 - 更新:同样先做域名占用检查(更新时排除自身),通过
cleanSslHstsData规范化 SSL/HSTS 数据后写库、记录审计日志,再重新生成 Nginx 配置;如果主机处于禁用状态则跳过配置生成。 - 启用/禁用:
enable会重新生成 Nginx 配置;disable则调用internalNginx.deleteConfig删除配置并reload。 - 删除:软删除(
is_deleted = 1),删除 Nginx 配置并 reload,全程写入审计日志。
所有变更操作都会调用 backend/internal/audit-log.js 写入审计记录,操作类型包括created、updated、deleted、enabled、disabled,对象类型统一为dead-host。
权限控制
404 Host 的权限受用户角色与细粒度权限双重控制:
- 管理员角色默认拥有全部
dead_hosts权限(见 backend/lib/access/dead_hosts-create.json); - 普通用户需要
permission_dead_hosts权限且角色为user; - 权限动作包括
create、update、get、delete、list,并且当用户的权限可见性不是all时,查询结果会自动限定到该用户自己拥有的主机(见 backend/internal/dead-host.js 中getAll的实现)。
前端侧,frontend/src/pages/Nginx/DeadHosts/index.tsx 使用HasPermission组件配合DEAD_HOSTS/VIEW权限控制页面访问,列表中的编辑、启用/禁用、删除按钮则进一步要求MANAGE权限。
实战建议:何时选择 404 Host 而非其他主机类型
结合原文档的场景描述与项目实际,可以给出如下选型参考:
- 站点/页面已永久下线,希望声明「不再存在」:用 404 Host,让爬虫收到明确的 404 信号;
- 希望保留域名控制权并统计死链流量:用 404 Host,借助
dead-host-<ID>_access.log追踪点击量与 referrer; - 域名需要跳转到另一个站点:请使用 Redirection Host(301/302),而不是 404 Host;
- 域名仍指向存活的上游服务:请使用 Proxy Host 配置反向代理。
总结
404 Host 是 nginx-proxy-manager 中体量最小、但语义非常明确的一种主机类型:它用一行return 404;优雅地处理「域名已失效」的场景,同时借助独立访问日志为站长提供了死链统计与来源追踪能力。从本文可以看到,它背后的实现并不简单——从数据库迁移、Objection 模型、REST API、权限体系到 Nginx 模板渲染,形成了一个完整闭环。掌握它的配置字段与底层逻辑,能帮助你在站点迁移、内容下架等场景中更专业地管理域名资产。
如果想进一步研究,推荐阅读以下仓库文件:
- 帮助文档原文:frontend/src/locale/src/HelpDoc/pl/DeadHosts.md(中文版见 frontend/src/locale/src/HelpDoc/zh/DeadHosts.md)
- Nginx 配置模板:backend/templates/dead_host.conf
- 后端业务逻辑:backend/internal/dead-host.js
- 路由与 API:backend/routes/nginx/dead_hosts.js
- 前端表单:frontend/src/modals/DeadHostModal.tsx
- 数据库迁移:backend/migrations/20180618015850_initial.js
【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考