由于云服务器「便宜、CN 路由好、配置高」的不可能三角,我一直都有给自建的 EMBY 服务器前面加一个「线路机」作为反向代理,以便让不会 7x24 在个人设备上开着某个七层代理的正常人能够流畅地访问我的 EMBY。
为什么是四层 TCP 代理/直通
常见的作用于七层的反向代理一般是通过类似 Nginx 或者 Caddy 之类的 Web 服务器实现,但是对于我上面的需求来说,这种方式需要两次的 TLS 的加解密,会带来不小的 overhead,特别是对于低配置的「线路机」来说。而「直通」,一句话解释就是在 L4 只做 TCP 转发,不碰 HTTPS 内容,效率高、消耗低,在后面 Nginx 的配置里能看到,我们只做了最小程度的介入即 ssl_preread
。
因为这种简单的反代场景并不需要对 HTTP 进行改写等等,也不需要考虑在运行代理的服务器上维护 TLS 证书的问题,反而让维护变得简单。唯一要注意的是,用 TCP 直通(TCP Passthrough)进行反代更适合自建的后端,因为Web 服务器、域名解析等可控,比如,可以配合 GeoDNS 分地区解析,仅在某些地区将域名解析为线路机 IP,其他解析为源站 IP,以此自建 poor man's CDN。
NGINX 的配置
当然也可以用 HAProxy,看起来很强大但我不会用。
检查 stream 模块是否可用:
Nginx 对 TCP 代理的支持由 Stream 模块提供,这个模块有可能没有被默认包括在你安装的 Nginx 版本中
nginx -V 2>&1 | grep – '--with-stream'
如果输出里有 --with-stream
(或者显示 dynamic module: ngx_stream_module.so
),说明已编译进来;否则请安装 nginx-full
或者从官方源安装带 stream 支持的包。
在主配置中加载 stream 配置
在 Debian 默认的 /etc/nginx/nginx.conf
中,stream {}
区块通常不被包含。你可以在 nginx.conf
的顶层(最外层)加上一行
# 在 http { … } 块之前或之后,都可以
include /etc/nginx/streams-enabled/*.conf;
创建 L4 代理配置
创建 /etc/nginx/streams-enabled/emby-stream.conf
stream {
# 定义专用日志格式
log_format proxy_stream '$remote_addr [$time_local] '
'SNI=$ssl_preread_server_name '
'bytes_sent=$bytes_sent '
'bytes_received=$bytes_received '
'session_time=$session_time '
'upstream=$upstream_addr';
# 打开日志文件缓存
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
# 可选:根据 SNI 决定上游后端
map $ssl_preread_server_name $backend {
yourdomain.com emby_tls;
#other.example.com other_tls;
#default upstream_default;
}
# 定义上游 Emby TLS 实例
upstream emby_tls {
server <你的EMBY服务器的IP>:443;
}
# TCP+TLS 直通的 server 块
server {
listen 443 reuseport; # 接收客户端 TLS
proxy_pass emby_tls; # 原样转发给后端
ssl_preread on; # 提取 SNI 但不终结 TLS
access_log /var/log/nginx/stream_emby.access.log proxy_stream;
error_log /var/log/nginx/stream_emby.error.log notice;
}
}
重启 Nginx:
sudo nginx -t
sudo systemctl reload nginx
…et voilà