本篇主要是分享这次软路由折腾的一些经历和一些坑,希望能够帮助大家在「入坑」的时候更加顺滑一些。

折腾的初衷

此前多次倒腾过软路由以及一些略进阶一些的路由(不是你想的 Disco Cisco、Juniper 啥的),但总是小小的玩一下,除了常规的网络接入并没有做太多其他的尝试。

年初拉了一条 1G/50M 的联通到房间里(是的,到床头),如果在常规的 1G 内网链路下的话,基本跑测速理想是在 920Mbps 左右,但实际各 ISP 都会给一些冗余(比如 10~30%)。这样的结果作为一个「宽带症候群患者」是难以接受的。

正好最近也切到了远程开发,把家里的游戏机 24 小时开着用也不太实际,那就放在软路由上吧。后来又弄了一条 200M 对等的线到家里,就能够满足远程开发等等的上行诉求了。

想了想可行,于是「家用垃圾网络」项目启动!

硬件

那既然如此,就整一个常规 ATX 吧。

回想起早前了解到的一个叫猫棒(PON Stick)的玩意,这货一方面能够替代光猫,另一方面的作用就是速度解锁。那这次就把光猫也给换掉吧。

那么这次达到的效果就是:光纤直接入户然后接到软路由上再出来。

常规部件

本着「以最低的成本折腾软路由」的理念,我决定做垃圾佬捡垃圾!

CPU 捡垃圾基本考虑 E5v3 或者 v4,考虑到整体成本,最终选了一个 Xeon E5 2666v3。装机是在半年前,写这篇文章的时候 EPYC Rome 的洋垃圾价格已经下来了,要是现在重选肯定是 AMD YES! 配个 H11 板子香喷喷。这边有些要特别注意的,现在国内的家宽多为 PPPoE 接入,而 pppoe-client 在实现都是走单线程所以如果你的网卡通道少 CPU 单核又差,那么很可能出现跑不过一千左右的硬路由(硬件加速)。所以尽可能的选择高主频的 U 来顶,不过当时也有拿树莓派 4B 做过强制绑定多核的情况下单通道网卡跑 500M+ NAT(未测极限)。下一台软路由我一定选 AMD

主板倒是纠结很久,一方面是稳定性另一方面是拓展性,希望能够有更多的 PCI-E 能够支撑后续的多网卡。纠结了很久,在想要不要入华南的妖板。然后一朋友说他们公司大规模采购了华南的板子来支撑一些业务,他看了用量、稳定性都还可以。那就华南 F8,4 个 PCI + 两个 M2 差不多了!如果主板想要上 ITX 并且又要多接口,可以考虑下华擎,这家也有很多妖板但就是价格比较不美丽,市场存货少。

电源倒是没啥好纠结,比较随缘,就京东上整了个航嘉的金牌非模组;内存无脑上淘宝找浦东买 DDR4 ECC 的条子(2666v3 可以兼容 DDR3,但是除了便宜没理由选 R3 啊)

硬盘这个我比较慎重,不想天天炸盘。权衡之下买了一块 P4510 4T 的 U.2 SSD 做数据盘(别买 PM4501!!!)。买这种盘就不要去信什么低写入了,全是刷的数据,找个感觉差不多的卖家买了就好了。 之所以选择 Intel 的 DCSSD 倒不是因为企业级的一些特性,是因为它相较于消费级 SSD 在大容量的情况下有省接口和价格的优势,本身接口就比较紧张,所以尽可能的大盘。你也可以考虑下 OEM 盘比如 PM981A(PCI-E 3.0) 或者 PM9A1(PCI-E 4.0,这块盘我给挺多朋友推荐过)

机箱和散热器这两个部件我尽可能选择静音、无光的,因为准备把这玩意放在床头。散热器选择利民 PA120,机箱选乔思伯 D40 因为总体会较为紧凑,布局也还不错。没有选猫扇是因为它的配色确实有点那啥,丑丑的。

显卡这波操作是真的垃圾佬了(没有核显,也没有板载所以只能买张显卡来点亮了),选了张 MATROX G550 上古显卡(2001 年的卡),空载功耗超级低(个位数,没有实测。数据也找不到了)。咸鱼上买加邮费七十多。

至此几个没啥大疑问的部件就拍下来了。

猫棒

如果你要买猫棒的话注意 PON 的类型,现在常见是 EPON 和 GPON,部分地区还会有 XG-PON(XGS-PON 应该比较少)。PON 类型看光猫信息就能知道,这个由你所在地区的局端决定的。

有两个选择,一个海鲜市场(闲鱼)买诺基亚、华为(我在最近买了两根 MA5671A,有一些散热的问题后面再提)、阿尔卡特的棒子,另一个是买比如南天、ODI 这些有一定厂家支撑的。我第一次所以选择后者省事点,验证了整体网络拓扑后面要折腾再折腾。最后是买了 ODI 的双模(EPON + GPON) 可以协商 1G(买它肯定不是为了 1G) 和 2.5G 猫棒,推荐刚入坑可以考虑这货。

下图是两根 MA5671A

网卡

2.5Gbps 协商其实是一个很尴尬的事情,它属于一个中间产物不上不下。在万兆的场景下基本是 1G、10G 选,2.5G 和 5G 真就挺尬的。所以支持它的垃圾网卡现在也不多。性价比可行的改固件卡了解到能够实现的也就是博通的 57810 和 57820 这两个芯片的卡(当然也有其他的卡拉),我选了 57810 买了个 530FLR,买的时候如果不想自己刷固件就可以让卖家帮你刷好再发(默认全 10G)。

期间我还买了一张 MCX312(N 卡网速快)但收到货之后隐隐感觉不是很对劲,所以就退掉了。

然后由于内网现在都还是电口,所以不得不买一张电卡。于是乎又去海鲜市场搞了个 561FLR(万兆双电口)。原计划倒腾下 100G 内网但想了想现在这台机器的性能大概率跑不满所以就搁置了。

最终配置(截止本文最后更新)

零件型号
机箱乔思伯 D40
散热器利民 PA120
电源航嘉 500W 金牌非模组
主板华南 F8
CPUE5 2666v3
内存三星 32G DDR4 ECC 2133MHz
数据盘P4510 4T DCSSD
系统盘M6S 128G SSD
猫棒ODI XPON 双模 + MA5671A
网卡HPE 530FLR + HPE561FLR
显卡Matrox G550

上面这些配置陆陆续续买了差不多 1 个月吧。

「散热器与网卡的极限空间 😂」

软件

我的计划是通过各种虚拟化达成灵活组合的方式(这在后面的实践中确实也给我带来比较多的时间节省)。原计划是 PVE + RouterOS CHR + 开发机,但由于 57810/57820 魔改固件后开出的 2.5G 所以驱动层面也需要做对应的 patch 才能够协商到,否则看到的只能是 1G 和 10G。为了解锁掉 1G 的带宽,加上 RouterOS 闭源且对于 2.5G 支持并不好,所以在初期验证阶段我让网卡直通然后装了爱快做路由(需要加载所有网卡驱动才能识别 2.5G)。

有一个点要提的是:没有选择 ESXI 是因为闭源导致很多东西不方便折腾,比如驱动。也还有一方面是 license 的价格。

差不多以 PVE + 爱快跑了一段时间后(主要也是没时间折腾),就想是该折腾 ROS 了,我需要更多的灵活性。考虑到驱动的问题,所以打算是:将其中一个光口做虚拟化,然后给 PVE 打驱动补丁让协商 2.5G 后就能透传 2.5G 的速率给 ROS 用。

驱动补丁

57810 用的是 bnx2x 搜了下正好有人写了这个 patch bnx2x_warpcore+8727_2_5g_sgmii.patch 那就直接拿来 DKMS 打上用了。

~# ethtool ens6f1
Settings for ens6f1:
    Supported ports: [ FIBRE ]
    Supported link modes:   1000baseT/Full
                            2500baseX/Full <- 改完驱动后支持 2.5G
    Supported pause frame use: Symmetric Receive-only
    Supports auto-negotiation: No
    Supported FEC modes: Not reported
    Advertised link modes:  2500baseX/Full
    Advertised pause frame use: No
    Advertised auto-negotiation: No
    Advertised FEC modes: Not reported
    Speed: 2500Mb/s <- 协商到 2.5G 的速率
    Duplex: Full
    Auto-negotiation: off
    Port: FIBRE
    PHYAD: 1
    Transceiver: internal
    Supports Wake-on: g
    Wake-on: g
        Current message level: 0x00000000 (0)

    Link detected: yes

猫棒设置

所在地区的联通局端在测试后发现是通过 LOID + MAC 的方式认证,所以仅需要在光猫中设定好当时上门安装的对应光猫的信息就好。然后还有一点是,ONU 局端在分发到下层入户光猫的时候会分一个 VLAN 因此,也需要从光猫设置中获取下 VLAN ID 然后交给猫棒做 untag。猫棒大部分也支持 retag 丢出来,不过我没用,因为都是物理线 1:1 接入,所以没必要再加一层,等后续如果线多了上光交再 retag 就好。

还有一些地区可能还会绑定 SN 或者使用 LOID Password 的形式等等,我接触的都是只绑 LOID 或者加 MAC 所以也不好多说,见机行事吧。有一些猫棒的商家也会提供必要的技术支持,也可以问问他们。

折腾所需要的信息基本在超级管理员登陆光猫后都能拿到(MAC 机器背面贴纸就有了)。

拨号走起

因为也是要解锁万兆内网,所以就选了 P10 的 license(建议找淘宝上的代理商买,基本上是半价)。默认的 CHR 是有免费试用的时间,过后就是免费版你可以不购买,但就最大速率就是 1M 了。

ROS 的常规 PPPoE 和 NAT 就没啥说的了,我这边因为走双线并且还会转发公网端口进来用,所以需要类似 PCC 的做法配下 mangle 让源进源出。

首先做 connection mark 标记进链接然后再对于 NAT 后的出方向的 prerouting 做 route mark 转到不同的路由表(两条线我这边做成两个路由表给 default route),相关的一些内容可参考官网的文档 Firewall Marking

[neo@MikroTik] > /ip/firewall/mangle/print detail
Flags: X - disabled, I - invalid; D - dynamic
 0    chain=prerouting action=mark-connection new-connection-mark=conn_cu_wan1 passthrough=yes connection-state=new src-address-list=!local
      connection-mark=no-mark in-interface=cu-wan1 log=no log-prefix=""

 1    chain=prerouting action=mark-connection new-connection-mark=conn_cu_wan0 connection-state=new src-address-list=!local
      connection-mark=no-mark in-interface=cu-wan0 log=no log-prefix=""

 2    chain=prerouting action=mark-routing new-routing-mark=cu_wan1 passthrough=yes connection-mark=conn_cu_wan1 in-interface=!cu-wan1 log=no
      log-prefix=""

 3    chain=prerouting action=mark-routing new-routing-mark=main connection-mark=conn_cu_wan0 in-interface=!cu-wan0 log=no log-prefix=""

 4    chain=output action=mark-routing new-routing-mark=cu_wan1 passthrough=yes connection-mark=conn_cu_wan1 out-interface=cu-wan1 log=no
      log-prefix=""

 5    chain=output action=mark-routing new-routing-mark=cu_wan1 connection-mark=conn_cu_wan0 out-interface=cu-wan0 log=no log-prefix=""

透明代理

早前也玩过 iptables + ipset、OSPF 方式的透明代理,这次再做肯定不用 iptables:手动的去更新一些路由表比较诡异,而且效率方面也是比较尴尬的,并且也不太能够提供比较路由面的能力。至于 v6 其实差别也不大,这次暂时不给出海了。

这次打算做成白名单出海的形式,所以就用 BGP 那套吧。大致的想法是:从上游收到全表(v4 大概 80 万条)然后家里的 ROS 拉起 BGP peering,基于 ASN 和一些特殊 IP 块做过滤就能够得到一个「要出海的 IP」列表,接着改 gateway 到海外网关,塞到 main table 完事。

提供全表的比较方便低门槛的一个供应商是 Vultr,你可以去开个小鸡然后提个单让给一个全表的 BGP session。全表差不多要用 1 核 1G 的机器去顶,开个差不多的机器就好。如果你没有 RIR 分发的 ASN 可以直接用 Private ASN 去对接就好了。

  1. Vultr 机器开好后跟家里的 RouterOS 拉起隧道(因为 BGP 需要固定 IP,家宽都是浮动的 IP,所以需要来一个隧道)。IPSec 、GRE、WG 各种套娃随你爱了。
  2. 小鸡上跑你喜欢的路由系统就好(这边我走 Linux + bird2),首先找 VU 建立 session 收所有路由(他们有做过滤,所以不需要担心收到 bogon 等异常路由)
  3. 把家里的 ROS 跟小鸡再起一个 session 收表、改路由网关、加 check-gw(保证在海外网关异常的时候可以自动回 default route 或者其他网关)。

ROSv7 还有一个值得兴奋的特性就是:以往的版本中,BGP 收到的路由即使过滤掉也还是会存在于内存中并间接的增加 CPU 的计算量,而在 v7 中提供了 input.accept-* 的过滤方式,这种会直接将路由丢弃,极大的节省了计算资源。但实测的 7.3.1 版本中这个过滤似乎并没有生效。

由于 accept.input-* 特性还没有生效(BugOS 🤦🏻‍♀️),所以我就直接暂时在 bird 上做过滤然后在 ROS 上 accept all。

过滤规则这部分我当前还没有特别多的需求,基本 ASN(bgp last path)能够满足,后面有需要再加。以下是我当前重路由的 AS:

define well_known_rerouting_asn = [
    # Google, Facebook, WikiPedia
    15169, 32934, 14907,
    # Twitter, Edgecast
    13414, 15133,
    # Cloudflare, Akamai
    13335, 16625,
    # Telegram
    62041, 59930,
    # Netflix
    40027, 2906, 55095,
    # AWS
    16509
];

也可以再进一步细化下这块的路由策略,比如给某些 IP 打 community 进行细化路由等等,上限非常高,可以随便玩。

如果比较多人感兴趣 RoterOS 这部分的内容,我后面单独写一篇。然后如果你需要比较方便的收全表,也可以找我 export 给你。

收尾

装机的过程就是那种很普通的装机,因为空间大所以也没有什么不契合或者散热影响性能的问题。利民的风扇在夜间睡觉的时候在把温度压下去的同时也几乎感知不到风扇声,挺好的。

如果考虑功耗和体积大小但又想折腾,挺推荐入手 R86S 的。但如果说想要拓展性,那么 ATX

猫棒散热的问题

当前在用的两根猫棒分别是 ODI 和 MA5671A,前者没有特别大问题,温度在 50 度左右,而后者就比较夸张了日常维持在 70 度以上。朋友前些天来我这拆了根 MA5671A,看了下基本是 DIE 的热传导不带劲,用一块看起来很廉价的相变材料做传递,就交给他做改造方案了,期待后续的温度优化。

这波操作带来的变化

后续可能的操作