前言
Bilibili 直播有限制推流和在网页上点开播按钮的 IP 都需要是大陆的,不然不给开。为了解除这个限制,我打算用家里的机器和几台国内外的机器用 wireguard(wg) 起 tunnel 组网,然后再用 Nginx 反代 rtmp. 本文将包含 wireguard 的使用,Nginx 的配置。
架构说明
本文想要实现的网络架构是这样的。国内 NAT 和国外机器之间使用 IPv6 连接,本地到国外机器,国内 NAT 到 home 则使用 IPv4. 这么做一个是因为国内 NAT 的商家不让 IPv4 走大流量,还有就是为了优化整个网络的速率。我在使用这套架构之前只用了一台到大陆走的 CN2 机器作为中间节点,可无奈没办法达到要求速率才出此下策。一般情况下来讲,中继节点越多,从起源机器到目标机器所需延迟则越长。但这里为了业务需求只能牺牲一下延迟了。
Wireguard
wireguard 咋装这里就不赘述了,官网写的挺清楚的。
配置
先生成一个私钥用于 wg 加密数据,记录一下等下要用到. 这个步骤每台机器都要执行。
wg genkey > private
如果要查看私钥对应的公钥,可以使用 cat private | wg pubkey
.
编辑 /etc/wireguard/wg0.conf
, 简单写入配置
下面是 home 节点的示例配置。中继节点(在我的架构中:国内 NAT 和国外机器)的配置和这个大同小异,就不单独贴了。
[Interface]
Address = 172.17.87.86/24
SaveConfig = false
MTU =1300
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -j MASQUERADE
ListenPort = 51787
PrivateKey = # 刚刚生成的私钥填在这
[Peers]
Endpoint = # 对端 IP:ListenPort
AllowedIPs = 172.17.87.93/32
PublicKey = # 对端公钥
简单说明一下。wg 是没有明确的客户端和服务端一说的。被链接的两端中的一端有了需求就会去连接另一端。但是两端中有一端需要有公网 IP,或者能被公网访问到的端口。这个端口应该被定义为 ListenPort
.[Interface]
是对本机端口的定义,[Peers]
是针对远端的定义。PortsUp
和 PortsDown
分别是启动和停止 wg 时执行的命令。这里是把 NAT 做上了,以方便进行 IP 转发。Endpoint
不是必选的,但是就如上面说的,两台对端之间必须要有一台配置上 Endpoint
。两个黑瞎子没法找到对方,总有一个得带盏灯:Endpoint
.AllowedIPs
是走隧道的 IP, 加进去了之后 wg 会自动做好路由。如果需要走隧道的 IP 不加到这里,就算做好了路由也是没办法走隧道的。MTU
设成 1300 解君愁,管他底层 MTU 是多少,IPv4 还是 IPv6, 跑就完事了。
注意!
要注意,需要走代理的 IP 都要加入 AllowedIPs
. 就比如我本机的配置是
AllowedIPs = 172.17.87.86/32, 172.17.87.92/32, 172.17.87.93/32
别忘了启用 IP forward
echo 1 > /proc/sys/net/ipv4/ip_forward
如果还是不行的话,有可能是 NAT 规则的问题。清除重做一下。不过如果你还有别的 NAT 规则别这么玩啊。
iptables -t nat -F
iptables -t nat -A POSTROUTING -j MASQUERADE
Nginx
rtmp 代理我选择用 Nginx 来做。Nginx 需要装一个叫 nginx-rtmp-module 的模块。安装默认是不装的。这里记录下如果用 oneinstack 安装环境的话要怎么弄(我也不太清楚我当初为什么光装一个 nginx 也要用 oneinstack). 编译安装的方法就不记录了。
按照 说明 将文件下载下来后,先别着急运行 install.sh
. 找个目录运行
git clone https://github.com/arut/nginx-rtmp-module
这会把我们要用的模块下载下来。如果网络不好你想下压缩包再传到机器上解压也可以,记住路径。编辑 oneinstack 文件夹里的 options.conf
,找到 nginx_modules_options=''
, 改成
nginx_modules_options='--add-module=/Path/To/The/Model'
然后再安装的 Nginx 就包含我们要用的模块了。
配置
在 nginx.conf
中添加
rtmp {
server {
listen 31451;
chunk_size 4096;
include /usr/local/nginx/conf/stream-enabled/*;
}
}
这个要加到最顶层,和 http
块同级。然后放行下端口 31451.
然后创建目录 /usr/local/nginx/conf/stream-enabled
, 编辑 default.conf
。加入如下内容
application restream {
live on;
record off;
push rtmp://live-push.bilivideo.com/live-bvc/Your_Key;
}
记得把 Your_Key
换成你 B 站的直播密钥。
然后用 obs 推流到 rtmp://内网 IP:31451/restream
就可以了。
后记
感谢 eq, woomai, 老咸鱼和 kirito对我折腾过程中的帮助。下一部的计划是用 ros 来实现这个架构,抛弃 wireguard.
除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。