[Linux]基于Linux + 无线网卡实现IP栈切换
待测组网
网络支持双栈:可以支持IPv4和IPv6类型的ip地址访问
网络只支持IPv4协议:只支持IPv4地址访问
网络只支持IPv6协议:只支持IPv6地址访问
网络协议未知:只用域名访问
网络存在DNS劫持
背景信息
公司wifi仅有ipv4,测试“IPv6 Only”或“双栈”需要NAT64/DNS64 转换
测试仅域名访问网络需要构造代理。
测试网络拓扑(精简)
环境准备:
物理网络:
ens160:上行网络
wlx40a5ef59b748:供测试机连接的AP

逻辑网络:
ipv4测试网关:10.42.0.1
ipv6测试网关:fd00::1
NAT64网关:192.168.255.1
NAT64转换前缀:64:ff9b::/96:当手机想访问 IPv4 的 8.8.8.8 时,会基于转换前缀把目标伪装成 64:ff9b::0808:0808。
驱动无线网卡
如果免驱,会直接识别,这里显示rtw_8822bu是不免驱的,需要手动安装驱动


方法1:使用apt安装dkms驱动包
sudo apt update
apt search rtl8822bu
apt search rtl88x2bu


没有找到rtl8822bu专用驱动,但是找到了通用的驱动 firmware-realtek
sudo apt install firmware-realtek
sudo iw list|grep Supported interface modes
安装后使用iw list验证,支持AP模式作为热点使用

方法2:源码编译
仓库地址:https://github.com/morrownr/88x2bu-20210702
# 安装构建环境
sudo apt update
sudo apt install -y build-essential dkms git bc linux-headers-$(uname -r)
# 克隆 morrownr 的 8822bu 仓库
git clone https://github.com/morrownr/88x2bu-20210702.git
cd 88x2bu-20210702
# 运行安装脚本 (会自动处理 DKMS)
sudo ./install-driver.sh
构造四种网络栈
安装依赖
sudo apt update
sudo apt install tayga unbound tinyproxy
Tayga (NAT64)
Unbound (DNS、DNS64)
tinyproxy(本地代理,用于屏蔽非域名)
基础配置
开启系统转发
sudo vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
使之生效
sudo sysctl -p
配置 Tayga (NAT64)编辑配置文件
sudo vim /etc/tayga.conf
tun-device nat64
ipv4-addr 192.168.255.1
ipv6-addr fd00::1
prefix 64:ff9b::/96
dynamic-pool 192.168.255.0/24
data-dir /var/spool/tayga
sudo systemctl edit tayga
在[Service]部分填入以下内容:
[Service]
ExecStartPost=/usr/bin/ip link set nat64 up
ExecStartPost=/usr/bin/ip addr add 192.168.255.1 dev nat64
ExecStartPost=/usr/bin/ip addr add fd00::1 dev nat64
ExecStartPost=/usr/bin/ip route add 192.168.255.0/24 dev nat64
ExecStartPost=/usr/bin/ip route add 64:ff9b::/96 dev nat64
启用并启动 Tayga:
# 启动并设置开机自启
sudo systemctl enable --now tayga
sudo systemctl restart tayga
# 检查状态
sudo systemctl status tayga
ip addr show nat64

NAT64出网伪装
Tayga 将 v6 转为 v4 后,流量源IP是 192.168.255.x,必须做一次伪装才能通过物理网卡 ens160 上网。
# 临时生效
sudo apt install iptables iptables-persistent
#将source为192.168.255.0/24且output device为ens160的数据包的源IP地址,伪装为ens160 接口当前的 IP 地址
sudo iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -o ens160 -j MASQUERADE
# 持久化建议:安装 iptables-persistent
sudo netfilter-persistent save
配置 DNS和DNS64
sudo vim /etc/unbound/unbound.conf.d/dns64.conf
监听:
interface: 127.0.0.1
interface: 192.168.255.1
interface: fd00::1
的53端口
server:
verbosity: 1
interface: 127.0.0.1
interface: 192.168.255.1
interface: fd00::1
port: 53
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
# 允许局域网访问
access-control: 0.0.0.0/0 allow
access-control: ::0/0 allow
# DNS64 模块
module-config: "dns64 iterator"
dns64-prefix: 64:ff9b::/96 # 必须与 tayga.conf 的 prefix 一致
forward-zone:
name: "."
# 上游 DNS,可以使用阿里云或 Google
forward-addr: 223.5.5.5
forward-addr: 8.8.8.8
重启unbound:
sudo systemctl restart unbound
sudo systemctl status unbound
验证本地DNS64解析v6地址
dig @127.0.0.1 baidu.com AAAA +short

Test_IPv4_Only网络
除启停外的配置命令,仅需执行一次
export WLAN="wlx40a5ef59b748"
sudo nmcli con add type wifi ifname $WLAN con-name Hotspot_v4 autoconnect no ssid "Test_IPv4_Only"
sudo nmcli con modify Hotspot_v4 802-11-wireless.mode ap wifi-sec.key-mgmt wpa-psk wifi-sec.psk "12345678"
sudo nmcli con modify Hotspot_v4 ipv4.method shared ipv6.method ignore
#如果你是用的是三星手机,需要关闭pmf
sudo nmcli con modify Hotspot_v4 wifi-sec.pmf disable
#启动ap
sudo nmcli con up Hotspot_v4
#关闭ap
sudo nmcli con down Hotspot_v4

fe80:IPv4中的链路地址169.254.x.x,未获取DHCP地址时的本地地址。


使用本地dns解析对比,结果一致

手机端的localdns解析也正确
Test_IPv6_Only网络
除启停外的配置命令,仅需执行一次
export WLAN="wlx40a5ef59b748"
sudo nmcli con add type wifi ifname $WLAN con-name Hotspot_v6 autoconnect no ssid "Test_IPv6_Only"
sudo nmcli con modify Hotspot_v6 802-11-wireless.mode ap wifi-sec.key-mgmt wpa-psk wifi-sec.psk "12345678"
# 禁用 IPv4
sudo nmcli con modify Hotspot_v6 ipv4.method disabled
# 手动 IPv6:把自己设为网关
sudo nmcli con modify Hotspot_v6 ipv6.method manual ipv6.addresses fd00::1/64 ipv6.gateway fd00::1 ipv6.dns fd00::1
sudo nmcli con modify Hotspot_v6 ipv6.method shared
# 如果连接失败,重复执行以上两条命令
#如果你是用的是三星手机,需要关闭pmf
sudo nmcli con modify Hotspot_v6 wifi-sec.pmf disable
#启动ap
sudo nmcli con up Hotspot_v6
#关闭ap
sudo nmcli con down Hotspot_v6

192.0.0.2:这是苹果为了兼容性而内置的 CLAT (Customer-side Translator) 机制,属于 464XLAT 协议的一部分。
为了防止某些老旧 App(硬编码了 IPv4 或使用旧式 Socket API)在纯 IPv6 网络下崩溃,iOS 在手机内部虚拟了一个 IPv4 接口。
网关是fe80而不是fd00:在 IPv6 的设计哲学中,网关优先使用链路地址fe80而不是子网名fd00。
验证:
# 监听无线网卡,只看 IPv4 流量
sudo tcpdump -i wlx40a5ef59b748 ip
# 监听无线网卡,只看 IPv6 流量
sudo tcpdump -i wlx40a5ef59b748 ip6
# 抓取 wlx 接口,排除多播和广播,只看发往公网的数据
sudo tcpdump -i wlx40a5ef59b748 -n "not broadcast and not multicast"

日志可见iOS通过HTTPDNS获取了v6地址

双栈网络
除启停外的配置命令,仅需执行一次
export WLAN="wlx40a5ef59b748"
sudo nmcli con add type wifi ifname $WLAN con-name Hotspot_Dual autoconnect no ssid "Test_Dual_Stack"
sudo nmcli con modify Hotspot_Dual 802-11-wireless.mode ap wifi-sec.key-mgmt wpa-psk wifi-sec.psk "12345678"
# IPv4 共享 + IPv6 手动
sudo nmcli con modify Hotspot_Dual ipv4.method shared
sudo nmcli con modify Hotspot_Dual ipv6.method manual ipv6.addresses fd00::1/64 ipv6.gateway fd00::1 ipv6.dns fd00::1
sudo nmcli con modify Hotspot_Dual ipv6.method shared
#如果你是用的是三星手机,需要关闭pmf
sudo nmcli con modify Hotspot_Dual wifi-sec.pmf disable
#启动ap
sudo nmcli con up Hotspot_Dual
#关闭ap
sudo nmcli con down Hotspot_Dual

仅域名可用网络
复用ipv4网络,额外配置tinyproxy
sudo vim /etc/tinyproxy/tinyproxy.conf
在allow部分添加
Allow 10.42.0.0/16
然后重启服务
sudo systemctl restart tinyproxy
启动IPv4_Only热点,然后在手机端手动设置代理地址为10.42.0.1:8888
本地DNS污染网络
在 IPv6 Only 模式下,劫持DNS
sudo vim /etc/unbound/unbound.conf.d/poison.conf
server:
# 定义该域名为静态区域
local-zone: "offertoday.com." static
# 强制将 A 记录解析为 2.2.2.2
local-data: "offertoday.com. IN A 2.2.2.2"
# 强制将 AAAA 记录解析为 2001:db8::1
local-data: "offertoday.com. IN AAAA 2001:db8::1"
重启unbound
sudo systemctl restart unbound
验证劫持效果

IPv4 Only 或 双栈 (Dual Stack) 网络下,劫持DNS:
使用iptables拦截来自无线网卡53端口的udp请求,转发到unbound正在监听的nat64网关192.168.255.1
export WLAN="wlx40a5ef59b748"
# 添加 NAT 转发规则
sudo iptables -t nat -I PREROUTING -i $WLAN -p udp --dport 53 -j DNAT --to-destination 192.168.255.1
sudo iptables -t nat -I PREROUTING -i $WLAN -p tcp --dport 53 -j DNAT --to-destination 192.168.255.1
#若需要持久化
sudo netfilter-persistent save
启动需要的热点
sudo nmcli con up Hotspot_*
由于我们拦截的是来自无线网卡的DNS请求,debian本机不受影响,需在手机端验证效果:
web:

app:


浙公网安备 33010602011771号