最近家里新拉了一条 1000M 的上海移动宽带,为了充分使用新宽带和已有的移动宽带,自然是需求用一点魔法来一起使用这两路上游。这儿就以 CCR2004-16G-2S
路由器为例,介绍一下怎么用 BGP 全表来优化网络拜访。咱们的目标策略非常清晰:
基础网络配置: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;
有两个需求说明的是:
- china_asn_list 是一个从网上获取的在大陆运用的 ASN 列表,能够在
/routing/filter/num-list
中保护,比如添加 AS4134:/routing/filter/num-list/add list=china_asn_list range=4134
- 经过
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 地址,仍然存在问题,之后的文章会介绍怎么处理这个问题。最终展示一下成果: