收起左侧

利用Lucky中的stun使NAS中的BT客户端获得公网IP并实现自动端口转发

0
回复
100
查看
[ 复制链接 ]

1

主题

0

回帖

0

牛值

江湖小虾

前言

某个运营商不能申请家庭网的公网IPv4,为了在外面访问NAS方便点,就用DDNS将IPv6地址绑了域名。
开始是很好用,但自从玩了PT后发现有些用户连IPv6都没开启,IPv4也连不上。所以就打算自己折腾个IPv4的公网IP。
刚好Lucky里面有很多STUN(一种解决P2P应用NAT穿越问题的常用技术)教程,但有些复杂有些功能不全,比如没有自动化的端口转发,于是打算整合有关的教程写一期稍微适合和自己一样环境的教程。

所需工具

NAS
支持SSH连接的路由器(以openwrt系统为例)
NAT1网络环境
BT客户端(以Transmission为例)

教程

1 安装并启用Lucky

在NAS上或者路由器上操作都可以,不过这边建议在路由器上安装,这样更新端口就三行代码能搞定。如果在NAS上安装要调用到路由器的API。

1.1 打开路由器管理页面并更新软件列表(以Openwrt的Argon主题为例)

浏览器输入路由器后台管理地址,如192.168.10.1,然后登录,进入系统-软件包,然后点击更新列表等待软件包列表更新完成后点击关闭
如更新失败请配置国内镜像源,具体参考镜像站给出的方案

在过滤器中输入crul查看是否已安装,没安装的话点击安装正常安装即可

1.2 安装并启动Lucky

打开 https://github.com/gdy666/luci-app-lucky/releases 页面下载对应架构的IPK包,现在完成后在软件包页面点击上传软件包
先安装CPU架构相应Lucky核心IPK包
再安装最新的luci-app-lucky_XXX_all.ipk 和 luci-i18n-lucky-zh-cn_XXX_all.ipk

安装完成后Lucky应该会出现在在openwrt管理页面的服务-Lucky,点击启动

1.3 设置参考

启动完成后就会出现后台管理地址,点击进入

进入之后输入默认的账号密码666登录,然后会提示更改设置,参考:

还可以上传最新版本tar.gz包更新

2 检测并配置NAT1网络环境

2.1 检测NAT环境

在Lucky后台中进入STUN内网穿透,点击NAT类型检测,再点击开始检测,开源多试几个。为NAT1的话可以直接跳到3

2.2 尝试配置NAT1环境

有些系统在openwrt管理页面的网络-防火墙里面可以找到fullcone打勾之后保存并应用就好。
有些系统则是在网络-网络加速中参考图上配置保存并应用就好

保存完成之后再去Lucky检测是否为NAT1,如果还不是的话还是找其他教程开NAT1吧,也有可能是运营商的问题。

3 配置STUN

3.1 添加穿透规则

在Lucky的STUN内网穿透中点击添加穿透规则,然后参考图片参数并点击添加

得到一个公网IP加一个随机的端口10875

3.2 更改BT客户端的监听端口

以Transmission的TrguiNG页面为例,点击右上角设置-网络修改端口,改为刚才的公网IP端口并保存。

3.3 添加端口转发

回到openwrt后台,进入网络-防火墙-端口转发然后添加,其他选项不动,只填端口和IP,参考图片

保存并应用。进入https://tcp.ping.pe/中测试刚才的公网IP能否连的通
ping得通即为正常。
由于端口会变,这是只是个临时的方案,下面要获取改端口的指令。

3.4 获取端口更新指令

回到openwrt后台,进入网络-防火墙-端口转发,然后编辑刚才添加的端口转发规则,把内部端口的内容随便串数字,保存,但不要应用!
页面右上角会有个未保存配置点进去,复制里面的cfgxxxxxx,后面用得上。

点击恢复或者保存并应用都行,后面要测试脚本是否生效。

3.5 为STUN添加脚本

回到Lucky的STUN内网穿透页面,编辑刚才添加的规则。启用自定义脚本转发,以Transmission为例,使端口更新时自动执行脚本同步更新Transmission里面的端口。

client= #这里填tr是Transmission,qb是Qbittorrent
host= #这里填NAS地址
webui= #RPC端口
port=${port}
username= #RPC用户名
password= #RPC密码

[ "$client" = tr ] && {
#Transmission
json='{"arguments": {"peer-port": '$port'},"method": "session-set"}'
tr_token=$(curl -Ls -X POST http://$username:$password@$host:$webui/transmission/rpc/ | awk -F ': ' '{print$(NF)}' | awk -F '<' '{print$1}')
curl -X POST http://$username:$password@$host:$webui/transmission/rpc/ -H "X-Transmission-Session-Id: $tr_token" -d "$json"
} || [ "$client" = qb ] && {
#qbit
qb_token=$(curl -s -i -X POST -d "username=$username&password=$password" http://$host:$webui/api/v2/auth/login | sed -n 's/Set-Cookie: SID=\([^;]*\);.*/\1/p')
curl -H "Cookie: SID=$qb_token" -X POST --data-urlencode 'json={"listen_port":${port}}' http://$host:$webui/api/v2/app/setPreferences
} || echo "仅支持 client=qb 或 client=tr"

uci set firewall.cfgxxxxxx.dest_port='${port}' #这里cfgxxxxxx改成3.4中复制的部分
uci commit firewall
/etc/init.d/firewall reload >/dev/null 2>&1

我的配置修改完成后即为

client=tr
host=192.168.0.154
webui=9091
port=${port}
username=admin
password=123456

[ "$client" = tr ] && {
#Transmission
json='{"arguments": {"peer-port": '$port'},"method": "session-set"}'
tr_token=$(curl -Ls -X POST http://$username:$password@$host:$webui/transmission/rpc/ | awk -F ': ' '{print$(NF)}' | awk -F '<' '{print$1}')
curl -X POST http://$username:$password@$host:$webui/transmission/rpc/ -H "X-Transmission-Session-Id: $tr_token" -d "$json"
} || [ "$client" = qb ] && {
#qbit
qb_token=$(curl -s -i -X POST -d "username=$username&password=$password" http://$host:$webui/api/v2/auth/login | sed -n 's/Set-Cookie: SID=\([^;]*\);.*/\1/p')
curl -H "Cookie: SID=$qb_token" -X POST --data-urlencode 'json={"listen_port":${port}}' http://$host:$webui/api/v2/app/setPreferences
} || echo "仅支持 client=qb 或 client=tr"

uci set firewall.cfg163837.dest_port='${port}'
uci commit firewall
/etc/init.d/firewall reload >/dev/null 2>&1

注意,后面三行仅适配openwrtrt及其他分支系统,其他系统请自行修改。

点击修改,并查看日志

一般情况下有success即为成功。
回到openwrt后台,进入网络-防火墙-端口转发中查看端口是否更新,变成新端口了即为成功。

至此BT客户端的内网穿透已经成功了,可以去PT站的个人界面验证下IP有没有变为公网IP。

3.6 适用于NAS及其他设备运行的Lucky的脚本

由于NAS想让路由器执行指令需要ssh,使用ssh的话添加密钥又得多一步,所以我们仍然采用curl发送post请求来让路由器更新端口转发然后应用来实现。最后两行为AI出来的代码,经测试完成需求。

#BT客户端参数
client= #这里填tr是Transmission,qb是Qbittorrent
host= #这里填NAS地址
webui= #RPC端口
port=${port}
username= #RPC用户名
password= #RPC密码
#路由器
Router_IP= #路由器IP
Router_USER= #路由器用户名,一般为root
Router_PASS= #路由器密码
Rule_Number= #之前复制的cfgxxxxxx

#不要改下面
[ "$client" = tr ] && {
#Transmission
json='{"arguments": {"peer-port": '$port'},"method": "session-set"}'
tr_token=$(curl -Ls -X POST http://$username:$password@$host:$webui/transmission/rpc/ | awk -F ': ' '{print$(NF)}' | awk -F '<' '{print$1}')
curl -X POST http://$username:$password@$host:$webui/transmission/rpc/ -H "X-Transmission-Session-Id: $tr_token" -d "$json"
} || [ "$client" = qb ] && {
#qbit
qb_token=$(curl -s -i -X POST -d "username=$username&password=$password" http://$host:$webui/api/v2/auth/login | sed -n 's/Set-Cookie: SID=\([^;]*\);.*/\1/p')
curl -H "Cookie: SID=$qb_token" -X POST --data-urlencode 'json={"listen_port":${port}}' http://$host:$webui/api/v2/app/setPreferences
} || echo "仅支持 client=qb 或 client=tr"

router_token=$(curl -s -i -X POST http://$Router_IP/cgi-bin/luci/ -H "Content-Type: application/x-www-form-urlencoded" -d "luci_username=$Router_USER&luci_password=$Router_PASS" | grep -i 'set-cookie: sysauth_http' | grep -o 'sysauth_http=[^;]*' | head -1 | cut -d'=' -f2)
curl -s -X POST http://$Router_IP/ubus -H "Content-Type: application/json" -H "Cookie: sysauth_http=$router_token" -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"call\",\"params\":[\"$router_token\",\"uci\",\"set\",{\"config\":\"firewall\",\"section\":\"$Rule_Number\",\"values\":{\"dest_port\":\"${port}\"}}]}" && curl -s -X POST http://$Router_IP/ubus -H "Content-Type: application/json" -H "Cookie: sysauth_http=$router_token" -d "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"call\",\"params\":[\"$router_token\",\"uci\",\"apply\",{}]}"

我的配置修改完成后即为,如自己参数中有特殊符号请加双引号,如password="#123456@"

#BT客户端参数
client=tr
host=192.168.0.154
webui=9091
port=${port}
username=admin
password=123456
#路由器
Router_IP=192.168.0.1
Router_USER=root
Router_PASS=123456
Rule_Number=cfg163837

#不要改下面
[ "$client" = tr ] && {
#Transmission
json='{"arguments": {"peer-port": '$port'},"method": "session-set"}'
tr_token=$(curl -Ls -X POST http://$username:$password@$host:$webui/transmission/rpc/ | awk -F ': ' '{print$(NF)}' | awk -F '<' '{print$1}')
curl -X POST http://$username:$password@$host:$webui/transmission/rpc/ -H "X-Transmission-Session-Id: $tr_token" -d "$json"
} || [ "$client" = qb ] && {
#qbit
qb_token=$(curl -s -i -X POST -d "username=$username&password=$password" http://$host:$webui/api/v2/auth/login | sed -n 's/Set-Cookie: SID=\([^;]*\);.*/\1/p')
curl -H "Cookie: SID=$qb_token" -X POST --data-urlencode 'json={"listen_port":${port}}' http://$host:$webui/api/v2/app/setPreferences
} || echo "仅支持 client=qb 或 client=tr"

router_token=$(curl -s -i -X POST http://$Router_IP/cgi-bin/luci/ -H "Content-Type: application/x-www-form-urlencoded" -d "luci_username=$Router_USER&luci_password=$Router_PASS" | grep -i 'set-cookie: sysauth_http' | grep -o 'sysauth_http=[^;]*' | head -1 | cut -d'=' -f2)
curl -s -X POST http://$Router_IP/ubus -H "Content-Type: application/json" -H "Cookie: sysauth_http=$router_token" -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"call\",\"params\":[\"$router_token\",\"uci\",\"set\",{\"config\":\"firewall\",\"section\":\"$Rule_Number\",\"values\":{\"dest_port\":\"${port}\"}}]}" && curl -s -X POST http://$Router_IP/ubus -H "Content-Type: application/json" -H "Cookie: sysauth_http=$router_token" -d "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"call\",\"params\":[\"$router_token\",\"uci\",\"apply\",{}]}"

参考文献

「LUCKY STUN穿透」使用 cURL 自动修改 Transmission 的监听端口 作者: ie-12
打通大内网第二期 让BT下载畅通无阻 (基于Lucky的STUN穿透) 作者:qaz741wsd856

收藏
送赞
分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则