自宅网络改造计划:换光猫,用Mikrotik改VLAN、连PPPoE,拯救固话,等等

自宅网络改造计划:换光猫,用Mikrotik改VLAN、连PPPoE,拯救固话,等等

目录

  • 缘起
  • 换光猫
    • 光通讯入门
    • 选择ONU
    • 注册新光猫
  • 配置Mikrotik路由器上网
    • VLAN设置
    • PPPoE拨号
    • IPv6地址配置
  • 拯救固话
  • 结语

缘起

自从我开始回家网课养生,对我们家的网络质量提出了越来越高的要求。所以,在把家里唯一一台路由器换成每个房间一个无线AP,通过AC实现无缝漫游后,我终于把魔爪伸向了藏在脏兮兮弱电箱里的光猫。

起初是因为光猫跟路由器连接以后,以太网口速度总是协商不到千兆(1000M),让我怀疑怀疑是网线坏了。重新做了网线以后依然协商不到千兆。我才明白,这个2011年的华为HG8110F的LAN口是百兆的。虽然说家里之前宽带买的也一直是百兆的,所以速度上不去不能怪光猫。但是不换成千兆光猫,以后升级宽带套餐都没法升级。所以说,换吧。

脏兮兮的华为HG8110F

家里人虽然对我一通操作表示存疑(“我俩平时就看看小米电视也不觉得卡啊你别给玩儿坏了”),但是还是帮我打电话叫了中国移动的安装师傅来看看。从打电话到师傅来还不到15分钟,速度令人称奇。结果来了后师傅给我当头一棒:换光猫可以,但是你们家固定电话别想要了。之前,我们家的固话是插在光猫的电话口上的。师傅说,新的光猫不支持电话业务(虽然我看上面也有一个电话口)。他劝我,这都1202年了,正经人谁还继续用固话呀!意思是赶紧让我们家赶紧取消固话,移动可能过几年就要把我们小区固话给停了。

劝家里人停掉固话废了大力气。我连哄带骗算是把工作做通了了。可是再叫师傅上门,我定睛一看他的光猫,质感极其塑料,生产厂商“烽火通讯XXXX”,孤陋寡闻的我没听说过。插上去以后一通操作猛如虎,配置从移动自动下发,无法改桥接,无法改DHCP,无IPv6,什么都没有。我大呼上当,把师傅和他的新光猫劝了回去。

现在,弱电柜门前就一台华为百兆GPON ONU HG8110F,一台Mikrotik hEX S路由器,一地鸡毛和一个我。就看我孤身一人怎么表演这场换光猫大戏了。

换光猫

移动的光猫我不想用,那就只能自己买新光猫了呗。我一开始想得很简单,不就是整个能把光信号转换成电信号的玩意儿,简单!我的Mikrotik上就有一个SFP口。我只要买一个SFP光模块,把光纤插进去不就齐活儿了。可事情没这么简单。

SFP光模块长这样,图源wiki
  1. 光通讯入门

首先,各大运营商光纤入户,跟我以前接触过的“园区里两个交换机用一根光纤直连”这种简单场景还不一样。一个小区里这么多人家,不可能是每家一根光纤跟ISP直连。大家都见过小区里藏在角落的光纤盒,里面实际上是一根光纤,物理上“分出好几根”(Passive Optical Splitter)[1],每一根进入一户人家。这种设计叫做被动光纤网络(PON,Passive Optical Network)。而既然上游是一根光纤,那么一个时刻只有一个Client能够使用这个链路,剩下挂在同一条光纤上的各位都只能干等着。协调上游设备跟下游设备们的通讯需要分时复用技术(TDMA)。于是ITU-T把大家凑到一起,设计了GPON协议[2],用来满足诸如光纤入户这种FTTP(Fiber-To-The-Premises)服务。值得注意的是GPON还有个亲戚叫EPON,两种协议不一样,很多设备无法同时兼容两种。

PON网络图示。从OLT出来的光纤被无源分束器分成若干路。

而一般园区网络常见的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状态,无法通讯。

ONT注册上限过程。画红框的是ONT从O1到O5几个状态。


因此,如果想要自己更换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在速度上的提升没有意思。

Mikrotik hEX S的Block diagram。原本从switch到CPU是2Gbps,插上SFP后,变为1Gbps。

于是,我决定买光猫了。选择光猫的话,我不想用运营商那些奇奇怪怪功能花里胡哨的玩意儿。我只想选择一个能改各种认证参数的小盒子。经过简单搜索,我最终把目标锁定到TP-LINK TL-GP110[9]

TP-LINK TL-GP110

3. 注册新光猫

首先是登录旧光猫把认证参数拿到手。在HG8110F上,ONT认证部分可以看到,除了设备SN号以外其他地方都是空着的。说明ISP采用的是SN认证。其实在移动的师傅上门的时候,我已经打听到了,10年前我们家光纤入户的时候,ONU还是用的SN认证;而现如今,新安装的光猫已经都是采取LOID进行认证了,然后就是喜闻乐见的TR-069配置自动下发。

某鱼上30块到手的TL-GP110

插上我咸鱼二手购得的TL-GP110,在设备信息里把SN填进去,瞬间就认证成功,可谓是真快。但是,我不知道移动的TR-069怎么设置,也不想(不能)让移动自动下发配置。因此VLAN设置就需要自己上手了。

将旧光猫的SN填入TL-GP110

配置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的工作落在了路由器上。

TL-GP110中的VLAN设置,我选择了透传模式(Bridge)

在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规则都没有改动的话,现在就已经可以通过路由器上剩下的网口上网了。

检查pppoe-out1口中有数据流


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注册自己。

原来的VoIP的WAN口配置

现在我需要他通过LAN口访问ISP,于是我把信令端口改成br0(LAN口)。

VoIP(语音)业务配置,信令端口改成了br0

既然是通过IP注册到ISP,我需要保证HG8110F的LAN端(br0接口)的IP地址和原来的一致。可是好巧不巧,

LAN地址的设置十分简陋

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业务已经注册成功啦!

VoIP业务注册成功啦

然而,这个方法最大的问题在于,由于ip是我手动配置的,每次只要这个小家伙断电重启,我们必须卷土重来。Linux上用expect可以写一个脚本来解决这个问题。前文给出的链接[10]中介绍了手工修改HG8110F的配置文件的方法。在配置文件里搜索我们设置的IP地址,可以发现后面还有个选项,就是子网掩码。在这里修改了子网掩码并且保存配置,可以省下以后手动修改网段的难题。但是路由还是要手动配置。这也是没有办法的事情。

结语

折腾了这么半天,我终于能在千兆互联网的大路上驰骋,开启我美好的网上冲浪新一天啦!

最后附上Mikrotik的接口设置全家福。

Mikrotik的接口设置全家福

参考

  1. ^https://www.senko.com/literature/Optical%20Splitter%20Whitepaper_02.pdf
  2. ^https://en.wikipedia.org/wiki/G.984
  3. ^https://forum.huawei.com/enterprise/en/the-process-for-an-onu-to-go-online-gpon-technical-posts-12/thread/462895-100181
  4. ^https://wenku.baidu.com/view/dc53596da45177232f60a278.html
  5. ^https://github.com/torvalds/linux/blob/master/drivers/net/phy/sfp.c
  6. ^https://github.com/opencomputeproject/oom
  7. ^https://forum.mikrotik.com/viewtopic.php?t=116364
  8. ^https://i.mt.lv/cdn/product_files/RB760iGS-dsw_180523.png
  9. ^https://www.tp-link.com.cn/product_278.html
  10. ^abhttps://blog.csdn.net/LinSeeker85/article/details/88879336
发布于 2021-05-29 17:34