发现还是 Babeld(Bird2) + WireGuard 的组网方式更适合我,之前的 OSPF 有点复杂,配不明白(
前期准备 非常重要的系统设置
首先,千万 一定 绝对 要打开 Linux 内核的数据包转发功能,即 ip_forwarding
1 2 3 4 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.forwarding=1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.conf sysctl -p
然后,千万 一定 绝对 要关闭 Linux 内核 rp_filter 的严格模式
1 2 3 echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf sysctl -p
最后,检查一下自己的系统是不是预装 了 iptables
,我自己就因为这个问题翻过车,如果没有装上,请自行安装。
软件前期安装 必装:bird2
、wireguard
强烈建议:wireguard-tools
,装上这个才能愉快的用 wg-quick
,如果你的系统不支持(如 OpenWrt),请自行抉择。
我们这里使用了 bird2
提供的 babeld
协议进行组网,不用 babeld
主要是因为我太菜了。
内网组网 WireGuard VPN 把你需要配置的服务器通过 WireGuard 直接或间接的连接到一起。
你可以参考我的 WireGuard 配置:
1 2 3 4 5 6 7 8 9 10 11 [Interface] Table = off ListenPort = <your_listen_port>PrivateKey = <your_private_key>Address = fe80::9000 :225 /64 Address = 198.18 .0.225 [Peer] PublicKey = <your_peer_public_key>AllowedIPs = 10.0 .0.0 /8 , 172.20 .0.0 /14 , 172.31 .0.0 /16 , 198.18 .0.0 /15 , fd00::/8 , fe80::/64 , ff00::/8 Endpoint = <your_peer_endpoint>
似乎 bird2
的 babeld
要求一定要存在 IPv4 地址,为了满足这个要求,我在 WireGuard 的配置里添加了一个保留的 IPv4 地址 (198.18.0.0/15)。
配置 Bird 为了方便管理,这里主要把 bird.conf 作为入口文件,然后逐一细分到其他配置文件。
bird.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 ################################################ # Variable header # ################################################ # 不要忘了修改以下变量为你自己的配置 define OWNAS = 4242423374; define OWNIP = 172.20.154.225; define OWNIPv6 = fddf:3681:e80::225; define OWNNET = 172.20.154.224/27; define OWNNETv6 = fddf:3681:e80::/48; define OWNNETSET = [172.20.154.224/27+]; define OWNNETSETv6 = [fddf:3681:e80::/48+]; ################################################ # Header end # ################################################ router id OWNIP; protocol device { scan time 10; } /* * Utility functions */ function is_self_net() { return net ~ OWNNETSET; } function is_self_net_v6() { return net ~ OWNNETSETv6; } function is_valid_network() { return net ~ [ 172.20.0.0/14{21,29}, # dn42 172.20.0.0/24{28,32}, # dn42 Anycast 172.21.0.0/24{28,32}, # dn42 Anycast 172.22.0.0/24{28,32}, # dn42 Anycast 172.23.0.0/24{28,32}, # dn42 Anycast 172.31.0.0/16+, # ChaosVPN 10.100.0.0/14+, # ChaosVPN 10.127.0.0/16+, # neonetwork 10.0.0.0/8{15,24} # Freifunk.net ]; } function is_valid_network_v6() { return net ~ [ fd00::/8{44,64} # ULA address space as per RFC 4193 ]; } protocol kernel { scan time 20; ipv6 { import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = OWNIPv6; accept; }; }; }; protocol kernel { scan time 20; ipv4 { import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = OWNIP; accept; }; }; } protocol static { route OWNNET reject; ipv4 { import all; export none; }; } protocol static { route OWNNETv6 reject; ipv6 { import all; export none; }; } include "/etc/bird/rpki.conf"; include "/etc/bird/babeld.conf"; include "/etc/bird/bgp.conf"; include "/etc/bird/ibgp.conf"; include "/etc/bird/peers/*";
简单介绍一下:
定义了我们内网的 IP 和 ASN
引入了 RPKI、Babeld、BGP 和 iBGP 的配置文件
rpki.conf 1 2 3 4 5 6 7 8 9 10 11 roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol rpki rpki_akix { roa4 { table dn42_roa; }; roa6 { table dn42_roa_v6; }; remote "<your_rpki_server>" port 8082; # change it refresh 30; retry 5; expire 600; }
没什么好说的,RPKI 的配置文件。
不要忘了修改 <your_rpki_server>
为你自己的 RPKI 服务器地址。
babeld.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 protocol direct { ipv4; ipv6; interface "dummy"; }; protocol babel int_babel { ipv4 { import where source != RTS_BGP && is_self_net(); export where source != RTS_BGP && is_self_net(); }; ipv6 { import where source != RTS_BGP && is_self_net_v6(); export where source != RTS_BGP && is_self_net_v6(); }; interface "dn42-jp01" { # 注意:Babel 的成本度量与 BGP 和 OSPF 略有不同 # rxcost 指定的是邻居向我们发送流量的成本,而不是向邻居发送流量的成本 # 当然,如果两端的成本保持一致,这不会产生任何影响 # 我这里使用了延迟作为成本度量 rxcost 57; }; interface "dn42-sg01" { rxcost 173; }; interface "dn42-cn02" { rxcost 376; }; };
这里的 dummy
网卡应当绑定了你的 DN42 IPv4 和 IPv6 地址。
可以参考 玩一玩 DN42 - カレーうどん屋 。
Babeld
的配置文件是参考 Multiple servers on dn42: iBGP and IGPs | jlu5 配的,中文翻译位于 [译] dn42 多服务器环境中的 iBGP 与 IGP 配置 | liuzhen932 的小窝 。
bgp.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 template bgp dnpeers { local as OWNAS; path metric 1; ipv4 { import filter { if is_valid_network() && !is_self_net() then { if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then { # Reject when unknown or invalid according to ROA print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } else accept; } else reject; }; export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; }; next hop self; import limit 9000 action block; }; ipv6 { import filter { if is_valid_network_v6() && !is_self_net_v6() then { if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then { # Reject when unknown or invalid according to ROA print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } else accept; } else reject; }; export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; }; next hop self; import limit 9000 action block; }; }
是非常标准的 BGP 配置。
ibgp.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 template bgp ibgpeers { local as OWNAS; ipv4 { import where source = RTS_BGP && is_valid_network() && !is_self_net(); export where source = RTS_BGP && is_valid_network() && !is_self_net(); next hop self; }; ipv6 { import where source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6(); export where source = RTS_BGP && is_valid_network_v6() && !is_self_net_v6(); next hop self; }; }
是标准的 IBGP 配置,同样是参考 Multiple servers on dn42: iBGP and IGPs | jlu5 配的,中文翻译位于 [译] dn42 多服务器环境中的 iBGP 与 IGP 配置 | liuzhen932 的小窝 。
继续增加节点 增加节点就容易多了,只需要记得修改 babeld
和添加 IBGP Peer
即可。
疑难解答 Babeld 没连上 ip addr
看看你的 wg 接口是不是同时绑定了 IPv4 和 IPv6 link-local 地址,同时检查 babeld.conf
里是否填写了正确的接口名称。
参考资料