自宅网络改造计划:换光猫,用Mikrotik改VLAN、连PPPoE,拯救固话,等等
目录
- 缘起
- 换光猫
- 光通讯入门
- 选择ONU
- 注册新光猫
- 配置Mikrotik路由器上网
- VLAN设置
- PPPoE拨号
- IPv6地址配置
- 拯救固话
- 结语
缘起
自从我开始回家网课养生,对我们家的网络质量提出了越来越高的要求。所以,在把家里唯一一台路由器换成每个房间一个无线AP,通过AC实现无缝漫游后,我终于把魔爪伸向了藏在脏兮兮弱电箱里的光猫。
起初是因为光猫跟路由器连接以后,以太网口速度总是协商不到千兆(1000M),让我怀疑怀疑是网线坏了。重新做了网线以后依然协商不到千兆。我才明白,这个2011年的华为HG8110F的LAN口是百兆的。虽然说家里之前宽带买的也一直是百兆的,所以速度上不去不能怪光猫。但是不换成千兆光猫,以后升级宽带套餐都没法升级。所以说,换吧。
家里人虽然对我一通操作表示存疑(“我俩平时就看看小米电视也不觉得卡啊你别给玩儿坏了”),但是还是帮我打电话叫了中国移动的安装师傅来看看。从打电话到师傅来还不到15分钟,速度令人称奇。结果来了后师傅给我当头一棒:换光猫可以,但是你们家固定电话别想要了。之前,我们家的固话是插在光猫的电话口上的。师傅说,新的光猫不支持电话业务(虽然我看上面也有一个电话口)。他劝我,这都1202年了,正经人谁还继续用固话呀!意思是赶紧让我们家赶紧取消固话,移动可能过几年就要把我们小区固话给停了。
劝家里人停掉固话废了大力气。我连哄带骗算是把工作做通了了。可是再叫师傅上门,我定睛一看他的光猫,质感极其塑料,生产厂商“烽火通讯XXXX”,孤陋寡闻的我没听说过。插上去以后一通操作猛如虎,配置从移动自动下发,无法改桥接,无法改DHCP,无IPv6,什么都没有。我大呼上当,把师傅和他的新光猫劝了回去。
现在,弱电柜门前就一台华为百兆GPON ONU HG8110F,一台Mikrotik hEX S路由器,一地鸡毛和一个我。就看我孤身一人怎么表演这场换光猫大戏了。
换光猫
移动的光猫我不想用,那就只能自己买新光猫了呗。我一开始想得很简单,不就是整个能把光信号转换成电信号的玩意儿,简单!我的Mikrotik上就有一个SFP口。我只要买一个SFP光模块,把光纤插进去不就齐活儿了。可事情没这么简单。
- 光通讯入门
首先,各大运营商光纤入户,跟我以前接触过的“园区里两个交换机用一根光纤直连”这种简单场景还不一样。一个小区里这么多人家,不可能是每家一根光纤跟ISP直连。大家都见过小区里藏在角落的光纤盒,里面实际上是一根光纤,物理上“分出好几根”(Passive Optical Splitter)[1],每一根进入一户人家。这种设计叫做被动光纤网络(PON,Passive Optical Network)。而既然上游是一根光纤,那么一个时刻只有一个Client能够使用这个链路,剩下挂在同一条光纤上的各位都只能干等着。协调上游设备跟下游设备们的通讯需要分时复用技术(TDMA)。于是ITU-T把大家凑到一起,设计了GPON协议[2],用来满足诸如光纤入户这种FTTP(Fiber-To-The-Premises)服务。值得注意的是GPON还有个亲戚叫EPON,两种协议不一样,很多设备无法同时兼容两种。
而一般园区网络常见的SFP光模块不具备GPON协议栈,有SFP光口的设备也不会考虑GPON协议栈的问题(比如我手上这个Mikrotik)。因此买普通光模块肯定不行。GPON网络的服务端叫做OLT(Optical Line Termination),客户端叫做ONT(Optical Network Terminal)或者ONU(Optical Network Unit)。购买光模块需要购买专门标明是ONT或者ONU的模块才行。
问题在于,就算买对了ONU光模块,也不是插上去就能用。GPON协议规定了一套认证过程[3],光模块插上后需要先进行认证注册(Authentication),才能达到可以通讯的状态(在GPON协议里叫O5状态)。怎么认证呢?ONU会将自己的SN,LOID,Password等等发送给OLT,OLT核对数据库,如果数据库中有吻合的ONU条目,那么通过认证。认证不成功,ONU就会停在O3状态,无法通讯。
因此,如果想要自己更换ONU,首先就要知道旧光猫的SN,LOID(逻辑ID),Password等等到底是怎么设置的,把这些设置照搬到新ONU上,才可以通过注册!当然,ISP可能会采取SN,SN+Password,LOID,LOID+Password的组合中的一种来进行认证,因此搞清楚自己的ISP的认证参数也很重要。
2. 选择ONU
如果是换新的光猫的话好说。光猫往往提供了网页设置接口,只要访问一个链接就能设置这些参数。而GPON ONU光模块则是五花八门了。中国电信发布过一份标准[4],专门规定了怎样设置ONU光模块的LOID和Password(把他们写进SFP模块的EEPROM的某个地址)。
为了改EEPROM,我在Linux内核源码里[5]读到了改SFP的EEPROM的接口,甚至找到了一个python库[6]把调用这个接口的过程封装了起来。可惜,Mikrotik的操作系统ROS虽然是基于Linux的,但是不让用户运行自己的程序。且按照中国电信的标准,每次掉电以后都需要重新向SFP中写入LOID,让改一次一劳永逸变得不可能。
我还在Mikrotik论坛上看到了一个帖子[7],里面欧洲的geek们想方设法改写ONU SFP里面的LOID(热风枪吹掉FLASH然后读取ROM然后重新烧录,等等),最后一位小哥甚至找工厂做出了自己的ONU:那是一个光模块,插上以后可以访问一个网页(仔细一看,这不是Openwrt的Luci控制面板么!),里面有改LOID,SN,Password等一系列选项,分明是把光猫做进了一个光模块里。国内也有很多深圳华强北小厂生产这种ONU(淘宝搜索GPON Stick),价格不菲。而且据说发热严重。
所以,把ONU做进小小的光模块里,跟我直接咸鱼上买个价格是前者十分之一的二手ONU有什么区别呢?一番冥思苦想,那就是没有区别!如果纠结速度的话,要知道:SFP的速度也是~1Gbps,SFP+以上才有质的提升;Mikrotik hEX S的Block diagram里也画了[8],SFP到CPU的总线是1Gbps。所以纠结用SFP在速度上的提升没有意思。
于是,我决定买光猫了。选择光猫的话,我不想用运营商那些奇奇怪怪功能花里胡哨的玩意儿。我只想选择一个能改各种认证参数的小盒子。经过简单搜索,我最终把目标锁定到TP-LINK TL-GP110[9]。
3. 注册新光猫
首先是登录旧光猫把认证参数拿到手。在HG8110F上,ONT认证部分可以看到,除了设备SN号以外其他地方都是空着的。说明ISP采用的是SN认证。其实在移动的师傅上门的时候,我已经打听到了,10年前我们家光纤入户的时候,ONU还是用的SN认证;而现如今,新安装的光猫已经都是采取LOID进行认证了,然后就是喜闻乐见的TR-069配置自动下发。
插上我咸鱼二手购得的TL-GP110,在设备信息里把SN填进去,瞬间就认证成功,可谓是真快。但是,我不知道移动的TR-069怎么设置,也不想(不能)让移动自动下发配置。因此VLAN设置就需要自己上手了。
配置Mikrotik路由器上网
1. VLAN设置
VLAN是怎么回事?说白了就是在L2以太网包中加了一个VLAN ID字段。交换机在转发包的时候,只会把包往配置了相同VLAN的端口转发,一个端口也可以包括若干VLAN ID(叫做Trunk口)。这样,一台交换机下就可以运行两个甚至更多LAN,是不是很赚?
我的路由器上,用ether1口与光猫连接。在配置VLAN之前,所有从我路由器送入光猫LAN口的包都不包含VLAN字段(untagged)。而我之前使用的光猫就会帮我把这些包打上VLAN ID(tagged),再将这些包送给ISP。同样,ISP送回来的包也都是tagged的,由光猫untag后送出LAN口(光猫的LAN口就叫做一个Access口)。
我需要先知道ISP用的是哪个VLAN。TL-GP110贴心地提供了VLAN扫描功能,但是扫描的结果应该仅限是有PPPoE的VLAN。VoIP的VLAN还需要手动设置。其实VLAN设置我都已经从旧光猫上抄下来了。PPPoE上网的VLAN ID是10,VoIP是2014。我直接选择了VLAN透传(实际上就是Bridge模式,把光猫的LAN口从Access口变成了一个Trunk口),所以给数据包tag/untag的工作落在了路由器上。
在Mikrotik路由器的操作系统ROS里面,可以在一个物理接口上建立VLAN接口,进入这个VLAN接口的包会被tag,出来会被untag,相当于就是一个Access口。设置这个VLAN接口的VLAN ID为10。
/interface vlan add interface=ether1 name=vlan10-internet vlan-id=10
之后,我们在这个VLAN口上再建立一个PPPoE Client接口,用来拨号。
2. PPPoE拨号
设置PPPoE用户名密码
/interface pppoe-client add add-default-route=yes interface=vlan10-internet keepalive-timeout=disabled name=pppoe-out1 password=******* user=*******
确认接口都已经创建,然后monitor一下,确定PPPoE已经正确连接。
[terry@MikroTik] /interface/pppoe-client> monitor 0
status: connected
uptime: 41s
active-links: 1
encoding:
service-name:
ac-name: BJDX-PA-CMNET-*********
ac-mac: 00:00:**:**:**:**
mtu: 1480
mru: 1480
local-address: 100.89.*.*
remote-address: 100.89.*.*
检查路由表,看到往pppoe-out1口的路由已经正确添加。
[terry@MikroTik] > /ip route print
Flags: D - DYNAMIC; A - ACTIVE; c - CONNECT, v - VPN, y - COPY
Columns: DST-ADDRESS, GATEWAY, DISTANCE
DST-ADDRESS GATEWAY D
DAv 0.0.0.0/0 pppoe-out1 1
DAc 100.89.64.1/32 pppoe-out1 0
DAc 192.168.0.0/22 bridge 0
好了,如果路由器默认设置的NAT规则都没有改动的话,现在就已经可以通过路由器上剩下的网口上网了。
3. IPv6地址配置
IPv6地址的获取需要在pppoe-out1接口上添加IPv6 DHCP Client,获得ISP提供的IPv6前缀,然后设置自己的IPv6地址为“prefix::1”,
/ipv6 dhcp-client add interface=pppoe-out1 pool-name=isp-ipv6 request=prefix use-peer-dns=no
/ipv6 address add address=::1 from-pool=isp-ipv6 interface=bridge
检查Prefix已经获取到,并且路由器IPv6地址已经设置好,
[terry@MikroTik] > /ipv6 dhcp-client print
Columns: INTERFACE, STATUS, REQUEST, PREFIX
# INTERFACE STATU REQUES PREFIX
0 pppoe-out1 bound prefix 2409:8a00:*:*::/60, 2d4h17m57s
[terry@MikroTik] > /ipv6 address print
Flags: D - DYNAMIC; G - GLOBAL, L - LINK-LOCAL
Columns: ADDRESS, FROM-POOL, INTERFACE, ADVERTISE
# ADDRESS FROM-POO INTERFACE ADV
0 G 2409:8a00:*:*::1/64 isp-ipv6 bridge yes
1 DL fe80::4a8f:5aff:fe82:*/64 bridge no
2 DL fe80::4a8f:5aff:fe82:*/64 ether1 no
3 DL fe80::4a8f:5aff:fe82:*/64 vlan10-internet no
4 DL fe80::8/64 pppoe-out1 no
LAN内其他设备现在应该已经能获取到IPv6前缀并自动配置IPv6地址了。
拯救固话
其实能上网以后,我便几乎算是功德圆满了。然而TL-GP110只是一个符合unix哲学("do one thing, do it well")的简约风光猫,上面并没有电话口,不提供VoIP服务。可是我总是想挽救一下家里的固话。怎么办?我再一次把魔爪伸向可怜的华为HG8110F。
固话接到光猫上到底是怎么一回事呢?很久很久以前电话线还是直接接到小区的电话交换机上。但是在不那么久的以前,ISP们开始转用网络提供电话服务,也就是所谓的VoIP。家里的光猫将电话线(POTS)的模拟信号转换成数字信号,然后再通过网络传给ISP。
其实我之前也好奇过,为什么移动给我安装的新光猫,上面虽然有电话口但是却不能安装我们家的旧固话。虽然我觉得这是移动成心犯坏,但调研了一下以后,我意识到我们家用的旧固话用的是H.248协议(Megaco协议)。但是最近似乎SIP协议是主流。我网上查了一圈,除了华为的设备还顽强支持H.248,别的设备似乎都转投SIP的怀抱。就连电脑上的VoIP软件都没有支持Megaco的。因此考虑了一下,还是得靠这个旧光猫挽救我们家的固话。
之前已经记下来,固话的VLAN ID是2014。IP地址是静态配置的。因此,我还需要建立一个VLAN ID为2014的VLAN接口`vlan2014-voip`。之后,把HG8110F的LAN口和路由器的某个LAN口接起来(我选择的是ether4)。我创建了一个bridge,把vlan2014-voip和ether4桥接起来,让Mikrotik在他们俩中扮演一个交换机的角色。
HG8110F的设置页面中,原来VoIP是通过WAN口(也就是光口)与ISP通讯,IP地址和子网掩码和网关都是静态配置好的。HG8110F用IP地址向ISP注册自己。
现在我需要他通过LAN口访问ISP,于是我把信令端口改成br0(LAN口)。
既然是通过IP注册到ISP,我需要保证HG8110F的LAN端(br0接口)的IP地址和原来的一致。可是好巧不巧,
LAN地址的设置界面十分简陋,只能配置一个IP地址,无法配置子网掩码和网关。这种场景我见多了,这台小光猫分明就是把自己当成了网关,然后默认拿255.255.255.0,也就是/24网段作为子网。可惜时代变啦!现在它只是个从属设备。我得把子网掩码改成255.255.252.0(/22),然后还得设置个网关,这些在这个网页上怕是做不成了。
那咋整?经过一番搜索[10],我知道这小家伙身上有个telnet可以用一下。`telnet IP地址`连上去,用户名root密码admin,有够老气。我们进入了这个小光猫的一个简易shell。我需要把真正的shell召唤出来。敲`shell`回车,弹出了熟悉的BusyBox,
WAP>shell
BusyBox v1.18.4 (2013-03-26 12:11:33 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
profile close core dump, flag=
WAP(Dopra Linux) #
我试了一下,发现`ip`命令可以用,
WAP(Dopra Linux) # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether b4:15:13:d0:**:** brd ff:ff:ff:ff:ff:ff
3: br0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether b4:15:13:d0:**:** brd ff:ff:ff:ff:ff:ff
inet 172.28.xxx.xxx/24 brd 172.28.***.255 scope global br0
那就好办了,先用`ip addr`添加一个同一个网段的地址,
# ip addr add 172.28.xxx.xxy/22 dev br0@eth0
然后退出用这个新ip地址重新telnet进去,删除旧的ip地址,再配置好“/22”网段重新添加回去
# ip addr del 172.28.xxx.xxx
# ip addr add 172.28.xxx.xxx/22 dev br0@eth0
同时配置正确的路由
# ip route add 0.0.0.0/0 via 172.28.124.1
现在,再打开HG8110F的网页控制面板,我们惊喜地发现VoIP业务已经注册成功啦!
然而,这个方法最大的问题在于,由于ip是我手动配置的,每次只要这个小家伙断电重启,我们必须卷土重来。Linux上用expect可以写一个脚本来解决这个问题。前文给出的链接[10]中介绍了手工修改HG8110F的配置文件的方法。在配置文件里搜索我们设置的IP地址,可以发现后面还有个选项,就是子网掩码。在这里修改了子网掩码并且保存配置,可以省下以后手动修改网段的难题。但是路由还是要手动配置。这也是没有办法的事情。
结语
折腾了这么半天,我终于能在千兆互联网的大路上驰骋,开启我美好的网上冲浪新一天啦!
最后附上Mikrotik的接口设置全家福。
参考
- ^https://www.senko.com/literature/Optical%20Splitter%20Whitepaper_02.pdf
- ^https://en.wikipedia.org/wiki/G.984
- ^https://forum.huawei.com/enterprise/en/the-process-for-an-onu-to-go-online-gpon-technical-posts-12/thread/462895-100181
- ^https://wenku.baidu.com/view/dc53596da45177232f60a278.html
- ^https://github.com/torvalds/linux/blob/master/drivers/net/phy/sfp.c
- ^https://github.com/opencomputeproject/oom
- ^https://forum.mikrotik.com/viewtopic.php?t=116364
- ^https://i.mt.lv/cdn/product_files/RB760iGS-dsw_180523.png
- ^https://www.tp-link.com.cn/product_278.html
- ^abhttps://blog.csdn.net/LinSeeker85/article/details/88879336