<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BGP on Sisy's Blog</title><link>https://blog.sisy.cc/tags/bgp/</link><description>Recent content in BGP on Sisy's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 23 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.sisy.cc/tags/bgp/index.xml" rel="self" type="application/rss+xml"/><item><title>从零开始接入 DN42 网络 - 3: Dummy 网卡创建与保持、ROA 配置</title><link>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-3-dummy-%E7%BD%91%E5%8D%A1%E5%88%9B%E5%BB%BA%E4%B8%8E%E4%BF%9D%E6%8C%81roa-%E9%85%8D%E7%BD%AE/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-3-dummy-%E7%BD%91%E5%8D%A1%E5%88%9B%E5%BB%BA%E4%B8%8E%E4%BF%9D%E6%8C%81roa-%E9%85%8D%E7%BD%AE/</guid><description>&lt;img src="https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-3-dummy-%E7%BD%91%E5%8D%A1%E5%88%9B%E5%BB%BA%E4%B8%8E%E4%BF%9D%E6%8C%81roa-%E9%85%8D%E7%BD%AE/img/cover.png" alt="Featured image of post 从零开始接入 DN42 网络 - 3: Dummy 网卡创建与保持、ROA 配置" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;2026-05-01 更新：配置在 dummy 网卡上的 IP 段 v4:&lt;code&gt;/27&lt;/code&gt; 和 v6:&lt;code&gt;/48&lt;/code&gt; 分别改为 &lt;code&gt;/32&lt;/code&gt; 和 &lt;code&gt;/128&lt;/code&gt;
这包括 &lt;code&gt;/etc/netplan/60-dn42-dummy.yaml&lt;/code&gt; 中的配置，以及文中示例命令 &lt;code&gt;ip addr add dev dn42-dummy &amp;lt;路由器IP&amp;gt;/&amp;lt;子网&amp;gt;&lt;/code&gt; 中的 &lt;code&gt;&amp;lt;子网&amp;gt;&lt;/code&gt; 部分。
如果需要配置内网，这里不应该填自己分配到的整个 IP 段，否则会导致后续配置内网 IGP 时出现问题：
例如对于 IPv4，如果给网卡配置 fd24:ac8e:9e04::3/48，内网的两个节点都会通过 direct protocol 产生同一条 /48 的路由，内核会把去往 ::2 的包直接丢给 dummy 接口（本地连接路由），而不是走隧道。
改为 fd24:ac8e:9e04::3/128 后，direct protocol 产生的是主机路由，每个节点通过 Babel/OSPF 等协议，只通告自己的 loopback 地址，对端就能学到一条指向隧道的具体路由。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="前言"&gt;前言
&lt;/h2&gt;&lt;p&gt;在前两篇文章里我们已经完成了 DN42 网络的注册和 Bird2 的基础配置，接下来首先必须创建一个 dummy 网卡来承载 BGP 协议的 IP 地址，之后还要配置 ROA 来让 Bird 能够正确地验证路由的合法性。&lt;/p&gt;
&lt;h2 id="dummy-网卡创建与保持"&gt;Dummy 网卡创建与保持
&lt;/h2&gt;&lt;p&gt;DN42 网络中 BGP 协议的 IP 地址是不会绑定在物理网卡上的，而是绑定在一个 dummy 网卡上，它作为虚拟的网络接口来承载这些 IP 地址，而 Bird 会监听这个接口来进行 BGP 通信。&lt;/p&gt;
&lt;p&gt;创建 dummy 接口：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link add dn42-dummy &lt;span class="nb"&gt;type&lt;/span&gt; dummy
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; dev dn42-dummy up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;为其分配此路由器的 IP 地址（对 ipv4 和 ipv6 都要执行一次）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip addr add dev dn42-dummy &amp;lt;路由器IP&amp;gt;/&amp;lt;子网&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需要注意这里的 IP 指的是 DN42 网络中选定的 IP 地址，而不是主机的真实公网 IP。&lt;/p&gt;
&lt;p&gt;然而这些命令是临时生效的，重启后会丢失。如果需要维持这个 dummy 网卡的配置在重启后不变，可以把这些命令写入系统的网络配置中，例如我的 Ubuntu 24.04 默认使用 Netplan 管理网络，可以创建一个新的 Netplan 配置文件 &lt;code&gt;/etc/netplan/60-dn42-dummy.yaml&lt;/code&gt; 来定义这个 dummy 网卡：（注意这里提到的两个地址段应当调整）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dummy-devices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dn42-dummy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;addresses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;172.23.15.34&lt;/span&gt;&lt;span class="l"&gt;/27&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;fd24:ac8e:9e04::2/48&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;保存后执行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;600&lt;/span&gt; /etc/netplan/60-dn42-dummy.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netplan apply
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;来设置安全的权限并应用配置。如果不设置 600 权限，可能会在 apply 时遇到以下 warning：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-plaintext" data-lang="plaintext"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;** (generate:924409): WARNING **: 03:49:04.343: Permissions for /etc/netplan/60-dn42-dummy.yaml are too open. Netplan configuration should NOT be accessible by others.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="roa-配置"&gt;ROA 配置
&lt;/h2&gt;&lt;p&gt;ROA 表一般是由社区维护的一个公共资源，包含了 DN42 网络中所有合法的路由前缀和它们对应的 ASN 信息。&lt;/p&gt;
&lt;p&gt;可以直接从注册中心生成，也可以用下面这些预构建的 BIRD ROA 表，我用的是 burble 源里列出的最后两个表：&lt;/p&gt;
&lt;p&gt;由 &lt;a class="link" href="https://git.burble.com/burble.dn42/dn42regsrv" target="_blank" rel="noopener"
 &gt;dn42regsrv&lt;/a&gt; 生成的 ROA 文件可从 burble.dn42 获取：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;URL&lt;/th&gt;
 &lt;th&gt;IPv4/IPv6&lt;/th&gt;
 &lt;th&gt;说明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_46.json" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_46.json&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;两者皆有&lt;/td&gt;
 &lt;td&gt;用于 RPKI 的 JSON 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird1_46.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird1_46.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;两者皆有&lt;/td&gt;
 &lt;td&gt;Bird1 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird1_4.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird1_4.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv4&lt;/td&gt;
 &lt;td&gt;Bird1 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird1_6.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird1_6.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv6&lt;/td&gt;
 &lt;td&gt;Bird1 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird2_46.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird2_46.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;两者皆有&lt;/td&gt;
 &lt;td&gt;Bird2 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird2_4.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird2_4.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv4&lt;/td&gt;
 &lt;td&gt;Bird2 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://dn42.burble.com/roa/dn42_roa_bird2_6.conf" target="_blank" rel="noopener"
 &gt;https://dn42.burble.com/roa/dn42_roa_bird2_6.conf&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv6&lt;/td&gt;
 &lt;td&gt;Bird2 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;由 &lt;a class="link" href="https://github.com/Kioubit/dn42_registry_wizard" target="_blank" rel="noopener"
 &gt;roa_wizard&lt;/a&gt; 生成的 ROA 文件可从 kioubit.dn42 获取：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;URL&lt;/th&gt;
 &lt;th&gt;IPv4/IPv6&lt;/th&gt;
 &lt;th&gt;说明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://kioubit-roa.dn42.dev/?type=v4" target="_blank" rel="noopener"
 &gt;https://kioubit-roa.dn42.dev/?type=v4&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv4&lt;/td&gt;
 &lt;td&gt;Bird2 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://kioubit-roa.dn42.dev/?type=v6" target="_blank" rel="noopener"
 &gt;https://kioubit-roa.dn42.dev/?type=v6&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;仅 IPv6&lt;/td&gt;
 &lt;td&gt;Bird2 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://kioubit-roa.dn42.dev/?type=json" target="_blank" rel="noopener"
 &gt;https://kioubit-roa.dn42.dev/?type=json&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;两者皆有&lt;/td&gt;
 &lt;td&gt;用于 RPKI 的 JSON 格式&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;为了即时生效，并且能定时更新到最新的 ROA 表，我们分两步走：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;先简单地手动下载最新的 ROA 表到本地，并放到 Bird 的配置目录下，以便直接跑通 Bird 服务。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -4 -O /tmp/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; mv -f /tmp/roa_dn42.conf /etc/bird/roa_dn42.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget -4 -O /tmp/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; mv -f /tmp/roa_dn42_v6.conf /etc/bird/roa_dn42_v6.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 cron 或者 systemd timer 定时执行一个脚本来定期更新 ROA 表，这里我还是用 cron。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;0&lt;/span&gt; * * * * wget -4 -O /tmp/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; mv -f /tmp/roa_dn42.conf /etc/bird/roa_dn42.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; wget -4 -O /tmp/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; mv -f /tmp/roa_dn42_v6.conf /etc/bird/roa_dn42_v6.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; birdc c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个 cron job 每小时执行一次，下载最新的 ROA 表并替换掉旧的文件，最后执行 &lt;code&gt;birdc c&lt;/code&gt; 来让 Bird 重新加载配置，使新的 ROA 表生效。&lt;/p&gt;
&lt;p&gt;现在 ROA 配置好了，Bird 就能够正确地运行了，下一步就可以直接开始添加 Peer 了。运行一下 &lt;code&gt;birdc c&lt;/code&gt; 来跑通 Bird 服务，输出应该类似于：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-plaintext" data-lang="plaintext"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BIRD 2.18.1 ready.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Reading configuration from /etc/bird/bird.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Reconfigured
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>从零开始接入 DN42 网络 - 2: DN42 的 Bird2 配置</title><link>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-2-dn42-%E7%9A%84-bird2-%E9%85%8D%E7%BD%AE/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-2-dn42-%E7%9A%84-bird2-%E9%85%8D%E7%BD%AE/</guid><description>&lt;img src="https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-2-dn42-%E7%9A%84-bird2-%E9%85%8D%E7%BD%AE/img/cover.png" alt="Featured image of post 从零开始接入 DN42 网络 - 2: DN42 的 Bird2 配置" /&gt;&lt;h2 id="前言"&gt;前言
&lt;/h2&gt;&lt;p&gt;在 dn42-registry 仓库里把身份注册了之后，除去搭建 VPN 隧道外，下一步就是配置 BGP 路由守护进程了。DN42 网络中我还是习惯用 Bird2 作为 BGP 来管理路由。&lt;/p&gt;
&lt;p&gt;Bird2 的配置文件相对来说比较复杂，包含了全局设置、协议定义、路由过滤等多个部分。而且 DN42 自己的 wiki 没有做 i18n，这个等以后熟悉社区了跟维护者沟通吧。&lt;/p&gt;
&lt;p&gt;时隔一个月，借这篇博客详细解释、记录一下 wiki 里提供的标准配置示例各部分的意思。整体思路就是先把大的 &lt;code&gt;bird.conf&lt;/code&gt; 文件搭建好。这里面会依赖外部引入的 ROA 表和对等方配置，ROA 表是起 Bird 服务所必须的；对等方配置可以依赖 &lt;code&gt;bird.conf&lt;/code&gt; 中定义的模板来简化配置，后续添加新的对等方时只需要写一个小的配置文件就行了。后续流程还包括创建一个 dummy 网卡，再往后还有 BGP Community 配置、RPKI 配置和开启 BFD 之类的。&lt;/p&gt;
&lt;h2 id="bird2-配置详解"&gt;Bird2 配置详解
&lt;/h2&gt;&lt;p&gt;&lt;em&gt;官方文章：&lt;a class="link" href="https://dn42.dev/howto/Bird2" target="_blank" rel="noopener"
 &gt;Bird2&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="全局变量定义"&gt;全局变量定义
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNAS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;OWNAS&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNIP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;OWNIP&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNIPv6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;OWNIPv6&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNNET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;OWNNET&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNNETv6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;OWNNETv6&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNNETSET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;[&amp;lt;OWNNET&amp;gt;+];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;define OWNNETSETv6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;[&amp;lt;OWNNETv6&amp;gt;+];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这一段用 &lt;code&gt;define&lt;/code&gt; 定义了一些 ASN、IP 段相关的全局变量，方便后面多次复用，写过代码的话应该都懂。&lt;code&gt;OWNNETSET&lt;/code&gt; 和 &lt;code&gt;OWNNETSETv6&lt;/code&gt; 是前缀集合（prefix set），加了 &lt;code&gt;+&lt;/code&gt; 表示匹配该前缀及其所有更长的子前缀。&lt;/p&gt;
&lt;p&gt;之所以要同时定义 &lt;code&gt;OWNNET&lt;/code&gt; 和 &lt;code&gt;OWNNETSET&lt;/code&gt; 两个变量，是因为 Bird 在某些语法场景下（比如 &lt;code&gt;route ... reject&lt;/code&gt;）需要单个前缀，而在过滤器中做匹配（&lt;code&gt;net ~&lt;/code&gt;）时需要集合，Bird 的变量解析机制不允许在集合字面量中直接内嵌变量。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="基础设置"&gt;基础设置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;router id OWNIP;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;protocol device {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;scan time 10;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;router id&lt;/code&gt; 用这台主机的 IPv4 地址全局变量作为路由器的全局标识符，BGP 要求每个路由器有唯一 ID。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;protocol device&lt;/code&gt; 让 Bird 每 10 秒扫描一次系统网络接口的状态变化（如接口 up/down、地址增删）。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="工具函数"&gt;工具函数
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;function is_self_net() -&amp;gt; bool {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;return net ~ OWNNETSET;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;function is_self_net_v6() -&amp;gt; bool {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;return net ~ OWNNETSETv6;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;意思基本显然且平凡，即判断当前路由的前缀是否属于本 AS 自己的网段，下文中的过滤器 &lt;code&gt;filter&lt;/code&gt; 中会用来避免从外部邻居那里接受自己的前缀，以防止路由环路。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;function is_valid_network() -&amp;gt; bool {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;return net ~ [&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.20.0.0/14{21,29},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.20.0.0/24{28,32},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;10.0.0.0/8{15,24}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.20.0.0/14{21,29}, # dn42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.20.0.0/24{28,32}, # dn42 Anycast&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.21.0.0/24{28,32}, # dn42 Anycast&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.22.0.0/24{28,32}, # dn42 Anycast&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.23.0.0/24{28,32}, # dn42 Anycast&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;172.31.0.0/16+, # ChaosVPN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;10.100.0.0/14+, # ChaosVPN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;10.127.0.0/16+, # neonetwork&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;10.0.0.0/8{15,24} # Freifunk.net&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;function is_valid_network_v6() -&amp;gt; bool {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;return net ~ [&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;fd00::/8{44,64} # ULA address space as per RFC 4193&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一个白名单过滤器，定义了 dn42 生态中所有合法的 IPv4 地址范围。&lt;code&gt;{21,29}&lt;/code&gt; 的语法表示前缀长度必须在 21 到 29 之间。不在此范围内的路由一律拒绝，==防止对等方泄漏公网路由或其他无关路由进来==。各段分别对应注释中的不同网络。除了官方分配的地址段之外，还有一些社区网络（如 ChaosVPN、neonetwork、Freifunk.net）也在 dn42 中使用了自己的地址段。&lt;/p&gt;
&lt;p&gt;IPv6 版本类似，只接受 &lt;code&gt;fd00::/8{44,64}&lt;/code&gt;，即 RFC 4193 定义的 ULA（唯一本地地址）空间。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="roa-表路由源授权"&gt;ROA 表（路由源授权）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;roa4 table dn42_roa;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;roa6 table dn42_roa_v6;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;protocol static {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;roa4 { table dn42_roa; };&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;include &amp;#34;/etc/bird/roa_dn42.conf&amp;#34;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;protocol static {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;roa6 { table dn42_roa_v6; };&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;include &amp;#34;/etc/bird/roa_dn42_v6.conf&amp;#34;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;声明了两张 ROA 表（IPv4 和 IPv6），并通过 &lt;code&gt;include&lt;/code&gt; 从外部文件加载 ROA 数据。&lt;/p&gt;
&lt;p&gt;ROA 数据的本质是&amp;quot;哪个 ASN 被授权通告哪个前缀&amp;quot;的映射关系。下文中的 BGP 过滤器会用 &lt;code&gt;roa_check()&lt;/code&gt; 查询这张表来验证路由的合法性。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="kernel-协议bird---系统内核"&gt;Kernel 协议（Bird &amp;lt;-&amp;gt; 系统内核）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;protocol kernel {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;scan time 20;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ipv4 {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;import none;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;export filter {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;if source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;RTS_STATIC then reject;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; krt_prefsrc = OWNIP;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; accept;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; };&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;控制 Bird 与 Linux 内核路由表之间的同步：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;import none&lt;/strong&gt;：不从内核路由表导入任何路由到 Bird,从而限制 Bird 仅通过 BGP 学习路由）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;export filter&lt;/strong&gt;：将 Bird 学到的路由写入内核，但排除静态路由（&lt;code&gt;RTS_STATIC&lt;/code&gt;），因为静态路由只是占位用的（见下文），不需要写入内核。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;krt_prefsrc = OWNIP&lt;/strong&gt;：设置导出到内核的路由的首选源地址，确保主机（即该路由器）向 dn42 发出的数据包使用自己的 dn42 IP 作为源地址，而不是随机选一个。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IPv6 同理。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="静态路由前缀通告的来源"&gt;静态路由（前缀通告的来源）
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;protocol static {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;route OWNNET reject;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ipv4 {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;import all;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;export none;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;声明一条 &lt;code&gt;reject&lt;/code&gt; 类型的静态路由，目的不是为了真正路由流量，而是让 Bird 内部有一条自己网段的路由记录。&lt;/p&gt;
&lt;p&gt;BGP 的 export filter 中检查 &lt;code&gt;source ~ [RTS_STATIC, RTS_BGP]&lt;/code&gt;，这条静态路由满足 &lt;code&gt;RTS_STATIC&lt;/code&gt; 条件，从而被通告给邻居——也就是告诉整个 dn42：&amp;ldquo;我拥有这个前缀，请把目的地是这个前缀的流量发给我。&amp;rdquo; &lt;code&gt;reject&lt;/code&gt; 类型意味着如果真有流量到达但没有更具体的路由可匹配，就丢弃（黑洞路由），这是正常行为。&lt;/p&gt;
&lt;p&gt;ipv6 同理。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="bgp-模板-core-part"&gt;BGP 模板 (Core part)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;template bgp dnpeers {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;local as OWNAS;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;path metric on;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ipv4 {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;&amp;lt;import filter part&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;&amp;lt;export filter part&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ipv6 {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;&amp;lt;import filter part&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;&amp;lt;export filter part&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;template&lt;/code&gt; 定义了一个可复用的 BGP 配置模板，所有 dn42 对等方都继承它，避免重复配置。&lt;code&gt;path metric on&lt;/code&gt; 表示 AS 路径中每一跳的代价为 1，Bird 会优选 AS path 最短的路由。&lt;/p&gt;
&lt;p&gt;以下是 import/export filter 的具体内容，ipv4 和 ipv6 的过滤器内容相同，分别放在对应的 &lt;code&gt;ipv4&lt;/code&gt; 和 &lt;code&gt;ipv6&lt;/code&gt; 块中。&lt;/p&gt;
&lt;h4 id="import-filter入站过滤"&gt;Import Filter（入站过滤）
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;import filter {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;if is_valid_network() &amp;amp;&amp;amp; !is_self_net() then {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;if (roa_check(dn42_roa, net, bgp_path.last) !&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ROA_VALID) then {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; # Reject when unknown or invalid according to ROA
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; print &amp;#34;[dn42] ROA check failed for &amp;#34;, net, &amp;#34; ASN &amp;#34;, bgp_path.last;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; reject;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; } else accept;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; } else reject;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安全检查，由外到内：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;前缀必须在 dn42 合法范围内，且不接受自己的前缀从别人那里传回来，以防环路。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;roa_check()&lt;/code&gt; 验证通告这个前缀的最终 ASN（&lt;code&gt;bgp_path.last&lt;/code&gt;）是否被 ROA 表授权。不是 &lt;code&gt;ROA_VALID&lt;/code&gt; 的一律拒绝，并打印日志。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;全部通过则 accept。&lt;/p&gt;
&lt;h4 id="export-filter出站过滤"&gt;Export Filter（出站过滤）
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;export filter {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;if is_valid_network() &amp;amp;&amp;amp; source ~ [RTS_STATIC, RTS_BGP] then accept;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;else reject;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;只通告属于 dn42 合法范围的、且来源是静态路由（自己的前缀）或 BGP 学来的路由。避免将内核路由、直连路由等无关路由泄漏出去。&lt;/p&gt;
&lt;h4 id="import-limit"&gt;Import Limit
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;import limit 9000 action block;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果从单个对等方收到超过 9000 条路由，就阻断该会话。这是一种安全机制，防止某个对等方因配置错误向本端泄漏海量路由（比如全表泄漏），保护主机的内存以及稳定性。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="引入对等方配置"&gt;引入对等方配置
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;include &amp;#34;/etc/bird/peers/*&amp;#34;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;从 &lt;code&gt;/etc/bird/peers/&lt;/code&gt; 目录加载所有对等方的配置文件。一般来说每次创建一个 peer 时，只需要在该目录下创建一个与该 peer 对应的配置文件即可。每个配置文件中定义一个 &lt;code&gt;protocol bgp ... from dnpeers&lt;/code&gt; 实例，继承上面提到的模板，基本上只需要填入邻居的 IP 和 ASN 就行了。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="整体数据流"&gt;整体数据流
&lt;/h3&gt;&lt;p&gt;整个配置的数据流思路：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由器（即这台主机）通过静态路由声明自己拥有的前缀，BGP 模板将其通告给所有对等方；&lt;/li&gt;
&lt;li&gt;从对等方接收路由时经过白名单、防环、ROA 的各个验证，合格的路由写入内核路由表（附带正确的源地址），从而使路由器能够正确地转发 dn42 流量。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>从零开始接入 DN42 网络 - 1: 注册与身份认证</title><link>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-1-%E6%B3%A8%E5%86%8C%E4%B8%8E%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81/</link><pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-1-%E6%B3%A8%E5%86%8C%E4%B8%8E%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81/</guid><description>&lt;img src="https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-1-%E6%B3%A8%E5%86%8C%E4%B8%8E%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81/img/cover.png" alt="Featured image of post 从零开始接入 DN42 网络 - 1: 注册与身份认证" /&gt;&lt;h2 id="前言"&gt;前言
&lt;/h2&gt;&lt;p&gt;一开始听说 BGP 还真不是从大黑书里，而是 MoonWX 玩 DN42 的时候一直给我安利。这下不得不玩一玩了。简单了解下来，DN42 确实是一个很适合学习真正的公网环境是如何运行的&lt;a class="link" href="https://zh.wikipedia.org/wiki/%e8%a6%86%e7%9b%96%e7%bd%91%e7%bb%9c" target="_blank" rel="noopener"
 &gt;叠加网络&lt;/a&gt;。DN42 趣味在于调试的过程，不过接入这一块基本上也就是按照教程走，顺带在接入过程中学习一些网络知识，除了对等连接 (Peer) 这一步需要费些功夫配置。&lt;/p&gt;
&lt;p&gt;本文大量参考了 DN42 的官方文档和一些社区资源，尤其是 &lt;a class="link" href="https://dn42.dev/wiki/Main_Page" target="_blank" rel="noopener"
 &gt;DN42 Wiki&lt;/a&gt; 和&lt;a class="link" href="https://lantian.pub/article/modify-website/dn42-experimental-network-2020.lantian/" target="_blank" rel="noopener"
 &gt;蓝天大佬的博客文章&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="大致思路"&gt;大致思路
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;要接入一个网络，首先你需要在网络内有一个“身份”，包含一个 ASN（自治系统编号）、一个 IPv4 地址段（也可包含 IPv6 地址段）、该 ASN 的管理者、能够证明身份的通信凭证（auth key 之类）、联系方式等。&lt;/li&gt;
&lt;li&gt;以上身份中的大多数内容是由自己来选择和定义的，但是需要先提交申请，并被批准，整个网络才会认可你的身份。&lt;/li&gt;
&lt;li&gt;在 DN42 中，没有真正意义上的“接入点”，你可以在任何地方通过 VPN（如 WireGuard）连接到 DN42 网络中的其他节点来实现接入。这一步即是寻找其他节点并建立对等连接（Peer），需要配置好隧道软件 (VPN) 和 BGP 软件相关的设置。&lt;/li&gt;
&lt;li&gt;同时找很多个人 Peer，这可以增加你网络的稳定性，避免某个节点临时故障导致你和 DN42 完全失联。并且，多 Peer 还能够提高其他节点的访问速度，提高网络的冗余性和整体性能。&lt;/li&gt;
&lt;li&gt;后续的性能优化和安全配置等。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="注册"&gt;注册
&lt;/h2&gt;&lt;p&gt;注册的过程其实就是向 DN42 的身份信息 git 仓库提交 PR 的过程，各个信息配置文件的格式和内容都有严格的要求，被批准合并后就算拥有了自己管辖的 ASN 和 IP 地址段之类的了。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先去 &lt;a class="link" href="https://git.dn42.dev" target="_blank" rel="noopener"
 &gt;https://git.dn42.dev&lt;/a&gt; 注册一个账户，这是 DN42 通过 Gitea 提供的模板自部署的 DevOps 平台，类似于 GitHub。&lt;/li&gt;
&lt;li&gt;所有 DN42 成员的账户信息就存放在仓库 &lt;a class="link" href="https://git.dn42.dev/dn42/registry" target="_blank" rel="noopener"
 &gt;dn42/registry&lt;/a&gt; 里。为了 PR，先 fork 一份到自己的账户。&lt;/li&gt;
&lt;li&gt;Clone 已经 fork 的仓库到本地。&lt;/li&gt;
&lt;li&gt;接下来就是创建并编辑各个自己所属的配置文件，提交 commit 后创建 PR 了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;需要注意 ASN 和 IP 地址段需要自己挑选空缺的，而且 IPv6 地址极不推荐自己定义地址段前缀，而是通过蓝天大佬提到的随机生成前缀的工具来生成，以符合 RFC4193 中对 IPv6 唯一本地地址的要求。下面列举所有初次注册时必须提交的 8 个文件（注意根据配置不同，可能还需要第 9 个文件 &lt;code&gt;data/dns/[昵称].dn42&lt;/code&gt;）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;data/mntner/[昵称]-MNT&lt;/code&gt;：代表你的账户，用于验证后续操作&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/person/[昵称]-DN42&lt;/code&gt;：代表你个人的信息，包含昵称、邮箱等&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/aut-num/[你的ASN]&lt;/code&gt;：代表你想申请的 ASN 号，包含 ASN 号、AS 简介、管理者、联系方式等&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/inetnum/[地址段前缀]_[地址块大小]&lt;/code&gt;：代表你想申请的 IPv4 地址段，包含地址段前缀、地址块大小、管理者、联系方式等&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/route/[地址段前缀]_[地址块大小]&lt;/code&gt;：IPv4 地址段的路由信息，包含地址段前缀、地址块大小、AS 路由（即授权哪个 AS 使用这个地址段）等&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/inet6num/[地址段前缀]_[地址块大小]&lt;/code&gt;：代表你想申请的 IPv6 地址段（本文件是可选的，且如果不添加 IPv6 地址段，后续 &lt;code&gt;data/route6&lt;/code&gt; 中的文件也可以不添加）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/route6/[地址段前缀]_[地址块大小]&lt;/code&gt;：IPv6 地址段的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各个配置文件的内容和其解释可以直接参考蓝天大佬的博客的&lt;a class="link" href="https://lantian.pub/article/modify-website/dn42-experimental-network-2020.lantian/#%e6%b3%a8%e5%86%8c%e8%bf%87%e7%a8%8b" target="_blank" rel="noopener"
 &gt;注册过程部分&lt;/a&gt;。描述和原理他已经讲的很清楚了，这里不作赘述。另外，一个好的学习方法是直接参考其他已经成功 merge 的 PR 或参考仓库中已经较为成熟的配置文件来写自己的部分。&lt;/p&gt;
&lt;p&gt;这里补充一些蓝天大佬没提到的东西，以及一些需要注意的细节：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;提交 commit 所使用的签名密钥必须要包含在 &lt;code&gt;data/mntner/[昵称]-MNT&lt;/code&gt; 文件中的 &lt;code&gt;auth&lt;/code&gt; 字段中。该字段的内容是用来验证后续操作的凭证，所以本次 PR 中的 commit 需要使用该密钥进行签名，使自动化验证工具能够确认你的身份拥有对该 ASN 和 IP 地址段的管理权限，并批准你的 PR。&lt;/li&gt;
&lt;li&gt;寻找空闲的 IPv4 地址段时，蓝天提到了两个可用的网址，但是 &lt;a class="link" href="https://dn42.us/peers/free" target="_blank" rel="noopener"
 &gt;https://dn42.us/peers/free&lt;/a&gt; 最后一次更新为 2025 年 10 月末，已经没有什么参考价值了。&lt;/li&gt;
&lt;li&gt;对于 IPv4，DN42 一般建议申请的合适的地址块大小为 /27（即包含 32 个地址的块）&lt;/li&gt;
&lt;li&gt;对于 IPv6，建议申请 /48 的地址段（即包含 65536 个地址的块）&lt;/li&gt;
&lt;li&gt;v4 和 v6 的 &lt;code&gt;inetnum&lt;/code&gt; (&lt;code&gt;inet6num&lt;/code&gt;) 文件中所配置的 &lt;code&gt;nserver&lt;/code&gt; 为反向 DNS 服务器，如果配置了，那么还需要在 &lt;code&gt;data/dns&lt;/code&gt; 目录下添加一个对应的文件，内容包含反向 DNS 服务器的 IP 地址和主机名等信息。&lt;/li&gt;
&lt;li&gt;一些文件的 &lt;code&gt;remarks&lt;/code&gt; 字段可以添加一些比较美观的备注信息，增加一些个性化的内容，当然这不是必须的。以下展示我从 MoonWX 那里抄来的一个示例 &lt;code&gt;remarks&lt;/code&gt; 字段：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="remarks of my AS: 2426" class="gallery-image" data-flex-basis="426px" data-flex-grow="177" height="298" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.sisy.cc/p/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E6%8E%A5%E5%85%A5-dn42-%E7%BD%91%E7%BB%9C-1-%E6%B3%A8%E5%86%8C%E4%B8%8E%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81/img/data-aut-num.png" width="529"&gt;&lt;/p&gt;
&lt;p&gt;由于蓝天没有提到第 5 点中的这个 DNS 文件，以下简单给出我这个文件的示例内容：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-plaintext" data-lang="plaintext"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;domain: sisy.dn42
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;admin-c: SISY-DN42
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tech-c: SISY-DN42
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mnt-by: SISY-MNT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nserver: ns1.sisy.dn42 172.23.15.33
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nserver: ns1.sisy.dn42 fd24:ac8e:9e04::1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;source: DN42
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;接下来，创建一个带签名的 commit 并提交 PR。PR 的审核过程可能需要一些时间，审核人员会检查你的配置是否符合要求，并且可能会提出一些修改建议。审核通过后，你的 PR 就会被合并到主分支，你就正式成为 DN42 网络的一员了。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;其实感觉这里面最花时间的还是挑选自己喜欢的 ASN 和 IPv4 地址段，，，&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;关于第一个 Peer，暂且先决定放到下一篇里来讲吧。&lt;/p&gt;</description></item></channel></rss>