通过手机4G为局域网引入原生IPv6网络地址

3G/4G移动网络已经走在了IPv6建设的前沿,本人在全国各地出差发现,各地的三大运营商网络已经均可以分配到全局单播IPv6地址(IPv4都是10.xx.xx.xx的局域网地址),一般以2408开头。也就是说,当你在使用手机4G上网的时候,已经成功的使用双栈网络了,还是公网地址。虽然目前各大网站对IPv6的支持均不行,百度的IPv6站连图片都显示不出来,只能做个搜索。但是随着网络发展,我们在升级的IPv6的同时需要原生IPv6环境进行开发和测试。

由于手机4G网络已经可以获得全局IPv6公网地址,而且你会发现,当用不是很旧的苹果或者安卓手机当作热点分享wifi的话,那么连接此wifi的设备也能获得一个/64的公网全局IPv6地址,所以我们知道了,运营商分配给你的手机是子网是/64的,你还可以通过IPv6的SLAAC协议,通过NDP和路由器通告功能向以太网内通告一个/64的前缀,连接你分享wifi的设备通过IPv6的地址自动配置就可以给自己生成一个全局的公网IPv6地址,然后可以从另一个地方的IPv6站点直接ping通该设备,并做点对点的通信。神马Upnp,神马NAT都是浮云

很多企业内部从运营商那里拉来的商用线路,往往只提供了一个固定的IPv4地址,运营商没有给IPv6地址,此时开发们想要在IPv6下测试,就可以通过一个安卓手机,一台ubuntu电脑来实现了。分分钟把网络搞成双栈的。而且最近几年流量特别便宜,还有很多无限流量的套餐可以选择,成本非常低。下面就介绍一下如何通过一台安卓手机和一个电脑为现有以太网制作一个原生IPv6网络。

首先使用的安卓手机不能太久,至少Android 6.0以上,性能没有要求,然后准备一张4G手机卡插进去,用手机浏览器访问一下test-ipv6.com,如果能得到10/10得分,那么你的手机就是支持IPv6的。也可以看下手机被运营商分配的地址,小米手机通过 ”设置“-全部参数-状态 就可以看到

通过手机4G为局域网引入原生IPv6网络地址_第1张图片

然后我们需要在手机上打开USB网络,小米手机在 设置-更多链接方式-USB网络共用,把开关打开

通过手机4G为局域网引入原生IPv6网络地址_第2张图片

这样,把手机通过数据线插到电脑上之后,不仅能浏览手机里的照片,还可以发现多出了一块网络适配器

通过手机4G为局域网引入原生IPv6网络地址_第3张图片

查看一下这个网络的状态,发现就如同连接手机分享的wifi热点一样,该适配器已经获得了一个全局IPv6地址和一个内网IPv4地址,如果你的电脑没有接别的网络的话,就可以通过这个适配器正常上双栈网了。

通过手机4G为局域网引入原生IPv6网络地址_第4张图片

此时我们插手机的这个电脑已经双栈了,但是我们想要让交换机上的局域网也双栈,换句话说就是实现4G转有线然后接到交换机上,该如何做呢? 其实不难,我们只需要把这块NDIS网卡通过电脑内部桥接到有线网卡上就可以了,windows有桥接功能,linux也有,但是Linux里面有iptables和ebtables工具,可以过滤IPv4流量,windows不行,具体原因后面讲,所以下面使用Ubuntu18.04系统为例,其他版本的linux功能几乎一模一样。

关于Ubuntu系统,可以使用虚拟机也可以使用物理机,这个随意,为了演示方便我这里使用的是Virtual Box虚拟机。

首先建立一个虚拟机,在网络选项中配置两块网卡,一块桥接手机的NDIS适配器,一块桥接有线网卡,相当于在一个ubuntu电脑上接了手机网络和有线网络,如下图。

通过手机4G为局域网引入原生IPv6网络地址_第5张图片

注意混杂模式要选择”全部允许“否则SLAAC协议下的路由器通告和NDP无法顺利传出,这样就不能自动获得IPv6地址了。

通过手机4G为局域网引入原生IPv6网络地址_第6张图片

然后我们进入ubuntu系统,使用brctl工具在虚拟机内部进行桥接,让两块网卡的流量通过我们的linux虚拟机进行传输,方便抓包和拦截。

为了建立网桥,我们首先要把ubuntu里面的两块网卡的IP地址都去掉,去掉所有自动分配的地址和手动地址,在图形界面下就是操作右上角点关闭,如下图

通过手机4G为局域网引入原生IPv6网络地址_第7张图片

此时执行ifconfig看到的两块网卡应该是活动的且没有地址的,如果还有,可以通过命令去除,并且关闭NetworkManager服务

sudo ifconfig enp0s3 0
sudo ifconfig enp0s8 0

通过手机4G为局域网引入原生IPv6网络地址_第8张图片

此时我们需要安装bridge-utils来使用brctl命令

sudo apt install bridge-utils

然后我们有两个方式来建立br0网桥,第一种是命令行式,如下

sudo brctl addbr br0
sudo brctl addif br0 enp0s3 enp0s8
sudo ifconfig br0 up

这样,一个网桥就桥接上了enp0s3网卡和enp0s8网卡,然后工作了。此时所有的二层和二层以上的协议都会流经网桥,把有线网卡连接的交换机和手机共享的网络连接成为通一个局域网,然后有线交换机上连接的设备服务器都可以通过SLAAC和DHCPv4获得公网IPv6地址和内网IPv4地址,共享手机的流量了。

此时正常情况下网桥br0只做桥,ubuntu本机是没有获得手机分配的地址并且上网的,我们可以打开DHCP或者通过ifconfig命令配置br0的IP地址,让本机也上网。推荐用dhcp,命令如下

sudo brctl STP br0 on
sudo dhclient br0

同样,也可以使用配置文件,同样先把两块物理网卡的IP去除,然后编辑/etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto enp0s3
iface enp0s3 inet manual 

auto enp0s8
iface enp0s3 inet manual 

auto br0
iface br0 inet dhcp dhcpv6
bridge_ports enp0s3 enp0s8
bridge_stp off
bridge_fd 0

然后使用ifup命令就可以启动br0,然后系统会根据dhcp自动为br0设置地址,因为上面我们开启了DHCP

alex@alex-VirtualBox:~$ sudo ifup br0
[sudo] alex 的密码: 

Waiting for br0 to get ready (MAXWAIT is 2 seconds).
Internet Systems Consortium DHCP Client 4.3.5
Copyright 2004-2016 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/br0/08:00:27:51:04:60
Sending on   LPF/br0/08:00:27:51:04:60
Sending on   Socket/fallback
DHCPDISCOVER on br0 to 255.255.255.255 port 67 interval 3 (xid=0x22f2e026)
DHCPREQUEST of 192.168.42.183 on br0 to 255.255.255.255 port 67 (xid=0x26e0f222)
DHCPOFFER of 192.168.42.183 from 192.168.42.129
DHCPACK of 192.168.42.183 from 192.168.42.129
bound to 192.168.42.183 -- renewal in 1437 seconds.
alex@alex-VirtualBox:~$ ifconfig
br0: flags=4163  mtu 1500
        inet 192.168.42.183  netmask 255.255.255.0  broadcast 192.168.42.255
        inet6 fe80::a00:27ff:fe51:460  prefixlen 64  scopeid 0x20
        ether 08:00:27:51:04:60  txqueuelen 1000  (以太网)
        RX packets 55  bytes 4722 (4.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 81  bytes 9431 (9.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s3: flags=4163  mtu 1500
        ether 08:00:27:5f:16:64  txqueuelen 1000  (以太网)
        RX packets 269  bytes 32355 (32.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 319  bytes 39347 (39.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163  mtu 1500
        ether 08:00:27:51:04:60  txqueuelen 1000  (以太网)
        RX packets 1485  bytes 1461277 (1.4 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 925  bytes 113480 (113.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1000  (本地环回)
        RX packets 2315  bytes 176917 (176.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2315  bytes 176917 (176.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

启动之后我们发现br0上成功获取到了手机分配到的2408:开头的公网IPv6地址

然后此时我们观察我们电脑的有线网卡,因为在虚拟机里被桥接到NDIS适配器的原因,也被手机分配的IPv4地址和IPv6地址,该有线网卡分配的地址和NDIS适配器的地址不同,但是网络前缀是一样的

通过手机4G为局域网引入原生IPv6网络地址_第9张图片

此时我们在有线网卡的RJ45接口插入网线,另一端插入交换机,此时就完成了4G转有线的动作。相比于市面上销售的4G转有线路由器,他们大部分都不支持IPv6,我们通过Ubuntu支持了IPv6的地址无状态自动发现。

下图是局域网内的CentOS6服务器自动分配到的地址,2408:开头的公网IPv6全局地址,注意在IPv6配置中,自动(Automatic)和DHCP是两码事,”自动“一般是采用SLAAC和PD,接受路由器通告的/64前缀,然后通过无状态协议根据网卡MAC地址自动配置IPv6主机地址,而DHCP则需要局域网内部有DHCP服务器,分配的一般是有状态的/128地址。小米手机USB和热点共享的网络使用的是前者,也是IPv6较为提倡的方式,再通告模式下,不需要DHCPv6服务器,只需相邻主机互相通告即可,DNS地址和网关地址也是通告发现的,所以会看见上图Windows下IPv6的默认网关是fe80开头,这并不代表没有网关,而是网关通过组播的方式进行寻找,没有了路由器的概念。

通过手机4G为局域网引入原生IPv6网络地址_第10张图片通过手机4G为局域网引入原生IPv6网络地址_第11张图片

通过手机4G为局域网引入原生IPv6网络地址_第12张图片

如果发现桥接之后外部的设备不能自动获得IPv6和IPv4地址,那么关一下ubuntu的ufw防火墙试试

sudo ufw status
sudo ufw disable

如果是CentOS系统,那么就关闭selinux

setenforce 0

顺便再开启内核IPv6转发(不开应该也可以,因为上面配置的是二层网桥)

sysctl -w net.ipv6.conf.all.forwarding=1

做到这里其实还没有做完,因为我们虽然把手机热点通过有线引到原有局域网内了,但是原来的局域网里也许本来就能上网,原先就能使用DHCPv4分配IPv4地址,这样接入进来两个网络不就冲突了嘛,假设原来自动分配的IP是192.168.1.xxx,现在自动分配的IP是192.168.42.xxx,那么虽然IPv6分配不会出什么乱子,但是IPv4分到哪个网段就随缘了。更麻烦的问题是,如果局域网的设备分到了手机的IPv4网段,那么网关的也是手机的,这样的电脑上网全走的4G流量,话费是很可怕的。所以我们只想让手机给我们提供原生IPv6网络,IPv4还走原来局域网里的路由器就好。但是在小米手机的”USB网络共享“配置里没找到相关设置选项,光有一个开关,所以需要我们在网桥上动手脚。

由于我们使用的是Linux,可以通过内核对网桥转发的数据包做拦截或者NAT,此时由于Ubuntu 18.04默认没有开启bridge-nf内核模块,iptables是嗅探不到二层的也就是网桥上的数据包的,但是可以通过ebtables进行过滤(甚至是NAT,镜像接口都可以),此时我们Ubuntu主机实际上变成了一台”透明防火墙“。

sudo apt install ebbridges

由于我们只想让局域网中的IPv6请求通过宝贵的手机流量发送出去,所以我们一步到位,把所有的IPv4流量都禁掉。或者把DHCPv4的UDP 67,68端口封掉,或者全部UDP流量都禁掉。这样局域网内的其他设备就分配不到手机的IPv4地址,乖乖从原来的路由器上IPv4网。命令很粗暴简单,如下:

#封禁所有UDP流量
sudo ebtables -A FORWARD -i enp0s8 -p ipv4 --ip-proto 17 -j DROP
#封禁所有IPv4流量
sudo ebtables -A FORWARD -i enp0s8 -p ipv4 -j DROP

要注意的一点是,-i后面指定的网卡要为物理网卡,也就是上面的enp0s8,enp0s3,最好-i 和-o分别都封禁一次,但是封禁br0是不会有效果的,因为br0相当于只封禁到达Ubuntu本机的数据帧,没有过滤掉enp0s8和enp0s3中目标地址不是本机的数据帧。

此时,局域网内的其他电脑和服务器就不会分配到手机分享的IPv4地址了,只能获取到IPv6的地址,DNS和网关,对比如下

蓝线上方为封禁前,蓝线下方为封禁后

通过手机4G为局域网引入原生IPv6网络地址_第13张图片

当局域网内没有其他路由器提供DHCPv4的地址分配服务,那么内网设备就只能收到手机分配的IPv6全局单播地址,换句话说你的服务器就IPv6 Only啦。如果局域网内原来就有IPv4的路由器,那么还可以像原来一样获取IPv4地址并且上网,只是在原来基础上支持了IPv6上网,你的服务器变成了双栈服务器。

在IPv6 Only环境下,很多网站都是上不去的,国内应用环境支持IPv6太弱了,甚至在APP图标上标着IPv6的运营商营业厅APP也无法在IPv6 only环境下使用,目前可以去ipv6.baidu.com上看看,但是只能搜索不能展示图片,也许因为图片是IPv4 CDN的缘故吧。

注意,如果仅通过手机分配的IPv6,没有IPv4的话,windows和linux由于默认DNS都是IPv4的DNS,可能会出现能ping通公网IPv6地址但访问域名失败的情况,此时将IPv4关掉就能正常使用手机通告的IPv6DNS了,实在不行可以使用公网上的IPv6 DNS,如240c::6666这也是我发现最好记的一个了。可以在查之前ping6一下这个地址,验证IPv6是否通畅。如下图,在CentOS6通过NetworkManager开启IPv4 DHCP情况下,默认使用IPv4 DNS,导致ping域名失败,但是手工指定IPv6地址或者IPv6 DNS服务器就可以解决这个问题。

通过手机4G为局域网引入原生IPv6网络地址_第14张图片

或者在IPv6 only的环境下关闭IPv4的配置也可以解决问题

通过手机4G为局域网引入原生IPv6网络地址_第15张图片

windows关闭方法如下

通过手机4G为局域网引入原生IPv6网络地址_第16张图片

你可能感兴趣的:(通过手机4G为局域网引入原生IPv6网络地址)