前言
最近拉了条移动宽带到宿舍,立马改桥接用路由器拨号。虽然没有公网ipv4,但惊喜的发现是nat1,也就是说能变相的通过打洞获得公网般的体验。
打洞我用的是natmap,不过这篇文章不打算说natmap相关的安装和设置,主要说下打洞后的一些应用。
qbittorrent打洞
项目:qBittorrent-NAT-TCP-Hole-Punching
大佬文章:通过 NAT TCP 打洞使 qBittorrent 获得公网 IPv4 的连接性体验
脚本如下,根据情况修改参数
- private_port: Natter 填写
$3
/ NATMap 填写 $4
- public_port: Natter 填写
$5
/ NATMap 填写 $2
- qb_web_host: qBittorrent 主机的ip
- qb_web_port: qBittorrent Web 服务的端口,一般为 8080
- qb_username: 用户名
- qb_password: 密码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| #!/bin/sh
# Natter/NATMap
private_port=$4 # Natter: $3; NATMap: $4
public_port=$2 # Natter: $5; NATMap: $2
# qBittorrent.
qb_web_host="192.168.50.3"
qb_web_port="8080"
qb_username="admin"
qb_password="adminadmin"
echo "Update qBittorrent listen port to $public_port..."
# Update qBittorrent listen port.
qb_cookie=$(curl -s -i --header "Referer: http://$qb_web_host:$qb_web_port" --data "username=$qb_username&password=$qb_password" http://$qb_web_host:$qb_web_port/api/v2/auth/login | grep -i set-cookie | cut -c13-48)
curl -X POST -b "$qb_cookie" -d 'json={"listen_port":"'$public_port'"}' "http://$qb_web_host:$qb_web_port/api/v2/app/setPreferences"
echo "Update iptables..."
# Use iptables to forward traffic.
LINE_NUMBER=$(iptables -t nat -nvL --line-number | grep ${private_port} | head -n 1 | awk '{print $1}')
if [ "${LINE_NUMBER}" != "" ]; then
iptables -t nat -D PREROUTING $LINE_NUMBER
fi
iptables -t nat -I PREROUTING -p tcp --dport $private_port -j DNAT --to-destination $qb_web_host:$public_port
echo "Done."
|
非常感谢这位大佬提供的脚本,这个脚本原理非常简单主要做了两件事。
- 修改qbittorrent内部端口为打洞后的公网端口
- 路由器重定向本机内部映射端口的流量到qbittorrent修改后的新内部端口。
这样说可能说的不太清楚,举个例子。
打洞前:192.168.1.8:12345(qbittorrent)<->192.168.1.1:12345(路由器)<->公网:未知端口(这里我也不太清楚)
打洞后:192.168.1.8:18888(qbittorrent修改端口后)<->路由器内部重定向访问本机12345端口的流量到qbittorrent主机的18888端口<->192.168.1.1:12345(路由器natmap内部映射端口)<->公网:18888(外部映射端口)
wireguard服务
打洞教程建议直接看natmap的wiki教程,所以我不讲怎么配置了,这里主要讲下过程中我遇到的几个问题。
ip4p-ddns
这里困扰我的是脚本中的RECORD变量不知道怎么获取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #!/bin/sh
ZONE=''
RECORD=''
EMAIL=''
AUTH=''
DOMAIN=''
IP4P=${3}
while true; do
curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE}/dns_records/${RECORD}" \
-H "X-Auth-Email: ${EMAIL}" \
-H "Authorization: Bearer ${AUTH}" \
-H "Content-Type:application/json" \
--data "{\"type\":\"AAAA\",\"name\":\"${DOMAIN}\",\"content\":\"${IP4P}\",\"ttl\":60,\"proxied\":false}" > /dev/null 2> /dev/null
if [ $? -eq 0 ]; then
break
fi
done
|
经查看 Cloudflare API Documentation 明白这是dns记录的id,然后这个帖子 Where do I find my dns_record_id in Cloudflare? 写了如何获取。
先去网页手动创建一个dns记录随便填,替换ZONE_ID和YOUR_API_TOKEN后执行下面命令就能获取域名dns记录相关信息,然后找到对应的id。
1
2
3
| curl -X GET "https://api.cloudflare.com/client/v4/zones/[ZONE_ID]/dns_records" \
-H "Authorization: Bearer [YOUR_API_TOKEN]" \
-H "Content-Type: application/json"
|
访问其它内网段
部署好能通过外网访问后,想通过接入wireguard的主机,访问家里其它局域网里的设备,发现访问不了。
例:家里的内网段是10.0.8.0/24,wireguard虚拟内网段是10.0.9.0/24。
10.0.9.3(手机)通过wireguard和10.0.9.2(旁路由)连通,然后尝试访问在10.0.8.0/24(家里的内网段)的设备失败。注:wg配置文件中AllowedIPs已允许10.0.8.0/24网段。
于是我想是不是跨网段的问题需要做nat,由于不会写防火墙规则,以下代码由chatgpt生成。
PostUp运行的命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 创建 filter 表和 forward 链
nft add table inet filter
nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
# 允许来自 wg0 的流量转发到 eth0
nft add rule inet filter forward iif "wg0" oif "eth0" accept
# 允许来自 eth0 的返回流量(已建立连接或相关流量)
nft add rule inet filter forward iif "eth0" oif "wg0" ct state established,related accept
# 创建 nat 表和 postrouting 链
nft add table ip nat
nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
# SNAT: 将源地址为 10.0.9.0/24 的流量源 IP 修改为 eth0 的 10.0.8.2
nft add rule ip nat postrouting ip saddr 10.0.9.0/24 ip daddr 10.0.8.0/24 snat to 10.0.8.2
# 创建 prerouting 链,用于处理入站流量
nft add chain ip nat prerouting { type nat hook prerouting priority 0 \; }
# DNAT: 将目的地址为 10.0.8.2 的流量转发到 wg0 接口的 10.0.9.2
nft add rule ip nat prerouting ip saddr 10.0.8.0/24 ip daddr 10.0.8.2 dnat to 10.0.9.2
|
PostDown运行的命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| # 删除来自 wg0 到 eth0 的规则
nft delete rule inet filter forward iif "wg0" oif "eth0" accept
# 删除来自 eth0 到 wg0 的已建立连接相关的规则
nft delete rule inet filter forward iif "eth0" oif "wg0" ct state established,related accept
# 删除 forward 链
nft delete chain inet filter forward
# 删除 filter 表
nft delete table inet filter
# 删除 SNAT 规则
nft delete rule ip nat postrouting ip saddr 10.0.9.0/24 ip daddr 10.0.8.0/24 snat to 10.0.8.2
# 删除 DNAT 规则
nft delete rule ip nat prerouting ip saddr 10.0.8.0/24 ip daddr 10.0.8.2 dnat to 10.0.9.2
# 删除 postrouting 链
nft delete chain ip nat postrouting
# 删除 prerouting 链
nft delete chain ip nat prerouting
# 删除 nat 表
nft delete table ip nat
|