最近家里新拉了一条 1000M 的上海移动宽带,为了充分使用新宽带和已有的移动宽带,自然是需求用一点魔法来一起使用这两路上游。这儿就以 CCR2004-16G-2S 路由器为例,介绍一下怎么用 BGP 全表来优化网络拜访。咱们的目标策略非常清晰:

  1. 针对中国电信的 IP 地址(AS4134,AS4812),直接运用电信出口
  2. 针对所有剩下的非中国 ASN,运用局域网内的一个科学路由
  3. 其他走移动

基础网络配置:PPPoE 等

首要需求让咱们的路由器衔接上互联网。假设电信的网络接在 ether1,移动的接在 ether2,咱们能够创立这样两个 PPPoE client:

/interface/pppoe-client/add name="pppoe-chinanet" interface=ether1 profile=default add-default-route=no dial-on-demand=no use-peer-dns=no allow=pap,chap,mschap1,mschap2
/interface/pppoe-client/add name="pppoe-chinamobile" interface=ether2 profile=default add-default-route=no dial-on-demand=no use-peer-dns=no allow=pap,chap,mschap1,mschap2

上面省掉了 PPPoE 中账户和暗码的部份,各位能够依照需求自行补全。不难注意到咱们新建的 PPPoE 衔接没有运用默许网关,这儿咱们能够直接加一个静态的路由来作为默许网关配置。假定咱们计划运用移动的宽带作为默许上行:

/ip/route/add dst-address=0.0.0.0/0 routing-table=main gateway=pppoe-chinamobile distance=100

到此为止咱们的路由器应该就能正确的拜访网络了,不妨来用 traceroute 验证一下:

[admin@shanghai-router] > /tool/traceroute 223.5.5.5
Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
#  ADDRESS         LOSS   SENT  LAST     AVG   BEST  WORST  STD-DEV
1  <redacted>      0%        9  3.9ms    4.7   3.6   8.9    1.9
2  <redacted>      75%       9  timeout  3.7   3.6   3.7    0.1
3  <redacted>      12.5%     8  timeout  3.7   3.6   3.8    0.1
4  <redacted>      0%        8  12.9ms   7.8   3.9   20.3   5.5
5                  100%      8  timeout
6  116.251.116.93  0%        8  6.2ms    12.9  5.6   38.3   10.6
7                  100%      8  timeout
8                  100%      8  timeout
9  223.5.5.5       0%        8  5.5ms    5.4   5.2   5.6    0.1

一起咱们还能够经过指定 interface 参数来测验一下电信的 PPPoE 衔接:

[admin@shanghai-router] > /tool/traceroute 223.5.5.5 interface=pppoe-chinanet
Columns: ADDRESS, LOSS, SENT, LAST, AVG, BEST, WORST, STD-DEV
 #  ADDRESS         LOSS   SENT  LAST     AVG   BEST  WORST  STD-DEV
 1  <redacted>      7.7%     13  3.8ms    4.7   1.8   7.7    1.8
 2  <redacted>      0%       13  10.3ms   8.7   4.6   18.4   3.2
 3  <redacted>      66.7%    13  timeout  6.6   3.9   14.2   4.4
 4  <redacted>      66.7%    12  timeout  5.5   3.8   8.7    1.9
 5  <redacted>      0%       12  3.2ms    6.3   3.1   25.3   6.7
 6  <redacted>      0%       12  5.8ms    18.2  5.5   150.8  40
 7                  100%     12  timeout
 8                  100%     12  timeout
 9                  100%     12  timeout
10  223.5.5.5       0%       12  5.4ms    5.5   5.3   5.8    0.2

当然咱们还需求在 /ip/firewall/nat 中创立一些 NAT 规矩,让咱们 LAN 中的设备也能拜访互联网。这部分比较基础,就不赘述了。

拿到一份 BGP 全表

假如你是一个 BGP Player 完全能够越过这一部分,可是假如不了解 BGP 或者是没有 ASN 的人则可能会有一点点困难。这儿咱们能够经过买一台最便宜的 Vultr 服务器来获得 BGP 全表数据,一起不需求拥有自己的 ASN,性价比非常高,相关操作过程网上有许多资料,例如:

完结 Vultr 上的相关操作后,咱们就能够依照官方教程和 Vultr 树立 BGP session,从而拿到全表数据,非常容易,相关关键配置如下:

protocol device {}
protocol kernel kernel4 {
  ipv4 {
    import none;
    export where source != RTS_DEVICE && proto != "bgp_vultr_v4";
  };
}
protocol kernel kernel6 {
  ipv6 {
    import none;
    export filter {
      if source = RTS_DEVICE then reject;
      if proto = "bgp_vultr_v4" then reject;
      reject;
    };
  };
}
protocol static static_bgp_neighbor_v6 {
  ipv6;
  route 2001:19f0:ffff::1/128 via fe80::fc00:4ff:fe08:ee5f % enp1s0;
}
protocol static static_bgp_neighbor_v4 {
  ipv4;
  route 169.254.169.254/32 via a.b.c.1 % enp1s0;
}
protocol bgp bgp_vultr_v4 {
  local as 142641;
  neighbor 169.254.169.254 as 64515;
  source address a.b.c.d;
  multihop 2;
  password "xxxxxxxx";
  ipv4 {
    import all;
    export none;
  };
}
protocol bgp bgp_vultr_v6 {
  local as 142641;
  neighbor 2001:19f0:ffff::1 as 64515;
  source address 2001:db8::1;
  multihop 2;
  password "xxxxxxx";
  ipv6 {
    import all;
    export none;
  };
}

当然假如你有困难也能够从我这儿获取全表数据,详细能够 E-mail 联络~

假如一切顺利,咱们能够在 birdc 中运用指令 show protocol 看到咱们的 session 状况已经是 Established:

Name         Proto      Table      State  Since         Info
bgp_vultr_v4 BGP        ---        up     2023-01-21    Established
bgp_vultr_v6 BGP        ---        up     2023-01-21    Established

咱们也能够用 show route for 指令来检查详细的 FIB,例如:

bird> show route for 1.1.1.1 all
Table master4:
1.1.1.0/24           unicast [bgp_vultr_v4 2023-08-01 from 169.254.169.254] * (100/?) [AS13335i]
	via 45.32.28.1 on enp1s0
	Type: BGP univ
	BGP.origin: IGP
	BGP.as_path: 64515 20473 13335
	BGP.next_hop: 169.254.169.254
	BGP.local_pref: 100
	BGP.aggregator: 10.34.7.24 AS13335
	BGP.community: (20473,200) (64515,44)
	BGP.large_community: (20473, 200, 13335) (20473, 200, 45686)

这样咱们就预备好了自己的 BGP speaker 了。

在 BGP feeder 和路由器之间树立地道

家庭宽带通常没有固定 IP,为了尽可能削减配置改变,最简略的办法是在家里的路由器和有 BGP 全表的服务器之间拉一个地道。这儿能够运用 WireGuard,优点是比较新的内核和 RouterOS 都有原生的支持,而且是 UDP 协议,比较方便运用各种“转发”服务来提高可靠性

在 feeder 上,咱们捏一个配置来创立接口:

[Interface]
PrivateKey = xxx
Address = 10.22.33.1/24, fd34:38a:f295::1/64
MTU = 1400
ListenPort = 114514
[Peer]
PublicKey = yyy
AllowedIPs = 10.22.33.2/32, fd34:38a:f295::2/128

然后,在 RouterOS 上也树立一个接口并添加 peer:

/interface/wireguard/add name="wg-bgp-speaker" private-key="xxx" mtu=1400
/interface/wireguard/peers/add endpoint-address=172.16.1.1 endpoint-port=3000 interface=wg-bgp-speaker public-key="qzgKhWy8u0DBvXcrhfFDYPwKzKipWzCsxR5ecNIYZFs=" persistent-keepalive=60 allowed-address=10.22.33.1/32,fd34:38a:f295::1/128
/ip/address/add interface=wg-bgp-speaker address=10.22.33.2/24
/ipv6/address/add interface=wg-bgp-speaker address=fd34:38a:f295::2/64

这样咱们就弄出了一个直接衔接的地道了,这个地道只能让咱们的路由器和服务器点对点通讯,不过这样就够了。

预备路由过滤器

依照之前所说的规矩,咱们能够预备一下 RouterOS 侧的路由过滤器了,在这个 filter 中咱们直接根据 AS path 的末尾来挑选这条路由运用的网关,以 IPv4 为例:

if (dst-len == 0) {
  reject
}
set distance 50;
if (not bgp-as-path [[:china_asn_list:]]$) {
  set gw %ipip-internet-proxy;
  accept;
} else {
  if (bgp-as-path 4134$|4812$) {
    set gw %pppoe-chinanet;
  } else {
    set gw %pppoe-chinamobile;
  }
}
accept;

有两个需求说明的是:

  1. china_asn_list 是一个从网上获取的在大陆运用的 ASN 列表,能够在 /routing/filter/num-list 中保护,比如添加 AS4134: /routing/filter/num-list/add list=china_asn_list range=4134
  2. 经过 set gw %interface 能够直接设置一个接口作为网关,让内核重视下一跳终究给谁,能够削减许多保护本钱

依样画葫芦一个 IPv6 的过滤器,内容根本相同,只有跨境拜访的网关需求进行一些微调。预备好这两个 filter 之后,就只剩最终一步了——全表带回家

全表带回家

最终的工作就是在咱们的 feeder 和路由器之间树立一个 BGP 邻居关系,首要咱们在 speaker 上新增两个 protocol:

protocol bgp bgp_speaker_v4 {
  local as 65000;
  neighbor 10.22.33.2 as 65001;
  source address 10.22.33.1;
  passive;
  ipv4 {
    import none;
    export where proto = "bgp_vultr_v4" && 223.5.5.5 !~ net;
  };
};
protocol bgp bgp_speaker_v6 {
  local as 65000;
  neighbor fd34:38a:f295::2 as 65001;
  source address fd34:38a:f295::1;
  passive;
  multihop;
  ipv6 {
    import none;
    export where proto = "bgp_vultr_v6";
  };
};

接着在 RouterOS 上添加对应的 BGP connection:

/routing/bgp/connection/add remote.address=10.22.33.1/32 remote.as=65000
  local.address=10.22.33.2 remote.role=ebgp
  routing-table=main router-id=10.22.33.2 as=65001 multihop=yes hold-time=infinity address-families=ip
  output.filter-chain=bgp-speaker-export
  input.filter=bgp-speaker-v4
/routing/bgp/connection/add remote.address=fd34:38a:f295::1/128 .as=65000
  local.address=fd34:38a:f295::2 .role=ebgp
  routing-table=main router-id=10.22.33.2 as=65001 multihop=yes hold-time=infinity address-families=ipv6
  output.filter-chain=bgp-speaker-export
  input.filter=bgp-speaker-v6

之后等待全表进入 FIB 后,就能够开始验证咱们的分流效果了,咱们分别用一个电信/移动/联通/Cloudflare 地址来进行测验:

# 电信
[admin@shanghai-router] > /ip/route/print where 221.227.153.1 in dst-address and routing-table=main and !static
Flags: D - DYNAMIC; A - ACTIVE; b, y - BGP-MPLS-VPN
Columns: DST-ADDRESS, GATEWAY, DISTANCE
    DST-ADDRESS     GATEWAY         DISTANCE
DAb 221.224.0.0/13  pppoe-chinanet        50
# 移动
[admin@shanghai-router] > /ip/route/print where 120.232.236.5 in dst-address and routing-table=main and !static
Flags: D - DYNAMIC; A - ACTIVE; b, y - BGP-MPLS-VPN
Columns: DST-ADDRESS, GATEWAY, DISTANCE
    DST-ADDRESS       GATEWAY            DISTANCE
DAb 120.192.0.0/10    pppoe-chinamobile        50
DAb 120.232.0.0/16    pppoe-chinamobile        50
DAb 120.232.236.0/22  pppoe-chinamobile        50
# 联通
[admin@shanghai-router] > /ip/route/print where 103.45.78.1 in dst-address and routing-table=main and !static
Flags: D - DYNAMIC; A - ACTIVE; b, y - BGP-MPLS-VPN
Columns: DST-ADDRESS, GATEWAY, DISTANCE
    DST-ADDRESS     GATEWAY            DISTANCE
DAb 103.45.76.0/22  pppoe-chinamobile        50
# Cloudflare
[admin@shanghai-router] > /ip/route/print where 1.1.1.1 in dst-address and routing-table=main and !static
Flags: D - DYNAMIC; A - ACTIVE; b, y - BGP-MPLS-VPN
Columns: DST-ADDRESS, GATEWAY, DISTANCE
    DST-ADDRESS  GATEWAY                         DISTANCE
DAb 1.1.1.0/24   198.18.1.1%ipip-internet-proxy        50

这样咱们的双线宽带的 IPv4 就算是充分使用上了,v6 尽管经过这些办法完成了分流,可是由于没有 NAT,设备也不能智能的挑选用哪个前缀的 IP 地址,仍然存在问题,之后的文章会介绍怎么处理这个问题。最终展示一下成果:

在 RouterOS 上使用 BGP 全表优化多线互联网拜访