偷天换日:屏蔽光猫的IP地址自动分配
1. 背景
在之前的文章[1]中,笔者苦于安卓对IPv6的支持不佳,所以在手机已root的情况下使用tasker应用+命令行让安卓设备连接指定wifi后禁用IPv6。但这种方案并不完美:
- 首先需要保证tasker应用始终在后台运行(笔者会定时进入清空后台的深度省电模式)
- 其次tasker并不能保证每次都禁用IPv6成功(可能和笔者选择只运行一条命令有关)
所以笔者的目光还是转向了更为彻底的解决思路:屏蔽光猫的IP地址自动分配功能,从而让安卓不使用IPv6网络。考虑到笔者并不对光猫有完全的控制权,所以笔者主要从无线AP上入手。
2. IP地址自动分配原理
2.1 IPv4
局域网内的IPv4地址普遍使用DHCP协议来进行自动分配。按照维基百科[2]的描述,DHCP是一个使用UDP协议的应用层协议,其使用端口为67/68的UDP协议。通过wireshark抓包,我们可以很容易发现它的存在:
2.2 IPv6
局域网内的IPv6地址可以通过两种方式自动分配:有状态的DHCPv6[3]、无状态的SLAAC[4][5]。出于配置的便捷性考虑,目前使用后者的设备更为常见,包括笔者的光猫。除了上一篇文章[1]引用的资料[6],另一篇文章也[7]用动图很好地描述了SLAAC分配地址的过程。
SLAAC使用的是网络层的ICMPv6协议,同样,我们可以用Wireshark来发现它的存在:
3. 施工
3.1 替换IPv4 DHCP
笔者通过搜寻得知,部分可配置交换机上有一个叫DHCP snooping[8]的功能,可以屏蔽恶意DHCP服务器。继续搜寻得知,Linux上可以使用ebtables
实现类似的效果[9]:
1 |
|
ebtables
[10]是一个能控制网桥中以太网帧流量的工具。刚好笔者的无线AP是一个运行着Padavan(嵌入式linux系统)的路由器,也可以使用该工具。于是笔者在无线AP上运行如下命令,即可屏蔽来自光猫的IPv4 DHCP服务器:
1 |
|
在无线AP上启用DHCP服务器后,网络架构变成了下面的形式,这样笔者就不需要手动设置透明代理网关了:
3.2 屏蔽IPv6 SLAAC
屏蔽SLAAC协议的核心是屏蔽ICMPv6协议,而ebtables
作为能控制以太网帧的工具应该也能做到。虽然ebtables
的man page[10]页面没有说明如何屏蔽该协议,但神奇的是笔者在Azure的代码仓库内[11]找到了对应的使用例子:
1 |
|
于是笔者在无线AP上运行如下命令,即可屏蔽来自光猫的ICMPv6数据包:
1 |
|
不过虽然此时安卓设备无法通过光猫获取到IPv6地址,但有线连接无线AP的AIO主机依然能正常获取IPv6地址,笔者推测这和无线AP的特殊软硬件设置有关。至此,笔者的改造完美达到目标,家庭网络架构变成了这种形式:
无IPv6、自动设置透明代理网关,笔者又能顺畅地使用安卓设备了。
4. 后记
如果对光猫拥有完全的控制权,在光猫上开启桥接模式、让个人的路由设备进行拨号可能才是最完善的解决方案。特别是如今家用宽带已经开始分配公网IPv6网段,如果能用合理设置防火墙,笔者的AIO主机就能直接在公网提供服务。希望这一天能早日到来。
引用
- 2022-12-17-安卓对指定WiFi禁用IPv6 ↩
- 动态主机设置协议 - 维基百科,自由的百科全书 ↩
- DHCPv6 - Wikipedia ↩
- IPv6 - Wikipedia ↩
- IPv6 address - Wikipedia ↩
- IPv6系列基础篇(下)—邻居发现协议NDP - 锐捷网络 ↩
- IPv6 Stateless Address Auto-configuration (SLAAC) | NetworkAcademy.io ↩
- DHCP snooping - 維基百科,自由的百科全書 ↩
- linux - iptables dhcp snooping - Unix & Linux Stack Exchange ↩
- ebtables(8) - Linux man page ↩
- azure-container-networking/ebtables.go at v1.4.39 · Azure/azure-container-networking ↩