首页
iYoRoy DN42 Network
关于
友情链接
推荐
悠笙の喵罐头
Search
1
Docker下中心化部署EasyTier
869 阅读
2
给Android 4.9内核添加KernelSU支持
698 阅读
3
记一次为Android 4.9内核的ROM启用erofs支持
213 阅读
4
为黑群晖迁移RR引导盘
177 阅读
5
在TrueNAS上使用Docker安装1Panel
176 阅读
Android
运维
NAS
开发
网络技术
登录
Search
标签搜索
Linux
C&C++
Android
Windows
Docker
MSVC
AOSP
服务
DN42
STL
网络技术
Kernel
caf/clo
Web
TrueNAS
OSPF
IGP
BIRD
内部路由协议
BGP
神楽悠笙
累计撰写
15
篇文章
累计收到
5
条评论
首页
栏目
Android
运维
NAS
开发
网络技术
页面
iYoRoy DN42 Network
关于
友情链接
推荐
悠笙の喵罐头
搜索到
2
篇与
的结果
DN42探究日记 - Ep.2 通过OSPF搭建内部网络
为什么需要内部路由 当节点数量增多,我们需要一个合适的方式处理自己AS的内部路由。因为BGP路由只负责将数据包路由到AS,这就导致了一个问题:假如我有A、B两个节点都与别人peer,但是在路由器看来这两台设备同属于一个AS,从A节点发出的请求回包可能被回到B上。这个时候,如果没有做内部路由,则A会无法收到回包。因此,我们需要保证自家内网各个设备之间都能连通。常见的几种方式如下: 通过ZeroTier等组网工具:这种方式较为简单,只需要在每个节点上配置一个客户端即可实现各个节点之间的P2P连接。 通过WireGuard等P2P工具手动建立$\frac{n(n+1)}{2}$条隧道,效果同1,但是节点一多工作量呈指数级上升 通过WireGuard等P2P工具手动建立<$\frac{n(n+1)}{2}$条隧道,再通过OSPF、Babel等内网寻路协议建立内网路由,优点是较为灵活,易于后期添加新节点,缺点就是较为危险,容易配置错误引爆DN42。 因此我决定冒险一下 网络结构 我的网络结构如下图,其中A-E分别代表5个不同的节点: graph LR A[A<br>172.20.234.225<br>fd18:3e15:61d0::1] B[B<br>172.20.234.226<br>fd18:3e15:61d0::2] C[C<br>172.20.234.227<br>fd18:3e15:61d0::3] D[D<br>172.20.234.228<br>fd18:3e15:61d0::4] E[E<br>172.20.234.229<br>fd18:3e15:61d0::5] E <--> A E <--> C A <--> D C <--> D A <--> C D <--> B 本文更新日志 {timeline} {timeline-item color="#50BFFF"} 2025年7月22日:文章第一版发布,使用VXLAN over WireGuard隧道 {/timeline-item} {timeline-item color="#4F9E28"} 2025年7月25日:更新隧道方案,使用type ptp;以支持直接通过WireGuard传输OSPF流量(特别感谢Nuro Trance大佬指导!) {/timeline-item} {/timeline} 更新Bird2至v2.16及以上 因为我希望使用IPv6 Link-Local地址传递IPv4的OSPF数据,而Bird在2.16及以后才支持这项功能,因此需要更新至v2.16。如果你不希望更新,可以先跳过此步骤。 使用以下指令安装最新版本的Bird2: sudo apt update && sudo apt -y install apt-transport-https ca-certificates wget lsb-release sudo wget -O /usr/share/keyrings/cznic-labs-pkg.gpg https://pkg.labs.nic.cz/gpg echo "deb [signed-by=/usr/share/keyrings/cznic-labs-pkg.gpg] https://pkg.labs.nic.cz/bird2 $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/cznic-labs-bird2.list sudo apt update && sudo apt install bird2 -y 配置隧道 [Interface] PrivateKey = <本地WireGuard私钥> ListenPort = <监听端口> Table = off Address = <IPv6 LLA>/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对端公钥> Endpoint = <对端公网接入点> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8, ff02::5 ff02::5是OSPFv3路由器专用的链路本地范围组播地址,需要添加进AllowedIPs。 如果你正在使用v2.16以前的Bird,请再为隧道配置一个IPv4地址,不一定非要是DN42 IPv4,其他私有地址也可以。请参考: {collapse} {collapse-item label="包含IPv4的WireGuard配置示例"} [Interface] PrivateKey = <本地WireGuard私钥> ListenPort = <监听端口> Table = off Address = <IPv6 LLA>/64 PostUp = ip addr add 100.64.0.225/32 peer 100.64.0.226/32 dev %i PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对端公钥> Endpoint = <对端公网接入点> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8, ff02::5 请将100.64.0.225、100.64.0.226替换为你本机的IPv4和对端的IPv4。 {/collapse-item} {/collapse} 启用OSPF 默认你已经配置好了如上一篇文章所写的bird基础配置 在/etc/bird下新建一个名为ospf.conf的文件,填入如下内容: protocol ospf v3 <name> { ipv4 { import where is_self_net() && source != RTS_BGP; export where is_self_net() && source != RTS_BGP; }; include "/etc/bird/ospf/*"; }; protocol ospf v3 <name> { ipv6 { import where is_self_net_v6() && source != RTS_BGP; export where is_self_net_v6() && source != RTS_BGP; }; include "/etc/bird/ospf/*"; }; 理论上来说应该使用OSPF v2处理IPv4,但是因为需要通过IPv6 LLA地址通信IPv4,因此此处IPv4也使用OSPF v3。 过滤规则保证只有本网段内的路由能够通过OSPF传递,并且过滤掉外部BGP协议的路由 千万不要随意使用import all;export all;,有可能会导致路由劫持并影响到整个DN42网络。OSPF只应该处理网段内部的路由。 {collapse} {collapse-item label="配置示例"} /etc/bird/ospf.conf protocol ospf v3 dn42_iyoroynet_ospf { ipv4 { import where is_self_net() && source != RTS_BGP; export where is_self_net() && source != RTS_BGP; }; include "/etc/bird/ospf/*"; }; protocol ospf v3 dn42_iyoroynet_ospf6 { ipv6 { import where is_self_net_v6() && source != RTS_BGP; export where is_self_net_v6() && source != RTS_BGP; }; include "/etc/bird/ospf/*"; }; {/collapse-item} {/collapse} 接着,新建/etc/bird/ospf文件夹,在其中创建area配置文件(如:/etc/bird/ospf/0.conf),填写区域信息: area 0.0.0.0 { interface "<DN42 dummy网卡>" { stub; }; interface "<wg0网卡名称>" { cost 80; # 按照你的网络情况修改 type ptp; }; interface "<wg1网卡名称>" { cost 100; # 按照你的网络情况修改 type ptp; }; # 以此类推 }; 0.0.0.0区域代表骨干网 此处dummy网卡指上一篇文章中所写的DN42虚拟网卡 cost值本应该是用于开销计算,但在DN42这种对带宽要求不大而对延迟较为敏感的场景下可以直接填写延迟,OSPF会自动走开销值之和最短的路由。 {collapse} {collapse-item label="配置示例"} /etc/bird/ospf/0.conf area 0.0.0.0 { interface "dn42" { stub; }; interface "dn42_hkg" { cost 80; type ptp; }; interface "dn42_hfe" { cost 150; type ptp; }; interface "dn42_lax"{ cost 100; type ptp; }; }; {/collapse-item} {/collapse} 最后,打开/etc/bird/bird.conf,在末尾引入OSPF的配置文件: include "ospf.conf"; 运行birdc configure,然后birdc show protocols应该就能看到OSPF的状态是Running了。如果不是,请检查配置步骤是否出错。 此时,在非直连的两台机器上互相ping应该就能通了: 参考文章: https://soha.moe/post/bird-bgp-kickstart.html https://milu.ink/519.html https://blog.xeiu.top/archives/344 https://baimeow.cn/posts/dn11/configureospf/ https://lantian.pub/article/modify-website/dn42-experimental-network-2020.lantian/ https://lantian.pub/article/modify-website/how-to-kill-the-dn42-network.lantian/ https://edu.51cto.com/article/note/3019.html https://bird.nic.cz/news/2024-12-07-new-release-2.16/ https://bird.xmsl.dev/docs/user-guide/1-2-installing.html
2025年07月22日
54 阅读
0 评论
0 点赞
DN42探究日记 - Ep.1 加入DN42网络
欢迎与我建立对等连接!详情请查看:iYoRoy DN42 Network 想研究BGP,奈何租一个ASN和IP段实在是太贵了,又怕自己因为配置错误干掉半个互联网,因此决定研究一下DN42这个虚拟的网络。DN42是个大型去中心化网络,使用BGP协议建立路由,和当今互联网的结构很相像,因此适合用于BGP等网络技术学习。在DN42中,每个人都将扮演ISP(网络服务提供商)的角色,和其他用户Peer,以加入并参与建设整个DN42网络。DN42运行在172.20.0.0/14和fd00::/8上,这两个地址都是内网地址,因此不会影响到正常的互联网。 注册 你需要会使用基础的git指令、GPG、Linux,并且最好启用GPG签名Commit。 有Git使用基础的话可以参考我的commit:Add AS4242422024 · d1f9046ecb - registry - dn42 git Fork并克隆DN42注册表Git仓库 在dn42 git注册一个账号,并且Fork dn42/registry仓库。Clone下Fork出来的仓库并进入。 注册联系人 在data/person下创建文件<昵称>-DN42,填入如下内容: person: <姓名> e-mail: <邮箱> pgp-fingerprint: <GPG密钥指纹> nic-hdl: <NIC 句柄> mnt-by: <维护者> source: DN42 person: 名称 e-mail: 邮箱 pgp-fingerprint: GPG密钥指纹,会被用于一些认证服务 nic-hdl: NIC句柄,指向文件本身,直接填写当前文件名即可 mnt-by: 由谁维护,指向下文注册维护者一节中的维护者信息 source: 来源,保持DN42即可 www: 可选,可填网页地址 {collapse} {collapse-item label="示例"} data/person/IYOROY-DN42 @ dn42/registry@master person: Kagura iYoRoy e-mail:
[email protected]
www: https://www.iyoroy.cn pgp-fingerprint: 3ECCFFDEC2CB4CB8DA8089BE9AF2F2E03CE8FD67 nic-hdl: IYOROY-DN42 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册维护者 创建文件data/mntner/<昵称>-MNT,并填入如下内容: mntner: <昵称>-MNT admin-c: <联系人> tech-c: <联系人> auth: <验证方式> mnt-by: <维护者> source: DN42 mntner: 维护者名称,一般与文件名相同即可 admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 auth: 验证方式,支持pgp或者ssh-key mnt-by: 由谁维护,一般指向文件名本身即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/mntner/IYOROY-MNT @ dn42/registry@master mntner: IYOROY-MNT admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 auth: pgp-fingerprint 3ECCFFDEC2CB4CB8DA8089BE9AF2F2E03CE8FD67 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册ASN 在公网上,4200000000 - 4294967294为ASN保留范围。DN42使用了4242420000 - 4242429999,而目前开放注册的是4242420000 - 4242423999。官方不建议自己寻找可用ASN,而是推荐使用Burble的DN42 Free ASN Explorer,从中选取可用的ASN注册。 找好心仪的ASN后在data/aut-num创建<ASN,包含AS字母>文件,填写如下内容: aut-num: <ASN> as-name: <自治系统名称> descr: <自治系统描述> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> source: DN42 aut-num: 你选择的ASN,包含AS前缀。应该是AS424242xxxx的样式 as-name: 自治系统名称 descr: 自治系统描述,可以有空格 admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/aut-num/AS4242422024 @ dn42/registry@master aut-num: AS4242422024 as-name: IYOROYNET-AS-DN42 descr: iYoRoy DN42 Network admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册IPv4地址块并添加路由 如果你不想要注册IPv4,可以忽略本节 官方提供了一个用于检索可用地址块的工具:DN42 Free IPv4 Explorer 。同样不建议手动指定,而是建议用检索工具检索出来的可用地址块。 DN42同样面临IPv4地址短缺,所以请尽量按需注册。一般而言,一个/27地址块包含30个IPv4地址就够用了,如果是小型网络可以申请/28(14个可用地址)和/29(6个可用地址)。能直接申请的地址块最大是/26,也就是62个地址,若申请/25、/24则需要提交申请然后等待审核。详情可参考:DN42 实验网络介绍及注册教程(2022-12 更新) - Lan Tian @ Blog 选定你的IPv4地址块,然后在data/inetnum创建一个文件,命名为IPv4地址块的CIDR格式,并使用_代替/(如:我申请的IPv4地址块为172.20.234.224/28,则文件名为172.20.234.224_28),填入内容: inetnum: <IPv4地址块第一个地址> - <IPv4地址块最后一个地址> cidr: <IPv4地址块CIDR格式> netname: <IPv4地址块名称> descr: <IPv4地址块描述> country: <IPv4地址块所属国家代码> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> status: ASSIGNED source: DN42 inetnum: IPv4地址范围,从第一个地址到最后一个地址,中间用-连接 cidr: IPv4地址块CIDR格式,不需要用_代替/ netname: IPv4地址块名称,自行填写即可,无特殊要求 descr: IPv4地址块描述,中间可以有空格 country: ISO 3166中的两字符国家代码,中国就填CN admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 status: 状态,保存ASSIGNED即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/inetnum/172.20.234.224_28 @ dn42/registry@master inetnum: 172.20.234.224 - 172.20.234.239 cidr: 172.20.234.224/28 netname: IYOROYNET-DN42-V4 descr: iYoRoy DN42 Network IPv4 Block country: CN admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT status: ASSIGNED source: DN42 {/collapse-item} {/collapse} 接着,在data/route下同样创建一个名为IPv4地址块的 CIDR 格式,并使用_代替/的文件,填入内容: route: <IPv4地址CIDR格式> origin: <ASN> max-length: <IPv4掩码> mnt-by: <维护者> source: DN42 route: IPv4地址块,填写CIDR格式,无需转换/ origin: ASN,需要带AS max-lenth: 前缀长度(Prefix Length),即CIDR格式中/后面的数字 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/route/172.20.234.224_28 @ dn42/registry@master route: 172.20.234.224/28 origin: AS4242422024 max-length: 28 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册IPv6地址块并添加路由 如果你不想要注册IPv6,可以忽略本节 同样使用官方工具检索可用IPv6:DN42 Free IPv6 Explorer 。 选定地址块后在data/inet6num下创建名为IPv6地址块的CIDR格式,并使用_代替/的文件(如:我的IPv6地址块为fd18:3e15:61d0::/48,则文件名fd18:3e15:61d0::_48),填入内容: inet6num: <IPv6地址块第一个地址> - <IPv6地址块最后一个地址> cidr: <IPv6地址块CIDR格式> netname: <IPv6地址块名称> descr: <IPv6地址块描述> country: <IPv6地址块所属国家代码> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> status: ASSIGNED source: DN42 inet6num: IPv6地址范围,从第一个地址到最后一个地址,不可使用::简写,中间用-连接。也就是说,比如我的地址块是fd18:3e15:61d0::/48,我需要填入fd18:3e15:61d0:0000:0000:0000:0000:0000 - fd18:3e15:61d0:ffff:ffff:ffff:ffff:ffff。 cidr: IPv6地址块CIDR格式,不需要用_代替/ netname: IPv6地址块名称,自行填写即可,无特殊要求 descr: IPv6地址块描述,中间可以有空格 country: ISO 3166中的两字符国家代码,中国就填CN admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 status: 状态,保存ASSIGNED即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/inet6num/fd18:3e15:61d0::_48 @ dn42/registry@master inet6num: fd18:3e15:61d0:0000:0000:0000:0000:0000 - fd18:3e15:61d0:ffff:ffff:ffff:ffff:ffff cidr: fd18:3e15:61d0::/48 netname: IYOROYNET-DN42-V6 descr: iYoRoy DN42 Network IPv6 Block country: CN admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT status: ASSIGNED source: DN42 {/collapse-item} {/collapse} 接着,在data/route6下同样创建一个名为IPv6地址块的 CIDR 格式,并使用_代替/的文件,填入内容: route6: <IPv6地址CIDR格式> origin: <ASN> max-length: <IPv4掩码> mnt-by: <维护者> source: DN42 route6: IPv6地址块,填写CIDR格式,无需转换/ origin: ASN,需要带AS max-lenth: 前缀长度(Prefix Length),即CIDR格式中/后面的数字 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/route6/fd18:3e15:61d0::_48 @ dn42/registry@master route6: fd18:3e15:61d0::/48 origin: AS4242422024 max-length: 48 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 创建并上传commit,提交PR 最好使用GPG签名你的commit并且在dn42 git里上传你的公钥 填完上述信息,回到仓库根目录下,运行脚本./fmt-my-stuff <维护者>自动格式化配置文件。注意:此处<维护者>是上文注册维护者章节中的mntner的值。接着按照正常git commit流程git add data/、git commit -S -m "<commit-msg>"创建commit,git push origin master推送,接着,来到dn42 git网页端,打开你Fork的仓库并提交Pull Request即可。 如果配置有问题,自动审查机器人和管理员会告知你,请耐心按照要求修改并且合并到原来的commit中,不要新开commit,推荐add后使用git commit --amend指令。修改完**直接强制推送(git push origin master --force)**即可。 DN42 Registry 的工作语言是英语。请使用英语完成全部流程,以免出现不必要的麻烦。 配置Bird 首先安装bird,以Ubuntu22.04为例: apt install bird2 -y 如果要一并安装后续使用的WireGuard,就再加上wireguard、wireguard-tools软件包: apt install bird2 wireguard wireguard-tools -y 编写配置文件 bird.conf 修改/etc/bird/bird.conf: define OWNAS = <AS 号>; define OWNIP = <DN42 IPv4 地址>; define OWNIPv6 = <DN42 IPv6 地址>; define OWNNET = <DN42 IPv4 地址块, CIDR 格式>; define OWNNETv6 = <DN42 IPv6 地址块, CIDR 格式>; define OWNNETSET = [ <DN42 IPv4 地址块, CIDR 格式>+ ]; define OWNNETSETv6 = [ <DN42 IPv6 地址块, CIDR 格式>+ ]; router id OWNIP; protocol device { scan time 10; } 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{16,32}, # 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 "rpki.conf"; include "ebgp.conf"; 此处OWNIP和OWNIPV6参数意为本机的DN42 IPv4和IPv6地址,不是地址块的地址,比如我申请到的地址段是172.20.234.224/28,我给A机器分配了172.20.234.225,则OWNIP为172.20.234.225,IPv6同理。 rpki.conf 你可能在其他教程里看到过使用定时任务+重载Bird的更新ROA方案,此处配置RPKI则是另一种配置ROA的方式。 创建/etc/bird/rpki.conf,填写如下内容: roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol rpki dn42_rpki_akix { roa4 { table dn42_roa; }; roa6 { table dn42_roa_v6; }; remote "<rpki服务器地址>" port 8082; # change it refresh 30; retry 5; expire 600; } RPKI服务器可以使用我朋友的AkaereIX提供的服务:rpki.akae.re {collapse} {collapse-item label="样例"} roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol rpki dn42_rpki_akix { roa4 { table dn42_roa; }; roa6 { table dn42_roa_v6; }; remote "rpki.akae.re" port 8082; refresh 30; retry 5; expire 600; } {/collapse-item} {/collapse} ebgp.conf 创建/etc/bird/ebgp.conf,填入如下内容: 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 { print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } accept; } reject; }; export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; reject; }; import limit 1000 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 { print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } accept; } reject; }; export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; reject; }; import limit 1000 action block; }; } include "peers/*"; 此配置项定义了DN42内部互相peer的模板,并且引用/etc/bird/peers下的所有配置文件,之后我们peer的时候就只需要在这里按照模板创建配置文件并编写即可。 创建/etc/bird/peers文件夹用作后续peer。 系统配置 内核 因为每个节点都可能会作为其他节点的路由器使用,因此需要打开Linux内核数据包转发;同时因为使用了WireGuard,并不是通过物理网卡转发,因此需要关闭rp_filter严格模式。 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 echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf sysctl -p DN42虚拟网卡 因为MP-BGP通常使用LLA地址建立BGP,因此我们需要在系统里设置一个dummy网卡并绑定我们给这台机器分配的DN42 IP。运行以下指令: ip link add dn42 type dummy ip addr add <你给这这台机器分配的DN42 IPv4> dev dn42 ip addr add <你给这这台机器分配的DN42 IPv6> dev dn42 如果需要持久化配置,可以参考以下三种方式: {tabs} {tabs-pane label="systemd-networkd"} tee /etc/systemd/network/10-dn42.netdev > /dev/null <<EOF [NetDev] Name=dn42 Kind=dummy EOF tee /etc/systemd/network/20-dn42.network > /dev/null <<EOF [Match] Name=dn42 [Network] Address=<你给这台机器分配的DN42 IPv4>/32 Address=<你给这台机器分配的DN42 IPv6>/128 EOF systemctl enable systemd-networkd systemctl restart systemd-networkd {/tabs-pane} {tabs-pane label="netplan"} tee /etc/netplan/99-dn42.yaml > /dev/null <<EOF network: version: 2 renderer: networkd ethernets: dn42: match: name: dn42 addresses: - <你给这台机器分配的DN42 IPv4>/32 - "<你给这台机器分配的DN42 IPv6>/128" accept-ra: no EOF netplan apply {/tabs-pane} {tabs-pane label="/etc/network/interfaces"} tee -a /etc/network/interfaces > /dev/null <<EOF auto dn42 iface dn42 inet static address <你给这台机器分配的DN42 IPv4> netmask 255.255.255.255 iface dn42 inet6 static address <你给这台机器分配的DN42 IPv6>/128 EOF ifup dn42 {/tabs-pane} {/tabs} 与其他成员Peer 对新手较友好的应该就是Potat0大佬的自助Peer服务了,详情可参考他的DN42 Network页面。按照指引找到他的自动对等连接机器人,按照要求在机器人上注册你的账号,需要提供你的DN42 ASN、上文注册时Maintainer里记录的邮箱(这也是为什么在注册的时候最好需要填邮箱,很多验证服务都会使用),并且用该邮箱接收验证码,然后按照机器人的要求建立peer即可。以下是我通过Bot建立peer的过程,全程使用Ubuntu22.04系统的香港VPS操作。 安装WireGuard apt install wireguard wireguard-tools -y 注:现在的软件包管理一般会在安装wireguard的时候自动安装wireguard-tools以使用wg-quick指令。 生成密钥对 wg genkey | tee privatekey | wg pubkey > publickey 记下privatekey、publickey中的内容,代表私钥和公钥 建立Peer 一般而言有两种建立Peer的模式,即使用MP-BGP(Multiprotocol BGP,多协议BGP)和不使用MP-BGP。个人感觉MP-BGP更为常用,因为其配置较为简单。两种配置稍有不同,请根据你的需求参考。 使用MP-BGP 与Peer对方交换信息 你需要提供对方以下信息,同时你也需要知道对方的以下信息: 公钥 公网地址(非DN42地址) 公网WireGuard端口,一般是监听对方ASN的后5位 DN42 ASN LLA(Link-Local Address)地址,一般而言是fe80::<对方ASN后4位> 是否支持ENH(Extended Next Hop),注意,若使用v6交换路由而不启用ENH则无法交换v4路由 也有时会将公网地址和公网wg端口放在一起称作Endpoint。 配置WireGuard 在/etc/wireguard下创建一个配置文件,名称随意,但是我的命名习惯是dn42-<对方ASN后4位>.conf,其中dn42-xxxx即为隧道名。往文件内填入如下内容: [Interface] PrivateKey = <上文「生成密钥对」章节生成的私钥> ListenPort = <公网WireGuard监听端口> Table = off Address = <你的LLA地址>/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对方给你的公钥> Endpoint = <对方的Endpoint,即IP:端口> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 编辑完成后保存,运行: wg-quick up <隧道名> 即可启动wg隧道。使用wg show <隧道名>即可查看连接状态。直接运行wg可查看所有隧道状态 如果需要让隧道开机自启动,可以运行: systemctl enable wg-quick@<隧道名> 配置Bird2的Peer部分 在/etc/bird/peers下新建文件<名称>.conf,填入如下内容: protocol bgp <BGP会话名称> from dnpeers{ neighbor <对方LLA地址> % '<WireGuard隧道名>' as <对方ASN,不带AS前缀>; }; 如果使用使用了Extended next hop(如上图交换信息时协商的),则配置: protocol bgp <BGP会话名称> from dnpeers{ neighbor <对方LLA地址> % '<WireGuard隧道名>' as <对方ASN,不带AS前缀>; ipv4{ extended next hop; }; }; 应用配置 运行birdc configure(或者birdc c,等同)重载Bird配置,然后运行birdc show protocols(或者birdc s p,等同)即可查看当前建立的BGP连接。 root@hkg2-202501092021514df2f0:~# birdc show protocols BIRD 2.0.12 ready. Name Proto Table State Since Info device1 Device --- up 07:24:14.255 static1 Static dn42_roa up 07:24:14.255 static2 Static dn42_roa_v6 up 07:24:14.255 kernel1 Kernel master6 up 07:24:14.255 kernel2 Kernel master4 up 07:24:14.255 static3 Static master4 up 07:24:14.255 static4 Static master6 up 07:24:14.255 dn42-0298 BGP --- up 08:03:13.347 Established dn42-1816 BGP --- up 07:53:05.028 Established 不使用MP-BGP 与Peer对方交换信息 你需要提供对方以下信息,同时你也需要知道对方的以下信息: 公钥 公网地址(非DN42地址) 公网WireGuard端口,一般是监听对方ASN的后5位 DN42 ASN DN42 IP,如果交换IPv4路由则需要IPv4地址,如果交换IPv6路由则需要IPv6地址 也有时会将公网地址和公网wg端口放在一起称作Endpoint。 配置WireGuard 在/etc/wireguard下创建一个配置文件,名称随意,但是我的命名习惯是dn42-<对方ASN后4位>.conf,其中dn42-xxxx即为隧道名。往文件内填入如下内容: [Interface] PrivateKey = <上文「生成密钥对」章节生成的私钥> ListenPort = <公网WireGuard监听端口> Table = off PostUp = ip addr add <LLA>/64 dev %i PostUp = ip addr add <本地DN42 IPv6> dev %i PostUp = ip addr add <本地DN42 IPv4> peer <对方DN42 IPv4> dev %i PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对方给你的公钥> Endpoint = <对方的Endpoint,即IP:端口> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 编辑完成后保存,运行: wg-quick up <隧道名> 即可启动wg隧道。使用wg show <隧道名>即可查看连接状态。直接运行wg可查看所有隧道状态 如果需要让隧道开机自启动,可以运行: systemctl enable wg-quick@<隧道名> 配置Bird2的Peer部分 在/etc/bird/peers下新建文件<名称>.conf,填入如下内容: protocol bgp <v4BGP会话名称> from dnpeers{ neighbor <对方DN42 IPv4地址> as <对方ASN,不带AS前缀>; direct; ipv6{ import none; export none; }; }; protocol bgp <v6BGP会话名称> from dnpeers{ neighbor <对方DN42 IPv6地址> % '<WireGuard隧道名称>' as <对方ASN,不带AS前缀>; direct; ipv4{ import none; export none; }; }; 应用配置 运行birdc configure(或者birdc c,等同)重载Bird配置,然后运行birdc show protocols(或者birdc s p,等同)即可查看当前建立的BGP连接。 自此,我们成功加入了DN42网络。要想让网络更加稳定,我们可以与更多用户进行Peer,建立多条BGP线路以防止其中部分节点瘫痪导致失联。你可以加入DN42非官方tg交流群获取更多信息。 如果出现BGP Established但是无法Ping通DN42内部IP的情况,请检查bird.conf中设置的IP和dummy网卡分配的IP或WireGuard中的本地IP是否相同。 配置DNS DN42内有自己的公共DNS,泛播地址为172.20.0.53,并且也能解析正常互联网的域名。要想能够访问以dn42结尾的内部域名,需要将这个地址放到resolv.conf最上面: nameserver 172.20.0.53 nameserver 223.5.5.5 #下面是正常的DNS服务器配置 之后就可以解析DN42内部域名啦,同时ping、traceroute、mtr等命令查询内部IP时也能显示出来rDNS的解析结果。 欢迎与我建立对等连接!详情请查看:iYoRoy DN42 Network 参考文章: https://blog.baoshuo.ren/post/dn42-network/ https://dn42.dev/howto/Bird2#example-configuration https://dn42.eu/howto/wireguard https://blog.udon.eu.org/archives/dbf21067.html https://blog.byteloid.one/2025/06/02/babeld-over-wireguard/ https://blog.wcysite.com/2021/%E8%B8%A9%E5%9D%91DN42-p2-peer/ https://blog.chs.pub/p/23-14-joindn42/ https://www.cnblogs.com/FengZeng666/p/15583434.html
2025年06月28日
51 阅读
2 评论
1 点赞