Homepage
Privacy Policy
iYoRoy DN42 Network
About
More
Friends
Language
简体中文
English
Search
1
Centralized Deployment of EasyTier using Docker
1,705 Views
2
Adding KernelSU Support to Android 4.9 Kernel
1,091 Views
3
Enabling EROFS Support for an Android ROM with Kernel 4.9
309 Views
4
Installing 1Panel Using Docker on TrueNAS
300 Views
5
2025 Yangcheng Cup CTF Preliminary WriteUp
296 Views
Android
Ops
NAS
Develop
Network
Projects
DN42
One Man ISP
CTF
Kubernetes
Cybersecurity
Brain Dumps
Login
Search
Search Tags
Network Technology
BGP
BIRD
Linux
DN42
Android
OSPF
C&C++
Web
AOSP
CTF
Cybersecurity
Docker
iBGP
Windows
MSVC
Services
Kernel
IGP
TrueNAS
Kagura iYoRoy
A total of
32
articles have been written.
A total of
23
comments have been received.
Index
Column
Android
Ops
NAS
Develop
Network
Projects
DN42
One Man ISP
CTF
Kubernetes
Cybersecurity
Brain Dumps
Pages
Privacy Policy
iYoRoy DN42 Network
About
Friends
Language
简体中文
English
12
articles related to
were found.
DN42 - Ep.2 Building Internal Network with OSPF and Enabling iBGP
Foreword I am a novice in BGP. This article may contain imprecise content/naive understandings/elementary mistakes. I kindly ask the experts to be lenient. If you find any issues, you are welcome to contact me via email, and I will correct them as soon as possible. If you find this unacceptable, it is recommended to close this article now. Article Update Log {timeline} {timeline-item color="#50BFFF"} July 22, 2025: First edition published, using VXLAN over WireGuard tunnel. {/timeline-item} {timeline-item color="#50BFFF"} July 25, 2025: Updated tunneling solution, using type ptp; to support OSPF traffic via WireGuard (Special thanks to Nuro Trance for the guidance!). {/timeline-item} {timeline-item color="#50BFFF"} August 8, 2025: Added explanation and configuration for iBGP. {/timeline-item} {timeline-item color="#4F9E28"} August 27, 2025: Updated node topology diagram. {/timeline-item} {/timeline} Why Do We Need Internal Routing? As the number of nodes increases, we need a proper way to handle internal routing within our AS (Autonomous System). BGP only handles routing to different ASes, which causes a problem: if nodes A and B are both peering with external networks, a request from node A may have its response routed to node B, even though they are part of the same AS. Without internal routing, node A will not receive the reply. To solve this, we need to ensure that all devices within our AS can communicate with each other. The common solutions are: Using network tools like ZeroTier: Simple to set up, just install the client on each node for P2P connectivity. Using P2P tools like WireGuard to manually create $\frac{n(n-1)}{2}$ tunnels, which works like the first solution but becomes cumbersome as nodes grow. Using WireGuard to establish $\frac{n(n-1)}{2}$ tunnels, then using an internal routing protocol like OSPF or Babel to manage the routing. This is more flexible and easier to scale, but it can be risky and could break the DN42 network due to misconfigurations. Thus, I decided to take the risk. Node Topology graph LR A[HKG<br>172.20.234.225<br>fd18:3e15:61d0::1] B[NKG<br>172.20.234.226<br>fd18:3e15:61d0::2] C[TYO<br>172.20.234.227<br>fd18:3e15:61d0::3] D[FRA<br>172.20.234.228<br>fd18:3e15:61d0::4] E[LAX<br>172.20.234.229<br>fd18:3e15:61d0::5] B <--> A C <--> A A <--> E A <--> D C <--> D C <--> E D <--> E Update Bird2 to v2.16 or Above To use IPv6 Link-Local addresses to transmit IPv4 OSPF data, Bird v2.16 or later is required. Here are the steps to update: 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 Tunnel Configuration [Interface] PrivateKey = <Local WireGuard Private Key> ListenPort = <Listen Port> Table = off Address = <IPv6 LLA>/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <Peer Public Key> Endpoint = <Peer Public Endpoint> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8, ff02::5 ff02::5is the OSPFv3 router-specific link-local multicast address and should be included in AllowedIPs. If you're using Bird versions earlier than v2.16, you'll need to add an IPv4 address for the tunnel as well. See the example below: {collapse} {collapse-item label="WireGuard Configuration Example with IPv4"} [Interface] PrivateKey = <Local WireGuard Private Key> ListenPort = <Listen Port> 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 = <Peer Public Key> Endpoint = <Peer Public Endpoint> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 100.64.0.0/16, 172.31.0.0/16, fd00::/8, fe00::/8, ff02::5 Please replace 100.64.0.225 and 100.64.0.226 with your local and peer IPv4 addresses, and remember to add AllowedIPs. {/collapse-item} {/collapse} Enable OSPF You should have already configured basic Bird settings as described in the previous article. Create a new file called ospf.conf under /etc/bird and add the following: 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/*"; }; Theoretically, OSPF v2 should be used for handling IPv4, but since we need to communicate IPv4 using IPv6 Link-Local addresses, we are using OSPF v3 for IPv4 in this case as well. The filter rules ensure that only routes within the local network segment are allowed to propagate through OSPF, and routes from external BGP protocols are filtered out. Never use import all; export all; indiscriminately, as this could lead to route hijacking and affect the entire DN42 network. OSPF should only handle internal network routes. {collapse} {collapse-item label="Example"} /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} Next, create the /etc/bird/ospf folder and then create an area configuration file (e.g., /etc/bird/ospf/backbone.conf) with the following content: area 0.0.0.0 { interface "<DN42 dummy interface>" { stub; }; interface "<wg0 interface>" { cost 80; # Modify according to your network situation type ptp; }; interface "<wg1 interface>" { cost 100; # Modify according to your network situation type ptp; }; # Continue for other interfaces }; The 0.0.0.0 area represents the backbone network. he dummy interface here refers to the DN42 virtual interface mentioned in the previous article The cost value is typically used for cost calculation but in DN42's case, where bandwidth is less critical but latency is more important, you can directly assign the latency value. OSPF will automatically choose the route with the lowest cost (sum of the cost values). {collapse} {collapse-item label="Example"} /etc/bird/ospf/backbone.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} Finally, open /etc/bird/bird.conf and add the following to include the OSPF configuration file at the end: include "ospf.conf"; Run birdc configure, and then birdc show protocols should show the OSPF status as Running. If not, check the configuration steps for errors. At this point, you should be able to ping between two non-directly connected machines: Enable iBGP Before establishing multiple peer connections, each of your nodes must first have complete knowledge of the internal AS topology. This involves configuring another key component: internal BGP (iBGP). Necessity of iBGP iBGP ensures that all routers within the AS have complete knowledge of external destination routes. It ensures that: Internal routers can select the best exit path. Traffic is correctly routed to the boundary routers responsible for specific external networks. Even if there are multiple boundary routers connected to the same external network, internal routers can choose the best exit based on policies. Compared to using a default route pointing to the border router within the AS, iBGP provides precise external route information, allowing internal routers to make more intelligent forwarding decisions. Disadvantages and Solutions To prevent uncontrolled propagation of routing information within the AS, which could cause loops, an iBGP router will not readvertise routes learned from one iBGP neighbor to other iBGP neighbors. This necessitates that traditional iBGP requires a full mesh of iBGP neighbor relationships between all iBGP-running routers within the same AS. (You still need to establish $\frac{n(n+1)}{2}$ connections , there's no way around it. But configuring iBGP is still easier than configuring tunnels after OSPF is set up ). Solutions include: Using a Route Reflector (RR): An RR router manages all routing information within the entire AS. The disadvantage is that if the RR router fails, the entire network can be paralyzed (which is not very Decentralized). Using BGP Confederation: This involves virtually dividing the routers within the AS into sub-ASes, treating the connections between routers as eBGP, and finally stripping the internal AS path information when advertising routes externally. I haven't tried the latter two solutions. Here are some potentially useful reference articles. This article focuses on the configuration of iBGP. DN42 Experimental Network: Intro and Registration (Updated 2022-12) - Lan Tian @ Blog Configure BGP Confederation & Fake Confederation in Bird (Updated 2020-06-07) - Lan Tian @ Blog Writing the iBGP Configuration File Create a new file ibgp.conf in /etc/bird and fill it with the following content: 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; extended next hop; }; 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; }; }; include "ibgp/*"; The import and export filters ensure that iBGP only processes routes learned via the BGP protocol and filters out IGP routes to prevent loops. next hop self is required. It instructs BIRD to rewrite the next hop to the border router's own IP address (instead of the original external next hop) when exporting routes to iBGP neighbors. This is because internal routers cannot directly access the external neighbor's address; without rewriting, the address would be considered unreachable. After rewriting, internal routers only need to send traffic to the border router via IGP routing, and the border router handles the final external forwarding. Because I want to use IPv6 addresses to establish MP-BGP and route IPv4 over IPv6, extended next hop is enabled for IPv4. Next, create the /etc/bird/ibgp directory. Inside, create an iBGP Peer configuration file for each node: protocol bgp 'dn42_ibgp_<Node Name>' from ibgpeers{ neighbor <Corresponding Node's IPv6 ULA Address> as OWNAS; }; {collapse} {collapse-item label="Example"} /etc/bird/ibgp/hkg.conf: protocol bgp 'dn42_ibgp_HKG' from ibgpeers{ neighbor fd18:3e15:61d0::1 as OWNAS; }; {/collapse-item} {/collapse} Note: Each node needs to establish (n-1) iBGP connections, ensuring connectivity with all other machines within the AS. This is why ULA addresses are used. Using ULA addresses ensures that even if the WireGuard connection between two nodes goes down, iBGP can still establish connections via the internal routing established by OSPF. Otherwise, it could lead to the collapse of the entire internal network. Finally, add the inclusion of ibgp.conf in /etc/bird/bird.conf: include "ibgp.conf"; And run birdc configure to apply the configuration. References: BIRD 与 BGP 的新手开场 - 海上的宫殿 萌新入坑 DN42 之 —— 基于 tailscale + vxlan + OSPF 的组网 – 米露小窝 使用 Bird2 配置 WireGuard + OSPF 实现网络的高可用 | bs' realm DN42 实验网络介绍及注册教程(2022-12 更新) - Lan Tian @ Blog 如何引爆 DN42 网络(2023-05-12 更新) - Lan Tian @ Blog Bird 配置 BGP Confederation,及模拟 Confederation(2020-06-07 更新) - Lan Tian @ Blog 深入解析OSPF路径开销、优先级和计时器 - 51CTO New release 2.16 | BIRD Internet Routing Daemon 第一章·第二节 如何在 Linux 上安装最新版本的 BIRD? | BIRD 中文文档 [DN42] 使用 OSPF ptp 搭建内网与IBGP配置 – Xe_iu's Blog | Xe_iu的杂物间 [译] dn42 多服务器环境中的 iBGP 与 IGP 配置 | liuzhen932 的小窝
22/07/2025
353 Views
1 Comments
3 Stars
DN42 - Ep.1 Joining the DN42 Network
Foreword I am a novice in BGP. This article may contain imprecise content/naive understandings/elementary mistakes. I kindly ask the experts to be lenient. If you find any issues, you are welcome to contact me via email, and I will correct them as soon as possible. If you find this unacceptable, it is recommended to close this article now. Welcome to peer with me! For details, please visit: iYoRoy DN42 Network I wanted to study BGP, but renting an ASN and IP block is too expensive, and I was afraid of taking down half the internet due to a configuration error. So, I decided to look into DN42, a virtual network. DN42 is a large decentralized network that uses the BGP protocol for routing, making its structure very similar to today's internet. This makes it suitable for learning networking technologies like BGP. In DN42, everyone plays the role of an ISP (Internet Service Provider), peering with other users to join and participate in building the entire DN42 network. DN42 operates on 172.20.0.0/14 and fd00::/8, both of which are private address ranges, so it won't affect the clearnet. Registration You need to know basic git commands, GPG, and Linux. It's also best to sign your commits with GPG. If you have basic Git knowledge, you can refer to my commit: Add AS4242422024 · d1f9046ecb - registry - dn42 git Fork and Clone the DN42 Registry Git Repository Register an account on dn42 git and Fork the dn42/registry repository. Clone your forked repository and enter it. Register a Contact Create a file named <Nickname>-DN42 under data/person and fill in the following content: person: <Nickname> e-mail: <Email Address> pgp-fingerprint: <GPG Key Fingerprint> nic-hdl: <NIC Handle> mnt-by: <Maintainer> source: DN42 person: Nickname. e-mail: Email address. pgp-fingerprint: GPG key fingerprint, used for some authentication services. nic-hdl: NIC handle, points to the file itself, just use the current filename. mnt-by: Maintained by, points to the maintainer information from the Register Maintainer section below. source: Source, keep it as DN42. www: Optional, your website URL. {collapse} {collapse-item label="Example"} 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} Register a Maintainer Create a file data/mntner/<Nickname>-MNT and fill in the following content: mntner: <Nickname>-MNT admin-c: <Contact> tech-c: <Contact> auth: <Authentication Method> mnt-by: <Maintainer> source: DN42 mntner: Maintainer name, generally the same as the filename. admin-c: Administrator contact information, points to a file in the person folder, use the filename from the Register Contact section above. tech-c: Technical contact information, points to a file in the person folder, use the filename from the Register Contact section above. auth: Authentication method, supports pgp or ssh-key. mnt-by: Maintained by, generally points to the filename itself. source: Source, keep it as DN42. {collapse} {collapse-item label="Example"} 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} Register an ASN On the clearnet, 4200000000 - 4294967294 is the reserved range for ASNs. DN42 uses 4242420000 - 4242429999, and currently, 4242420000 - 4242423999 is open for registration.The official recommendation is not to manually find an available ASN but to use Burble's DN42 Free ASN Explorer to select an available ASN for registration. After choosing your desired ASN, create a file <ASN, including AS letters> in data/aut-num and fill in the following content: aut-num: <ASN> as-name: <Autonomous System Name> descr: <Autonomous System Description> admin-c: <Administrator NIC Handle> tech-c: <Technical Contact NIC Handle> mnt-by: <Maintainer> source: DN42 aut-num: Your chosen ASN, including the AS prefix. It should be in the format AS424242xxxx. as-name: Autonomous System Name. descr: Autonomous System Description, can contain spaces. admin-c: Administrator contact information, points to a file in the person folder, use the filename from the Register Contact section above. tech-c: Technical contact information, points to a file in the person folder, use the filename from the Register Contact section above. mnt-by: Maintained by, points to the filename from the Create Maintainer section above. source: Source, keep it as 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} Register an IPv4 Block and Add Route You can skip this section if you don't want to register IPv4 The official provides a tool for finding available address blocks: DN42 Free IPv4 Explorer. It is also not recommended to manually specify but to use the available blocks found through the search tool. DN42 also faces IPv4 address shortages, so please register according to your needs. Generally, a /27 block containing 30 usable IPv4 addresses is sufficient. For smaller networks, you can apply for /28 (14 usable addresses) and /29 (6 usable addresses). The largest block that can be directly applied for is /26, which is 62 addresses. Applying for /25, /24 requires submitting an application and waiting for review. For details, refer to: DN42 Experimental Network: Intro and Registration (Updated 2022-12) - Lan Tian @ Blog After selecting your IPv4 block, create a file in data/inetnum named after the CIDR format of the IPv4 block, using _ instead of / (e.g., if the applied IPv4 block is 172.20.234.224/28, the filename is 172.20.234.224_28), and fill in the content: inetnum: <First IPv4 Address in Block> - <Last IPv4 Address in Block> cidr: <IPv4 Block in CIDR Format> netname: <IPv4 Block Name> descr: <IPv4 Block Description> country: <Country Code for IPv4 Block> admin-c: <Administrator NIC Handle> tech-c: <Technical Contact NIC Handle> mnt-by: <Maintainer> status: ASSIGNED source: DN42 inetnum: IPv4 address range, from the first address to the last address, connected with -. cidr: IPv4 block in CIDR format, do not replace / with _. netname: IPv4 block name, fill in as desired, no special requirements. descr: IPv4 block description, can contain spaces. country: Two-character country code from ISO 3166, for China, fill in CN. admin-c: Administrator contact information, points to a file in the person folder, use the filename from the Register Contact section above. tech-c: Technical contact information, points to a file in the person folder, use the filename from the Register Contact section above. mnt-by: Maintained by, points to the filename from the Create Maintainer section above. status: Status, keep it as ASSIGNED. source: Source, keep it as DN42. {collapse} {collapse-item label="Example"} 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} Next, under data/route, create a file also named after the IPv4 block's CIDR format, using _ instead of /, and fill in the content: route: <IPv4 Block in CIDR Format> origin: <ASN> max-length: <IPv4 Prefix Length> mnt-by: <Maintainer> source: DN42 route: IPv4 block, fill in CIDR format, do not convert /. origin: ASN, needs to include AS prefix. max-lenth: Prefix Length, i.e., the number after / in the CIDR format. mnt-by: Maintained by, points to the filename from the Create Maintainer section above. source: Source, keep it as DN42. {collapse} {collapse-item label="Example"} 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} Register an IPv6 Block and Add Route You can skip this section if you don't want to register IPv6 Similarly, use the official tool to find available IPv6: DN42 Free IPv6 Explorer 。 After selecting the address block, create a file under data/inet6num named after the IPv6 block's CIDR format, using _ instead of / (e.g., if the IPv6 block is fd18:3e15:61d0::/48, the filename is fd18:3e15:61d0::_48), and fill in the content: inet6num: <First IPv6 Address in Block> - <Last IPv6 Address in Block> cidr: <IPv6 Block in CIDR Format> netname: <IPv6 Block Name> descr: <IPv6 Block Description> country: <Country Code for IPv6 Block> admin-c: <Administrator NIC Handle> tech-c: <Technical Contact NIC Handle> mnt-by: <Maintainer> status: ASSIGNED source: DN42 inet6num: IPv6 address range, from the first address to the last address, cannot use :: shorthand, connected with -. For example, if my block is fd18:3e15:61d0::/48, I need to fill in fd18:3e15:61d0:0000:0000:0000:0000:0000 - fd18:3e15:61d0:ffff:ffff:ffff:ffff:ffff. cidr: IPv6 block in CIDR format, do not replace / with _. netname: IPv6 block name, fill in as desired, no special requirements descr: IPv6 block description, can contain spaces country: Two-character country code from ISO 3166, for China, fill in CN. admin-c: Administrator contact information, points to a file in the person folder, use the filename from the Register Contact section above. tech-c: Technical contact information, points to a file in the person folder, use the filename from the Register Contact section above. mnt-by: Maintained by, points to the filename from the Create Maintainer section above. status: Status, keep it as ASSIGNED. source: Source, keep it as DN42. {collapse} {collapse-item label="Example"} 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} Next, under data/route6, create a file also named after the IPv6 block's CIDR format, using _ instead of /, and fill in the content: route6: <IPv6 Block in CIDR Format> origin: <ASN> max-length: <IPv6 Prefix Length> mnt-by: <Maintainer> source: DN42 route6: IPv6 block, fill in CIDR format, do not convert /. origin: ASN, needs to include AS prefix. max-lenth: Prefix Length, i.e., the number after / in the CIDR format. mnt-by: Maintained by, points to the filename from the Create Maintainer section above. source: Source, keep it as DN42. {collapse} {collapse-item label="Example"} 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} Create and Push Commit, Submit PR It's best to sign your commits with GPG and upload your public key to dn42 git. After filling in the above information, return to the root directory of the repository and run the script ./fmt-my-stuff <Maintainer> to automatically format the configuration files. Note: Here <Maintainer> is the value of mntner from the Register Maintainer chapter. Then follow the normal git commit process: git add data/, git commit -S -m "<commit-msg>" to create the commit, git push origin master to push. Then, go to the dn42 git web interface, open your forked repository, and submit a Pull Request. If there are configuration issues, the automated review bot and administrators will inform you. Please patiently modify according to the requirements and merge into the original commit, do not create a new commit. It is recommended to use git commit --amend after git add. After modification, force push directly (git push origin master --force). The working language of the DN42 Registry is English. Please use English for the entire process to avoid unnecessary trouble. Configuring Bird First, install bird. Using Ubuntu 22.04 as an example: apt install bird2 -y If you also want to install WireGuard for later use, add the wireguard and wireguard-tools packages: apt install bird2 wireguard wireguard-tools -y Create Configuration Files bird.conf Modify /etc/bird/bird.conf: define OWNAS = <AS Number>; define OWNIP = <DN42 IPv4 Address>; define OWNIPv6 = <DN42 IPv6 Address>; define OWNNET = <DN42 IPv4 Block, CIDR Format>; define OWNNETv6 = <DN42 IPv6 Block, CIDR Format>; define OWNNETSET = [ <DN42 IPv4 Block, CIDR Format>+ ]; define OWNNETSETv6 = [ <DN42 IPv6 Block, CIDR Format>+ ]; 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"; Here, the OWNIP and OWNIPV6 parameters refer to the DN42 IPv4 and IPv6 addresses assigned to this machine, not the address of the block. For example, if I obtained the address segment 172.20.234.224/28 and assigned 172.20.234.225 to machine A, then OWNIP is 172.20.234.225. The same applies to IPv6. rpki.conf You might have seen other tutorials using cron jobs + reloading Bird to update ROAs. Configuring RPKI here is another way to configure ROAs. Create /etc/bird/rpki.conf and fill in the following content: 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 server address>" port 8082; # change it refresh 30; retry 5; expire 600; } For the RPKI server, you can use the service provided by my friend's AkaereIX: rpki.akae.re. {collapse} {collapse-item label="Example"} 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 Create /etc/bird/ebgp.conf and fill in the following content: 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/*"; This configuration defines a template for peering within DN42 and references all configuration files under /etc/bird/peers. Later, when we peer, we only need to create configuration files here according to the template and write them. Create the /etc/bird/peers folder for subsequent peering. System Configuration Kernel Because each node may act as a router for other nodes, Linux kernel packet forwarding needs to be enabled. Also, because WireGuard is used, which doesn't forward through physical network cards, the rp_filter strict mode needs to be disabled. 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 Virtual Network Interface Because MP-BGP typically uses LLA addresses to establish BGP sessions, we need to set up a dummy network interface in the system and bind the DN42 IP we assigned to this machine. Run the following commands: ip link add dn42 type dummy ip addr add <DN42 IPv4 assigned to this machine> dev dn42 ip addr add <DN42 IPv6 assigned to this machine> dev dn42 If persistent configuration is needed, you can refer to the following three methods: {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 assigned to this machine>/32 Address=<DN42 IPv6 assigned to this machine>/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 assigned to this machine>/32 - "<DN42 IPv6 assigned to this machine>/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 assigned to this machine> netmask 255.255.255.255 iface dn42 inet6 static address <DN42 IPv6 assigned to this machine>/128 EOF ifup dn42 {/tabs-pane} {/tabs} Peering with Other Members A user-friendly option for beginners is Potat0's self-service peering service. For details, refer to his DN42 Network page. Follow the instructions to find his Automatic Peering Bot, register your account with the bot by providing your DN42 ASN, the email recorded in the Maintainer during registration above (this is why it's best to fill in the email during registration, as many verification services use it), and receive the verification code with that email. Then, follow the bot's requirements to establish the peer. Install WireGuard apt install wireguard wireguard-tools -y Note: Modern package managers usually automatically install wireguard-tools when installing wireguard to use the wg-quick command. Generate Key Pair wg genkey | tee privatekey | wg pubkey > publickey Note down the contents of privatekey and publickey, representing the private and public keys respectively. Establishing a Peer Generally, there are two modes for establishing a peer: using MP-BGP (Multiprotocol BGP) and not using MP-BGP. Personally, I find MP-BGP more common because its configuration is relatively simple. The configurations are slightly different, so please refer according to your needs. Using MP-BGP Exchanging Information with the Peer You need to provide the other party with the following information, and you also need to know the other party's corresponding information: Public Key Public IP Address (non-DN42 address) Public WireGuard Port, usually listening on the last 5 digits of the other party's ASN DN42 ASN LLA (Link-Local Address), generally fe80::<last 4 digits of peer's ASN> Whether ENH (Extended Next Hop) is supported. Note: If using v6 to exchange routes without enabling ENH, v4 routes cannot be exchanged. Sometimes the public IP address and public WG port are combined and called the Endpoint. Configuring WireGuard Create a configuration file under /etc/wireguard. The name is arbitrary, but my naming convention is dn42-<last 4 digits of peer's ASN>.conf, where dn42-xxxx is the tunnel name. Fill the file with the following content: [Interface] PrivateKey = <Private key generated in the "Generate Key Pair" section above> ListenPort = <Public WireGuard Listen Port> Table = off Address = <Your LLA Address>/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <Peer's Public Key> Endpoint = <Peer's Endpoint, i.e., IP:Port> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 After editing and saving, run: wg-quick up <Tunnel Name> This will start the WG tunnel. Use wg show <Tunnel Name> to check the connection status. Running wg directly shows the status of all tunnels. If you want the tunnel to start automatically on boot, run: systemctl enable wg-quick@<Tunnel Name> Configuring the Bird2 Peer Section Create a new file <Name>.conf under /etc/bird/peers and fill in the following content: protocol bgp <BGP Session Name> from dnpeers{ neighbor <Peer's LLA Address> % '<WireGuard Tunnel Name>' as <Peer's ASN, without AS prefix>; }; If Extended Next Hop is used (as negotiated during information exchange above), configure: protocol bgp <BGP Session Name> from dnpeers{ neighbor <Peer's LLA Address> % '<WireGuard Tunnel Name>' as <Peer's ASN, without AS prefix>; ipv4{ extended next hop; }; }; Applying Configuration Run birdc configure (or birdc c, equivalent) to reload the Bird configuration, then run birdc show protocols (or birdc s p, equivalent) to view the currently established BGP connections. 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 Not Using MP-BGP Exchanging Information with the Peer You need to provide the other party with the following information, and you also need to know the other party's corresponding information: Public Key Public IP Address (non-DN42 address) Public WireGuard Port, usually listening on the last 5 digits of the other party's ASN DN42 ASN DN42 IP, if exchanging IPv4 routes, an IPv4 address is needed; if exchanging IPv6 routes, an IPv6 address is needed. Sometimes the public IP address and public WG port are combined and called the Endpoint. Configuring WireGuard Create a configuration file under /etc/wireguard. The name is arbitrary, but my naming convention is dn42-<last 4 digits of peer's ASN>.conf, where dn42-xxxx is the tunnel name. Fill the file with the following content: [Interface] PrivateKey = <Private key generated in the "Generate Key Pair" section above> ListenPort = <Public WireGuard Listen Port> Table = off PostUp = ip addr add <LLA>/64 dev %i PostUp = ip addr add <Local DN42 IPv6> dev %i PostUp = ip addr add <Local DN42 IPv4> peer <Peer's DN42 IPv4> dev %i PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <Peer's Public Key> Endpoint = <Peer's Endpoint, i.e., IP:Port> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 After editing and saving, run: wg-quick up <Tunnel Name> This will start the WG tunnel. Use wg show <Tunnel Name> to check the connection status. Running wg directly shows the status of all tunnels. If you want the tunnel to start automatically on boot, run: systemctl enable wg-quick@<Tunnel Name> Configuring the Bird2 Peer Section Create a new file <Name>.conf under /etc/bird/peers and fill in the following content: protocol bgp <v4 BGP Session Name> from dnpeers{ neighbor <Peer's DN42 IPv4 Address> as <Peer's ASN, without AS prefix>; direct; ipv6{ import none; export none; }; }; protocol bgp <v6 BGP Session Name> from dnpeers{ neighbor <Peer's DN42 IPv6 Address> % '<WireGuard Tunnel Name>' as <Peer's ASN, without AS prefix>; direct; ipv4{ import none; export none; }; }; Applying Configuration Run birdc configure (or birdc c, equivalent) to reload the Bird configuration, then run birdc show protocols (or birdc s p, equivalent) to view the currently established BGP connections. At this point, we have successfully joined the DN42 network. To make the network more stable, we can peer with more users, establishing multiple BGP lines to prevent disconnection if some nodes fail. You can join the DN42 Unofficial Telegram Group for more information. If BGP is Established but you cannot Ping internal DN42 IPs, check if the IP set in bird.conf matches the IP assigned to the dummy interface or the local IP in WireGuard. Configuring DNS DN42 has its own public DNS with the anycast address 172.20.0.53, which can also resolve normal internet domains. To access internal domains ending with .dn42, you need to put this address at the top of resolv.conf: nameserver 172.20.0.53 nameserver 223.5.5.5 # Below are normal DNS server configurations After this, you can resolve DN42 internal domain names. Also, commands like ping, traceroute, and mtr will show rDNS resolution results when querying internal IPs. Welcome to peer with me! For details, please visit: iYoRoy DN42 Network References: 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
28/06/2025
453 Views
3 Comments
2 Stars
1
2
3