Nginx配置:如何将子域名反向代理指向特定端口Teamspeak服务
你之前配置SRV记录不生效大概率是记录格式填写错误,不过四层反向代理方案兼容性更强,不依赖Teamspeak客户端对SRV记录的解析支持,完全满足子域名不落到Nginx默认站点的需求,具体步骤如下:
1. 前置模块检查
你现有RPi4上通过apt安装的Nginx默认已经带stream四层代理模块,先执行命令确认:nginx -V 2>&1 | grep with-stream
- 输出带
--with-stream或--with-stream=dynamic即代表模块可用 - 如果是动态加载模式,编辑
/etc/nginx/nginx.conf,在文件最顶部、所有配置块之外(不要放进原有的http{}块内)添加模块加载配置:
load_module /usr/lib/nginx/modules/ngx_stream_module.so;
同时在nginx.conf最外层(和http{}块平级)添加一行配置引入后续的stream规则文件:include /etc/nginx/stream-conf.d/*.conf;
执行mkdir -p /etc/nginx/stream-conf.d创建对应目录。
2. 配置Teamspeak流量转发规则
新建文件/etc/nginx/stream-conf.d/teamspeak.conf,写入以下配置:
stream { # 可选开启日志,排障时用 access_log /var/log/nginx/ts_access.log; error_log /var/log/nginx/ts_error.log; # Teamspeak语音服务默认走UDP 9987端口 upstream ts_voice { server 192.168.x.x:9987; # 替换为部署Teamspeak的树莓派内网IP } server { listen 9987 udp reuseport; proxy_pass ts_voice; proxy_timeout 300s; proxy_responses 1; } # 可选:如果需要开放ServerQuery(默认TCP 10011)、文件传输(默认TCP 30033),添加对应规则 upstream ts_query { server 192.168.x.x:10011; } server { listen 10011; proxy_pass ts_query; } upstream ts_file { server 192.168.x.x:30033; } server { listen 30033; proxy_pass ts_file; } }
注意:
stream{}块和原有http{}块是完全平级的,嵌套进http块会直接导致Nginx配置报错。
3. 配置HTTP/HTTPS兜底规则,避免落到默认站点
为了避免用户直接在浏览器访问Teamspeak子域名时被路由到Nginx默认站点,在http配置目录下新建站点规则:
新建文件/etc/nginx/sites-available/ts-redirect,写入:
server { listen 80; listen 443 ssl http2; # 配了SSL证书再开443监听 server_name ts.your-domain.com; # 替换为你分配给Teamspeak的子域名 # 有证书就填对应路径,没配证书可以只保留80端口监听 # ssl_certificate /path/to/ts.domain.cert.pem; # ssl_certificate_key /path/to/ts.domain.key.pem; default_type text/plain; return 200 "此为Teamspeak服务器地址,请使用Teamspeak客户端连接 ts.your-domain.com:9987"; }
执行软链接启用站点:ln -s /etc/nginx/sites-available/ts-redirect /etc/nginx/sites-enabled/
然后执行配置校验:nginx -t
返回test is successful后重载Nginx生效:systemctl reload nginx
4. DNS与网络配置
- 给Teamspeak子域名添加A记录,公网使用就指向RPi4的公网IP,纯内网使用就指向RPi4的内网IP
- 公网部署场景下,在路由器上把9987 UDP、10011 TCP、30033 TCP端口映射到RPi4的对应端口即可
- 可选优化:如果希望用户在Teamspeak客户端直接输入子域名、不用手动填端口就能连接,可以补配正确格式的SRV记录:
- 记录类型:SRV
- 服务字段:
_ts3._udp(格式必须完全一致,下划线、协议写错都会导致记录不生效) - 目标:你的Teamspeak子域名
- 端口:9987
- 优先级、权重填服务商默认值即可
- 纯内网场景可以做DNS分流:内网客户端访问该子域名直接解析到Teamspeak树莓派的内网IP,流量不经过Nginx转发,延迟更低。
如果能申请到额外的公网IP(部分运营商支持多拨或申请多IP),可以直接给Teamspeak树莓派分配独立公网IP,把子域名A记录指向这个IP,所有流量完全不经过第一台RPi4的Nginx,没有代理性能损耗。但绝大多数家庭宽带场景不支持多公网IP,前面的反代方案是通用性最高的选择。
- 优先读Nginx官方文档的核心模块说明,重点看
ngx_http_core_module、ngx_stream_core_module、ngx_http_proxy_module、ngx_http_upstream_module四个模块的内容,所有配置参数的作用域、默认值、优先级、生效逻辑都有明确标注,准确性远高于网上零散的第三方教程 - 本地搭测试环境反复验证,用
curl、nc、telnet逐段测试端口连通性、转发逻辑,不要直接在生产环境修改配置 - 排错优先看Nginx的
error.log,90%以上的配置错误日志里会直接标清错误原因和对应配置行号,不用盲目搜索解决方案
内容的提问来源于stack exchange,提问作者Bloodshot_pico

