前因

很难想象访问内网服务这玩意我居然能水到第三篇博客,究其根本还是前面的方案虽然能用,但或多或少还是有些小毛病。

Jellyfin 我本来是用一台大带宽 NAT 服务器来做转发,为什么会突然换到 frp,起因是前段时间 Reol 群里要开个 Minecraft 服务器一起玩,而我之前就在 NAS 上跑过一个 MC 服务器跟朋友一起玩生电,所以就很乐意地帮忙开了一个服。

但是之前跟朋友玩的时候是直接通过 IPv6 直连的,而为了避免让 Reol 群的群友们折腾 IPv6,所以只能使用 IPv4 服务器转发。一开始用那台 NAT 服务器试了一下,虽然能连上,但是性能非常差,延迟一直在三四百毫秒,并且波动很大,基本不可玩。

找了一圈最后尝试了一个很多人在用的三方 frp 服务(避免广告嫌疑就不在这提名字了),使用三线 BGP 节点没想到效果出奇的好,朋友连过来基本都延迟稳定在二三十毫秒,非常好用。

MC 的问题解决之后,我就开始考虑既然效果这么好,不如把其它转发服务也转移到三方 frp。最后找到一个每月 15 块钱,单端口能提供 50Mbps 速率的服务提供商,对于我的上传带宽基本够用。

HTTPS 还是 TCP

使用第三方的转发服务首先要注意的是隐私问题,玩 MC 当然无所谓,但是其他服务我就不希望转发内容明文出现在第三方的服务器上,尤其除了 Jellyfin,转发 Immich 相册之类的东西更要注意安全性。

可以看到 frp 虽然是有一个 HTTP/HTTPS 转发模式,但是需要注意,虽然底层协议都是 TCP,在 frp 中,HTTPS 模式并不是“帮你转发一个 HTTPS 流量”,而是让 frps 服务端自己作为 HTTPS 入口,由 frps 来终止 TLS,然后转成明文 HTTP 发回本地服务。

也就是说:Client (浏览器) --TLS--> frps(解密) --HTTP明文--> frpc --> 本地服务

一旦使用 HTTPS 模式转发,证书就必须放在 frps 端,TLS 也就在 frps 处结束了,流量在 frps → frpc → Jellyfin 之间全是明文。

所以 frp 一定要使用 TCP 模式,此时 frp 只是做一个纯粹的隧道,仅转发加密字节流,看不到明文媒体/接口内容,才能实现端到端加密。

配置

NAS 本地依然还是跟之前一样,假设 Jellyfin 端口是 11451,使用 Nginx Proxy Manager 配置一个反代端口为 11452 并配置 HTTPS 证书。

接下来只要在三方 frp 平台创建一个新的隧道,协议 TCP,本地端口 11452,远程端口 11453,把域名解析到隧道的公网地址上,最后在 NAS 上配置好 frpc 端,就可以通过 https://example.com:11453 访问到内网的 Jellyfin 了。

因为证书配置在本地,frp 在转发过程中不会解密,只能看到原始加密的字节流,所以无需担心第三方转发平台会看到转发内容。

Jellyfin 获取真实 IP

这样配置下来会出现一个问题,Jellyfin 端获取到的源 IP 其实是 frpc 的内网 IP,真实用户的公网 IP 被丢在 frps 那一端,没带过来。而 Jellyfin 需要登录 IP 来判断内网来选择是否强制转码,所以需要想办法让 Jellyfin 获取到真实 IP,Proxy Protocol 协议正是做这件事的。

Proxy Protocol 需要 frp 端和 Nginx 端同时启用才能生效。

frp 端配置很简单,只需要在 frpc.toml 中添加一行 transport.proxyProtocolVersion = "v2" 即可生效。

而 Nginx 端,由于 NPM 目前不支持配置 Proxy Protocol,所以只能手动修改配置文件了,vhost 路径在 data/nginx/proxy_host/ 下。

server 段中加上如下内容:

listen 11452 proxy_protocol ssl;
set_real_ip_from 127.0.0.1;
set_real_ip_from <frps服务器公网IP>;
real_ip_header proxy_protocol;
real_ip_recursive on;

最后重启 NPM,Jellyfin 后台 Dashboard 就可以看到已经获取到真实的登录 IP 了。

Nginx Proxy Protocol 问题

正当我以为问题圆满解决的时候,突然发现 Jellyfin 原本 IPv6 直连的地址打不开了。一通排查后发现,因为两个 vhost 都在 443 端口监听,而 Nginx 无法只对某个 server 单独启用 Proxy Protocol,同一端口只能都启用 Proxy Protocol 或者都不用,所以我这样配置必然会导致其中一个冲突无法使用。

最后我选择了一个简单粗暴的解决方案:直接再起一个 Nginx Proxy Manager 容器,一个开 Proxy Protocol,一个不开,分开配置反向代理,这下没有问题了(

7c9f3cefa051c671e1d4723c7db72e42

Last modification:November 9th, 2025 at 11:22 pm
If you think my article is useful to you, please feel free to appreciate