反向代理与 HTTPS

服务端跑起来之后,外网访问这件事迟早会提上日程。直接把端口暴露到公网是最省事也最危险的做法。反向代理加 HTTPS 是社区里被验证最多的方案,它把证书、域名、安全规则集中在一层,Emby 服务端本身保持简单。这一篇讲清楚方案选型、证书获取与两套可用的配置。

先给本篇定一个预期:代理部署是全书操作密度最高的一篇,新手可能需要一两个晚上反复对照才能完全跑通。但它是少数一次配置、长期受益的环节,证书自动续期跑顺之后,你几乎不会再想起代理的存在。

为什么需要反向代理

反向代理在客户端与 Emby 之间加了一层服务器。所有外部请求先到代理,代理再转发给内网的 Emby。初看只是多了一跳,但它一次性解决了四个问题。

需求 直连暴露端口的痛点 反向代理的解法
HTTPS 服务端需自签证书 代理层统一管理证书
域名访问 只能用 IP 加端口 域名指向代理
访问控制 服务端直接暴露 代理层过滤与限流
多服务复用 每个服务占一个端口 一个域名按路径分发

反向代理请求路径

反向代理带来的收益是结构性的:证书到期只在一处更新、安全规则只在一处维护、未来再加别的服务也按同一套模式接入。相比之下内网穿透方案的优势是不暴露任何端口,适合不想碰证书与端口的用户;代价是每个客户端都要装软件,em-0103 对三种外网姿势有过完整对比。

Nginx 与 Caddy 的选择

两个最主流的反向代理软件都能胜任,差别在配置哲学。Nginx 需要你写明每个细节,灵活但学习成本高;Caddy 把 HTTPS 证书申请与续期自动化了,配置文件极短。

维度 Nginx Caddy
配置量 多 少
证书申请 手动配置或插件 自动完成
续期 需安排任务 自动
社区资料 非常多 逐渐增多
适用人群 已熟悉或需要细控 追求省心

只有一个公网入口、只代理 Emby 一个服务时,Caddy 几乎是无可争议的选择。家里若已经有 Nginx 在跑其他服务,则统一在 Nginx 里加一段配置更顺。选型不需要纠结,哪个熟或哪个依赖少就用哪个。

多说一句部署位置。代理软件通常放在能同时访问公网与内网的机器上:软路由、旁路由或常开小主机都可以。群晖用户可以直接用系统自带的反向代理门户做基础转发,不需要另外装软件,但那个界面对 HTTPS 的灵活性有限,复杂需求仍建议用容器跑 Nginx 或 Caddy。

域名与证书获取

反向代理要对外提供服务,需要两样东西:一个解析到你家公网入口的域名,以及该域名的 TLS 证书。域名可以是从任意注册商买的任意域名,免费二级域名也可以用。证书的常见来源是 Let’s Encrypt,它签发的证书被主流浏览器信任,个人使用足够。

申请证书的前置条件是你的公网入口能让证书颁发机构完成验证。最常用的两种验证方式各有适用场景:

验证方式 原理 适用条件
HTTP 验证 颁发机构访问域名的特定路径 有公网 IP 且 80 端口可达
DNS 验证 在域名解析中写入 TXT 记录 无公网 IP 或 80 被封

家宽 80 端口被封的情况并不少见,这时 DNS 验证是唯一选择;有公网 IP 且 80 可达时 HTTP 验证配置更简单。Caddy 两种都支持,Nginx 配合证书工具同样可以。

如果你的宽带是运营商大内网,连公网 IP 都没有,情况会复杂一些。常见出路是借助具备公网入口的中继服务做验证,或干脆回到内网穿透方案。这条路上证书反而是次要问题,先确认网络的公网可达性再谈代理,能避免把精力花在注定走不通的分支上。

Nginx 配置示例

下面是一段最小可用的 Nginx 配置,把域名的请求转发到内网的 Emby 服务端。证书路径以你实际申请的位置为准:

server {
    listen 443 ssl;
    server_name emby.example.com;

    ssl_certificate     /etc/letsencrypt/live/emby.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/emby.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8096;
        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;
    }
}

几个要点。proxy_pass 指向 Emby 服务端的实际地址与端口,同一宿主机上是本地回环,跨机器则是内网 IP。三个 header 转发是让 Emby 知道原始请求来源,缺少它们会导致日志里全都是代理地址、远程访问控制也无法按来源区分。WebSocket 相关的升级头在 Emby 的实时通知中会用到,Nginx 的现代版本对常见场景已经自动处理,若遇到网页端状态不刷新,按官方示例补上升级头即可。

证书续期由系统的定时任务调用证书工具完成,Nginx 重新加载配置即生效,不需要重启服务。

Caddy 配置示例

Caddy 的等价配置只有几行,证书申请与续期全自动:

emby.example.com {
    reverse_proxy 127.0.0.1:8096
}

Caddyfile 的极简是它最大的优势:首次启动时它自动向 Let’s Encrypt 申请证书,到期前自动续期。配置量少意味着出错的地方少,对不想在证书上花任何时间的家庭用户非常合适。

代理层的增强设置

反向代理一旦接管入口,就可以做一些服务端本身做起来别扭的事。常用的三类增强如下。

增强 原理 收益
强制 HTTPS HTTP 请求跳转到 HTTPS 避免误用明文
速率限制 单 IP 请求频率上限 抗扫描与暴破
来源过滤 只允许可信网段访问 服务端不再对公网裸奔

反向代理分层结构

强制 HTTPS 是最低成本的安全增强。不开启时用户可能习惯性用 HTTP 访问,账号密码在传输中明文经过每一跳。速率限制对暴露在公网的家庭服务器值得开——互联网上的扫描流量远比你想象的多,限流配置能把绝大多数低级探测挡在门外。这些都属于代理层的收益,也是直连方案给不了的东西。

再补一个实用的组合玩法:多服务共享一个域名。代理层可以按路径把请求分发到不同内网服务,影音服务、文件管理、面板工具各占一个子域名,体验上像一家人在运营一个小型家庭云。这正是反向代理比端口转发先进的本质——一个入口、无限服务,而每个服务都不必知道对方的存在。

常见问题

有一类问题与 HTTPS 本身无关却常在代理后出现:网页端能打开、视频播不出来。这通常是代理对长连接或大数据流的支持问题,表现是进度条只走一小段就停。排查方向是代理的超时设置与缓冲设置,让代理对大响应不要主动截断。

另一类是证书过期导致访问失效。Let’s Encrypt 证书有效约三个月,自动续期失效后服务会忽然不可用。养成打开日历提醒或监控代理健康状态的习惯,比等家人打电话告诉你服务器坏了强。证书工具的续期模拟命令可以提前验证续期是否正常,部署完成后跑一次是值得的。

第三类最隐蔽:配置改错了但没人发现。代理配置调整后务必从外网实际访问一次,而不只在本地测试。内网测试想当然地认为外网也会通,是反向代理排错中最常见的思维盲区,花几分钟用手机流量验证一遍,比事后推测问题来源高效得多。

延伸阅读