注册 DN42 在 dn42 gitea 注册账号。
在网页上绑定 SSH/GPG 公钥。
Clone Repo Fork 注册仓库 ,然后拉到本地。
记得使用 Linux 拉取,Windows 会报错的,因为冒号的存在。似乎有方法绕过,但是因为我有 wsl,很方便,所以就用 wsl 了
然后签一个分支出来,免得操作不当搞炸了。当然你艺高人胆大不弄也行。
1 git checkout -b <username>/register
注册相关信息 可以参照 官方概要
可以先选个心仪的 ASN, IPv4/IPv6 Prefix 。
维护者 在 data/mntner
文件夹下新建一个名为 <FOO>-MNT
的文件。
写入以下内容
1 2 3 4 5 6 mntner: <FOO>-MNT admin-c: <FOO>-DN42 tech-c: <FOO>-DN42 mnt-by: <FOO>-MNT auth: pgp-fingerprint 0123456789ABCDEF0123456789ABCDEF01234567 source: DN42
这是官方参照的翻译版本:
1 2 3 4 5 6 7 8 9 10 mntner (必要) (单项) primary schema 维护者名称,应与文件名相同 descr (可选) (单项) 维护者描述 mnt-by (必要) (多项) lookup=dn42.mntner 实际维护人,个人就是维护者 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员联系信息,在 联系人 中注册的人,个人一般就是自己,维护者 tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员联系信息,在 联系人 中注册的人,个人一般就是自己,维护者 auth (可选) (多项) > [method] [value]... 身份验证信息,可以使用 GPG/SSH 公钥 org (可选) (多项) lookup=dn42.organisation 组织 abuse-mailbox (可选) (单项) 滥用反馈邮箱 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42
联系人 在 data/person
目录下新建一个名为 <FOO>-DN42
的文件。
1 2 3 4 5 person: <FOO> e-mail: <YourEmail> nic-hdl: <FOO>-DN42 mnt-by: <FOO>-MNT source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 person (必要) (单项) schema 姓名,可以为昵称 nic-hdl (必要) (单项) primary NIC 管理者,与文件名相同 mnt-by (必要) (多项) lookup=dn42.mntner 维护人 org (可选) (多项) lookup=dn42.organisation 组织 nick (可选) (多项) 昵称 pgp-fingerprint (可选) (多项) pgp 指纹 www (可选) (多项) 网站 e-mail (可选) (多项) 邮件 contact (可选) (多项) 联系方式 abuse-mailbox (可选) (多项) 滥用反馈邮箱 phone (可选) (多项) 手机号 fax-no (可选) (多项) 传真号 address (可选) (多项) 地址 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42
注册 ASN DN42 占用的私人地址块为:4242420000 - 4242429999 。目前 DN42 开放注册的 ASN 范围是 4242420000 - 4242423999 ,我注册时还剩一千多个,靓号都没了,看到个顺眼的就选了吧。
你可以在 这里 检查剩余可用 ASN。
在 data/aut-num
目录下新建一个文件,文件名为你选定的 ASN。
1 2 3 4 5 6 aut-num: <你想要的 ASN,需要带“AS”> as-name: <AS 名称> admin-c: <FOO>-DN42 tech-c: <FOO>-DN42 mnt-by: <FOO>-MNT source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 12 13 aut-num (必要) (单项) primary schema AS 号码,如 AS4242423999 as-name (必要) (单项) AS 名称,一个单词,多个单词可用 '-' / '_' 连接 descr (可选) (单项) 描述 mnt-by (必要) (多项) lookup=dn42.mntner 维护人 member-of (可选) (多项) lookup=dn42.as-set,dn42.route-set 谁的成员 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员,个人即之前注册的 nic-hdl tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员,个人即之前注册的 nic-hdl org (可选) (单项) lookup=dn42.organisation 组织 mp-import (可选) (多项) 多路由器之间的路由信息导入 mp-export (可选) (多项) 多路由器之间的路由信息导出 mp-default (可选) (多项) 默认路由 geo-loc (可选) (多项) > [lat-c] [long-c] [name] 地理位置 remarks (可选) (多项) 注释、说明
IPv6 Address 你可以在 这里 检查剩余可用 IPv6 地址段。不过 DN42 拥有整个 fd00::/8 ,非常庞大,基本是想要什么就有什么。
在 data/inet6num
目录下新建一个文件,文件名为你想要的 IPv6 地址块的 CIDR 格式,记得用 _
代替 /
。
1 2 3 4 5 6 7 8 9 10 inet6num: <起始 IP 地址> - <结束 IP 地址> cidr: <你想要的 IP 地址块的 CIDR 格式> netname: <FOO>-NETWORK descr: <描述> country: XD admin-c: <FOO>-DN42 tech-c: <FOO>-DN42 mnt-by: <FOO>-MNT status: ASSIGNED source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 inet6num (必要) (单项) schema IP 起始地址 - IP 结束地址 cidr (必要) (单项) primary IP 地址的 CIDR 表示 netname (必要) (单项) 网络名,此处可加 '-IPv6' 加以区分为 v6 网络 nserver (可选) (多项) > [domain-name] NS country (可选) (多项) 国家 descr (可选) (单项) 描述 status (可选) (单项) > {ALLOCATED|ASSIGNED} {PI|PA|} 状态 policy (可选) (单项) > {open|closed|ask|reserved} 政策 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员 tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员 zone-c (可选) (多项) lookup=dn42.person,dn42.role 联系人/组织 ds-rdata (可选) (多项) DNSSEC mnt-by (可选) (多项) lookup=dn42.mntner 维护人 mnt-lower (可选) (多项) lookup=dn42.mntner 维护子集 mnt-routes (可选) (多项) lookup=dn42.mntner 维护路由 org (可选) (单项) lookup=dn42.organisation 组织 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42
IPv4 Address 你可以在 这里 检查剩余可用 IPv4 地址段。 DN42 不推荐使用过小 / 过大的地址段。过小的不好分配,过大的地址不足。/26 - /28 都是比较好获取的。
在 data/inetnum
目录下新建一个文件,文件名为你想要的 IPv4 地址块的 CIDR 格式,用 _
代替 /
。
1 2 3 4 5 6 7 8 9 10 inetnum: <起始 IP 地址> - <结束 IP 地址> cidr: <你想要的 IP 地址块的 CIDR 格式> netname: <FOO>-NETWORK descr: <描述> country: XD admin-c: <FOO>-DN42 tech-c: <FOO>-DN42 mnt-by: <FOO>-MNT status: ASSIGNED source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 inetnum (必要) (单项) schema IP 起始地址 - IP 结束地址 cidr (必要) (单项) primary IP 地址的 CIDR 表示 netname (必要) (单项) 网络名,此处可加 '-IPv6' 加以区分为 v6 网络 nserver (可选) (多项) > [domain-name] NS country (可选) (多项) 国家 descr (可选) (单项) 描述 status (可选) (单项) > {ALLOCATED|ASSIGNED} {PI|PA|} 状态 policy (可选) (单项) > {open|closed|ask|reserved} 政策 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员 tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员 zone-c (可选) (多项) lookup=dn42.person,dn42.role 联系人/组织 ds-rdata (可选) (多项) DNSSEC mnt-by (可选) (多项) lookup=dn42.mntner 维护人 mnt-lower (可选) (多项) lookup=dn42.mntner 维护子集 mnt-routes (可选) (多项) lookup=dn42.mntner 维护路由 org (可选) (单项) lookup=dn42.organisation 组织 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42
Route Record 在 data/route
目录下新建一个文件,命名为你想要的 IP 地址块的 CIDR 格式,用 _
代替 /
。
IPv6 1 2 3 4 5 route6: <你想要的 IPv6 地址块> origin: <你想要的 ASN> max-length: 48 mnt-by: <FOO>-MNT source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 route6 (必要) (单项) primary schema IP 地址的 CIDR 表示 mnt-by (必要) (多项) lookup=dn42.mntner 维护人 origin (必要) (多项) lookup=dn42.aut-num ASN,带 “AS” member-of (可选) (多项) lookup=dn42.route-set 谁的成员 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员 tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员 descr (可选) (多项) 描述 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42 pingable (可选) (多项) 是否相应 ICMP max-length (可选) (单项) 最大 IP 长度,如 48
IPv4 1 2 3 4 5 route: <你想要的 IPv4 地址块> origin: <你想要的 ASN> max-length: <你 IP 长度,比如 27> mnt-by: <FOO>-MNT source: DN42
官方参照:
1 2 3 4 5 6 7 8 9 10 11 route (必要) (单项) primary schema IP 地址的 CIDR 表示 mnt-by (必要) (多项) lookup=dn42.mntner 维护人 origin (必要) (多项) lookup=dn42.aut-num ASN,带 “AS” member-of (可选) (多项) lookup=dn42.route-set 谁的成员 admin-c (可选) (多项) lookup=dn42.person,dn42.role 管理员 tech-c (可选) (多项) lookup=dn42.person,dn42.role 技术员 descr (可选) (多项) 描述 remarks (可选) (多项) 注释、说明 source (必要) (单项) lookup=dn42.registry DN42 pingable (可选) (多项) 是否相应 ICMP max-length (可选) (单项) 最大 IP 长度,如 27
检查 仓库根目录包含许多脚本来帮助检查您的请求:
fmt-my-stuff <FOO>-MNT
:自动修复较小的格式错误check-my-stuff <FOO>-MNT
:根据注册表模式验证您的对象check-pol origin/master <FOO>-MNT
:检查策略违规情况squash-my-commits
:自动更新并压缩您的本地提交,在第一次提交出现问题后,修改之后使用sign-my-commit
:使用 pgp 密钥或标准 SSH 签名对您的提交进行签名前三个运行、检查无误后即可提交了
推送 1 2 3 4 5 6 7 8 9 10 11 12 13 14 git add . git commit -S 'FOOBAR' # 签名 ./sign-my-commit --pgp <FOO>-MNT # 推送 git push --set-upstream origin <username>/register # 被拒修复后 git add . git commit -S 'FOOBAR' ./squash-my-commits ./sign-my-commit --pgp <FOO>-MNT git push --force
PR 这个,去官方 Repo 拉个 PR ,然后等就行了。
Bird2 配置 Debian 11 中的 Bird2 应当是 2.0.7 版本的。我使用的是这个版本。目前 Debian 12 是 2.0.12,小版本不同,配置是一样的。
安装 Bird2 1 2 apt update # && apt upgrade -y apt install bird2 -y
配置 参照 官方文档 内容即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ################################################ # Variable header # ################################################ define OWNAS = <你的ASN>; # AS4242423999 define OWNIP = <你的IPv4地址>; # 172.20.1.129 define OWNIPv6 = <你的IPv6地址>; # fd88:1234:1234::1 define OWNNET = <IPv4 CIDR>; # 172.20.1.128/27 define OWNNETv6 = <IPv6 CIDR>; # fd88:1234:1234::/48 define OWNNETSET = [<IPv4 CIDR>+]; # [172.20.1.128/27+] define OWNNETSETv6 = [<IPv6 CIDR>+]; # [fd88:1234:1234::/48+] ################################################ # Header end # ################################################ router id OWNIP; protocol device { scan time 10; } /* * Utility functions */ function is_self_net() { return net ~ OWNNETSET; } function is_self_net_v6() { return net ~ OWNNETSETv6; } function is_valid_network() { return net ~ [ 172.20.0.0/14{21,29}, # dn42 172.20.0.0/24{28,32}, # dn42 Anycast 172.21.0.0/24{28,32}, # dn42 Anycast 172.22.0.0/24{28,32}, # dn42 Anycast 172.23.0.0/24{28,32}, # dn42 Anycast 172.31.0.0/16+, # ChaosVPN 10.100.0.0/14+, # ChaosVPN 10.127.0.0/16{16,32}, # neonetwork 10.0.0.0/8{15,24} # Freifunk.net ]; } roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol static { roa4 { table dn42_roa; }; include "/etc/bird/roa_dn42.conf"; }; protocol static { roa6 { table dn42_roa_v6; }; include "/etc/bird/roa_dn42_v6.conf"; }; 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; }; } 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; } else accept; } else reject; }; export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else 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; } else accept; } else reject; }; export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; }; import limit 1000 action block; }; } include "/etc/bird/peers/*";
然后在 /etc/bird
目录下创建一个文件夹,名为 peers
,这是待会要用到的喵喵工具。
下载 ROA 文件 ROA 应该经常性的自动下载和更新,以防止 BGP 劫持。
1 2 wget -O /tmp/dn42_roa.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf && mv -f /tmp/dn42_roa.conf /etc/bird/roa_dn42.conf wget -O /tmp/dn42_roa_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf && mv -f /tmp/dn42_roa_v6.conf /etc/bird/roa_dn42_v6.conf
加载配置 重载并查看状态
1 2 birdc c # birdc configure birdc show protocol
查看状态
自动化 ROA 是需要经常更新的,这是对应的 Crontab 语句
1 2 3 0 0 */1 * * ? wget -O /tmp/dn42_roa.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf && mv -f /tmp/dn42_roa.conf /etc/bird/roa_dn42.conf 0 0 */1 * * ? wget -O /tmp/dn42_roa_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf && mv -f /tmp/dn42_roa_v6.conf /etc/bird/roa_dn42_v6.conf 3 0 */1 * * ? birdc c
每小时执行一次下载,并且会更新 bird 的配置文件。
WireGuard 配置 安装 WireGuard 生成密钥 运行下面的命令,在当前目录下生成一对公钥和私钥。
1 wg genkey | tee privatekey | wg pubkey > publickey
使用时直接查看就行,比如
1 cat privatekey && cat publickey
搭建隧道 需要一位已经在 DN42 的上游来和您 Peer 。
在 /etc/wireguard
目录下新建一个名为 <FOO>.conf
的文件。文件名应当能让自己好区分,比如 dn42-3999.conf
Interface 部分是自己的配置。
为保持方便,ListenPort
一般为 2
/ 3
+ ASN 后四位
1 2 3 4 5 6 7 8 9 10 11 12 13 [Interface] PrivateKey = <private_key> ListenPort = <YOUR_LOCAL_UDP_PORT> [Peer] PublicKey = <public_key_of_your_peer> # OPTIONAL, its also possible to define a pre-shared key for additional security PresharedKey = <PSK,双方约定好的> # at least one peer needs to provide this one Endpoint = <end_point_hostname_or_ip:port> # in theory this could be restricted to dn42 networks, # however it is easier to do this with iptables/bgp filters/routing table # instead just like for openvpn-based peerings AllowedIPs = 0.0.0.0/0,::/0
这是一份示例
1 2 3 4 5 6 7 8 [Interface] PrivateKey = 114514asdasdasdasdasd= ListenPort = 23999 [Peer] PublicKey = 1919810asdasdasdasdasd= Endpoint = 对方公网IP:对方端口 # 限制 IP AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, fe80::/64, fd00::/8
开启隧道 使用 ifupdown 进行配置。
在 /etc/network/interfaces.d
文件夹内新建一个名为 <FOO>
的文件,内容如下
1 2 3 4 5 6 7 8 9 auto <FOO> iface <FOO> inet manual pre-up ip link add $IFACE type wireguard pre-up wg setconf $IFACE /etc/wireguard/<FOO>.conf up ip link set $IFACE up post-up ip addr add <本机DN42 IP>/32 peer <对方Dn42 IP>/32 dev $IFACE post-up ip addr add <本机endpoint>/64 dev $IFACE post-up ip addr add <本机IPv6> dev $IFACE post-down ip link del $IFACE
开启隧道:
可以通过 ping <NEIGHBOR_IPv6>%'<NEIGHBOR_INTERFACE>'
测试隧道是否正常拉起。
设置 Peers 开启隧道后,在 /etc/bird/peers
目录下新建 <FOO>.conf
,内容为(如果 v4 v6 都有,那就只需要 v6 的内容)
1 2 3 protocol bgp <NEIGHBOR_NAME>_v6 from dnpeers { neighbor <NEIGHBOR_IPv6>%'<NEIGHBOR_INTERFACE>' as <NEIGHBOR_ASN>; }
其中,
<NEIGHBOR_NAME>
: 自己设置个邻居的名称<NEIGHBOR_IPv6>
: 邻居的 IPv6,对方提供<NEIGHBOR_INTERFACE>
: 邻居的接口名,对方提供<NEIGHBOR_ASN>
: 不需要带 “AS”,对方提供1 2 birdc c birdc show protocol all
然后就能见到类似的输出啦
与邻居的协议
事故处理 ip link del <FOO>
:删除错误配置的网络参见 DN42 Wiki