使用 WireGuard + Babald(Bird2) 快速组网

发现还是 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,我自己就因为这个问题翻过车,如果没有装上,请自行安装。

软件前期安装

必装:bird2wireguard

强烈建议: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 # 使用 IPv6 link-local 地址
Address = 198.18.0.225 # 使用保留的 IPv4 地址

[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>

似乎 bird2babeld 要求一定要存在 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 里是否填写了正确的接口名称。

参考资料


使用 WireGuard + Babald(Bird2) 快速组网
https://blog.byteloid.one/2025/06/02/babeld-over-wireguard/
作者
bingxin666
发布于
2025年6月2日
许可协议