首页
iYoRoy DN42 Network
关于
友情链接
推荐
悠笙の喵罐头
Search
1
Docker下中心化部署EasyTier
1,334 阅读
2
给Android 4.9内核添加KernelSU支持
910 阅读
3
记一次为Android 4.9内核的ROM启用erofs支持
272 阅读
4
在TrueNAS上使用Docker安装1Panel
240 阅读
5
为黑群晖迁移RR引导盘
218 阅读
Android
运维
NAS
开发
网络技术
专题向研究
DN42
个人ISP
CTF
登录
Search
标签搜索
网络技术
Linux
BGP
BIRD
C&C++
DN42
Android
Docker
AOSP
Windows
MSVC
内部路由协议
OSPF
iBGP
Clearnet
ASN
服务
DNS
TrueNAS
Web
神楽悠笙
累计撰写
21
篇文章
累计收到
8
条评论
首页
栏目
Android
运维
NAS
开发
网络技术
专题向研究
DN42
个人ISP
CTF
页面
iYoRoy DN42 Network
关于
友情链接
推荐
悠笙の喵罐头
搜索到
5
篇与
的结果
DN42&OneManISP - 使用VRF实现公网BGP和DN42共用一台机器
背景 目前同一区域内公网BGP和DN42分别用了一台VPS,也就是说同一个区域需要两台机器。从群友那里得知了VRF,便想着通过VRF实现同一台机器同时处理公网BGP并加入DN42。 VRF的必要性 虽然说DN42使用的IP段是私有地址,并且它的ASN用的都是内部ASN,理论上不会和公网BGP相互干扰,但是如果共用同一张路由表,可能会造成路由污染、管理复杂等问题。 VRF(Virtual Routing and Forwarding,虚拟路由转发)可以实现在一台机器上创建多个路由表,也就是说我们可以通过它将DN42的路由单独放到一个路由表里,以实现将DN42路由表和公网路由表相隔离。这么做的优点有: 绝对的安全与策略隔离:DN42路由表和公网路由表相隔离,从根本上杜绝了路由泄露的可能性。 清晰的运维管理:可以使用birdc show route table t_dn42和birdc show route table t_inet来分别查看和调试两张完全独立的路由表,一目了然。 故障域隔离:若果DN42的某个对等体发生Flap,这些影响将被完全限制在dn42的路由表内,不会消耗公网实例的路由计算资源,也不会影响公网的转发性能。 更符合现代网络设计理念:在现代网络工程中,为不同的路由域(生产、测试、客户、合作伙伴)使用VRF是标准做法。它将你的设备逻辑上划分成了多个虚拟路由器。 配置 系统部分 创建VRF设备 使用以下指令创建一个名为dn42-vrf的VRF设备并关联到系统的1042号路由表: ip link add dn42-vrf type vrf table 1042 ip link set dev dn42-vrf up # 启用 路由表号可以按照你自己的喜好修改,但是请避开以下几个保留路由表编号: 名称 ID 说明 unspec 0 未指定,基本不用 main 254 主路由表,大多数普通路由都放在这里 default 253 一般不用,保留 local 255 本机路由表,存放127.0.0.1/8、本机 IP、广播地址等,不能改 将现有的相应网卡关联到VRF 按照我目前的DN42网络为例,有若干WireGuard网卡和一个dummy网卡是用于DN42的,因此将这几个网卡都关联到VRF中: ip link set dev <网卡名> master dn42-vrf 需要注意的是,网卡关联到VRF之后可能会丢失地址,因此需要重新为其添加一次地址,如: ip addr add 172.20.234.225 dev dn42 完成之后,通过ip a应该能看到对应网卡的master是dn42-vrf: 156: dn42: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue master dn42-vrf state UNKNOWN group default qlen 1000 link/ether b6:f5:28:ed:23:04 brd ff:ff:ff:ff:ff:ff inet 172.20.234.225/32 scope global dn42 valid_lft forever preferred_lft forever inet6 fd18:3e15:61d0::1/128 scope global valid_lft forever preferred_lft forever inet6 fe80::b4f5:28ff:feed:2304/64 scope link valid_lft forever preferred_lft forever 持久化 我使用了ifupdown来实现开机自动加载dummy网卡和VRF设备。 对于VRF设备,创建文件/etc/network/interfaces.d/01-dn42-vrf并填入: auto dn42-vrf iface dn42-vrf inet manual pre-up ip link add $IFACE type vrf table 1042 up ip link set dev $IFACE up post-down ip link del $IFACE 然后使用ifup dn42-vrf启动。 对于dummy网卡,创建文件/etc/network/interfaces.d/90-dn42并填入: auto dn42 iface dn42 inet static address 172.20.234.225 netmask 32 pre-up ip link add $IFACE type dummy up ip link set $IFACE up master dn42-vrf # 此处master指定和dn42-vrf相关联 down ip link set $IFACE down post-down ip link del $IFACE iface dn42 inet6 static address fd18:3e15:61d0::1 netmask 128 因为ifupdown不支持同时配置v4和v6地址,因此需要分成两个iface。 我的dummy网卡名称为dn42,如果你的名称不一样请按需要修改。创建完后使用ifup dn42即可启动dummy网卡。 注意:VRF设备前面的标号需要比dummy网卡的大,以让VRF设备先于dummy网卡启动。 WireGuard隧道 添加PostUp使其关联到vrf并重新为其绑定地址。举个例子: [Interface] PrivateKey = [数据删除] ListenPort = [数据删除] Table = off Address = fe80::2024/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 + PostUp = ip link set dev %i master dn42-vrf + PostUp = ip addr add fe80::2024/64 dev %i [Peer] PublicKey = [数据删除] Endpoint = [数据删除] AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 然后重新启动隧道即可。 Bird2部分 首先我们需要定义两张路由表,分别用于dn42的IPv4和IPv6: ipv4 table dn42_table_v4; ipv6 table dn42_table_v6 随后,在kernel protocol中指定VRF和系统路由表编号,并在IPv4、IPv6中指定前面创建的v4、v6路由表: protocol kernel dn42_kernel_v6{ + vrf "dn42-vrf"; + kernel table 1042; scan time 20; ipv6 { + table dn42_table_v6; import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = DN42_OWNIPv6; accept; }; }; }; protocol kernel dn42_kernel_v4{ + vrf "dn42-vrf"; + kernel table 1042; scan time 20; ipv4 { + table dn42_table_v4; import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = DN42_OWNIP; accept; }; }; } 除了kernel以外的protocol都加上VRF和IPv4、IPv6独立的table,但不需要指定系统路由表编号: protocol static dn42_static_v4{ + vrf "dn42-vrf"; route DN42_OWNNET reject; ipv4 { + table dn42_table_v4; import all; export none; }; } protocol static dn42_static_v6{ + vrf "dn42-vrf"; route DN42_OWNNETv6 reject; ipv6 { + table dn42_table_v6; import all; export none; }; } 总而言之就是: 一切和DN42有关的都给配置一个VRF和之前定义的路由表 只有kernel协议需要指定系统路由表编号,其他不需要 对于BGP、OSPF等也如法炮制,不过我选择将公网的RouterID和DN42的分开,因此还需要单独配置一个RouterID: # /etc/bird/dn42/ospf.conf protocol ospf v3 dn42_ospf_iyoroynet_v4 { + vrf "dn42-vrf"; + router id DN42_OWNIP; ipv4 { + table dn42_table_v4; import where is_self_dn42_net() && source != RTS_BGP; export where is_self_dn42_net() && source != RTS_BGP; }; include "ospf/*"; }; protocol ospf v3 dn42_ospf_iyoroynet_v6 { + vrf "dn42-vrf"; + router id DN42_OWNIP; ipv6 { + table dn42_table_v6; import where is_self_dn42_net_v6() && source != RTS_BGP; export where is_self_dn42_net_v6() && source != RTS_BGP; }; include "ospf/*"; }; # /etc/bird/dn42/ebgp.conf ... template bgp dnpeers { + vrf "dn42-vrf"; + router id DN42_OWNIP; local as DN42_OWNAS; path metric 1; ipv4 { + table dn42_table_v4; ... }; ipv6 { + table dn42_table_v6; ... }; } include "peers/*"; 完成后birdc c重载配置即可。 这时,我们可以通过ip route show vrf dn42-vrf来单独查看DN42的路由表: root@iYoRoyNetworkHKGBGP:~# ip route show vrf dn42-vrf 10.26.0.0/16 via inet6 fe80::ade0 dev dn42_4242423914 proto bird src 172.20.234.225 metric 32 10.29.0.0/16 via inet6 fe80::ade0 dev dn42_4242423914 proto bird src 172.20.234.225 metric 32 10.37.0.0/16 via inet6 fe80::ade0 dev dn42_4242423914 proto bird src 172.20.234.225 metric 32 ... 也可以在Ping的时候通过参数-I dn42-vrf来实现通过VRF Ping: root@iYoRoyNetworkHKGBGP:~# ping 172.20.0.53 -I dn42-vrf ping: Warning: source address might be selected on device other than: dn42-vrf PING 172.20.0.53 (172.20.0.53) from 172.20.234.225 dn42-vrf: 56(84) bytes of data. 64 bytes from 172.20.0.53: icmp_seq=1 ttl=64 time=3.18 ms 64 bytes from 172.20.0.53: icmp_seq=2 ttl=64 time=3.57 ms 64 bytes from 172.20.0.53: icmp_seq=3 ttl=64 time=3.74 ms 64 bytes from 172.20.0.53: icmp_seq=4 ttl=64 time=2.86 ms ^C --- 172.20.0.53 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3006ms rtt min/avg/max/mdev = 2.863/3.337/3.740/0.341 ms 注意事项 如果vrf设备重载了,所有原先和vrf相关联的设备都需要重载一次,否则无法正常工作 参考文章: 用 BIRD 运行你的 MPLS 网络
2025年09月16日
9 阅读
0 评论
0 点赞
OneManISP - Ep.2 向世界宣告我们自己的IP段
前言 上文我们已经成功注册了一个ASN并且拿到了一段IPv6地址,这次我们就来将这段地址广播给全世界。 在RIPE Database设置子网对象 需要注意的是,公网允许广播的最小IPv6前缀是/48,也就是说你如果只有一个/48地址你无法将其拆成更小的段。所以我后来又单独租用了一段/40,打算将其拆成多个/48来广播。 我获取到的IPv6为2a14:7583:f200::/40,打算拆出来2a14:7583:f203::/48用于给Vultr使用。如果你不需要拆段,请直接跳转到「创建路由信息」一节 拆段 首先打开Create "inet6num" object - RIPE Database,填入如下内容: inet6num: 打算拆出来的IP段,CIDR格式 netname: 网络名称 country: IP段所属国家,需要符合ISO 3166标准(RIPE DB里可以直接选择) admin-c: 上文创建的Role对象的主键值 tech-c: 上文创建的Role对象的主键值 status: ASSIGNED即可 此步骤将你获得的地址拆出来一个小的/48地址块。 创建路由信息 打开Create "route6" object - RIPE Database,填入如下内容: route6: 填写你打算广播播的IPv6地址块的CIDR格式 origin: 填写你申请到的ASN,包含AS前缀 此步骤声明允许你的ASN使用这段地址段来发BGP路由。 申请VPS的BGP Session接入 此次我使用的是Vultr家的机器,他们家的BGP Session算是很新手友好的了,有一套自己的验证系统;并且上游良好的过滤器保证了一般情况下即使发送了错误的路由表也不会影响到公网。 (此处我配置的时候忘记截图了,可以参考一下宝硕大佬的文章 年轻人的第一个 ASN 中的 申请 Vultr 的 BGP 广播功能 章节) 进入BGP - Vultr.com,选择Get Started之后按照要求填写你的ASN信息和IPv6地址块。LOA(Letter Of Authorization,授权信)可参考以下模板:LOA-template.docx(因为发现网上查到的都是以公司的名义写的,因此以个人名义重新写了一份) 完成后系统会自动创建一条工单,并且能看到我们的ASN和IP地址块处于待验证的状态: 点击Start,系统会向注册Role时填写的abuse-mailbox邮箱发送一封验证邮件: 收到的邮件如图所示: 其中,上面那个链接代表同意授权Vultr广播你的IP段,下面那个则是不同意。我们点击上面那个之后会进入Vultr的网页: 再点击Approve Announcement即可。ASN和IP段都需要验证一次。 接着,等待Vultr的工作人员审核完成后来到VPS的控制台,就能看到我们的BGP选项卡了,其中可以得到上游的信息: 此处不得不称赞一下Vultr的工单效率,我平均从创建工单申请授权到完成只花了10分钟左右。(反观之前在iFog GmbH,平均工作日工单回复时间1天左右实在是好太多了) 其他厂商的VPS大概都是这么个流程,你需要告诉工作人员你要播的ASN和IP段,在验证完所有权之后工作人员会为你配置对应的BGP Session。 广播! 你应该已经从上游那里得到了以下信息: 上游的ASN 上游用于BGP Session的地址 (可选)密码 我用的操作系统是Debian12 Bookworm,使用Bird2作为路由软件,并且按照这篇文章中「更新Bird2至v2.16及以上」章节更新Bird2至最新版。Vultr那边给我的上游ASN是64515,上游用于BGP Session的地址是2001:19f0:ffff::1,VPS用于BGP Session的地址是2001:19f0:0006:0ff5:5400:05ff:fe96:881f。 我的Bird2配置文件修改自DN42中的配置文件: log syslog all; define OWNAS = 205369; # 自己的ASN define OWNIPv6 = 2a14:7583:f203::1; # 给机器绑定的单个IPv6地址 define OWNNETv6 = 2a14:7583:f203::/48; # 打算播的网段 define OWNNETSETv6 = [ 2a14:7583:f203::/48+ ]; # 打算播的网段集合 router id 45.77.x.x; # 路由器ID,这里使用VPS的公网IPv4 protocol device { scan time 10; } function is_self_net_v6() { return net ~ OWNNETSETv6; } protocol kernel { scan time 20; ipv6 { import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = OWNIPv6; accept; }; }; }; protocol static { route OWNNETv6 reject; ipv6 { import all; export none; }; } template bgp upstream { local as OWNAS; path metric 1; multihop; # 指定多跳 ipv6 { import filter { if net ~ [::/0] then reject; # 拒绝导入默认路由 accept; }; export filter { if is_self_net_v6() then accept; # 仅导出自己网段内的路由,防止劫持 reject; }; import limit 1000 action block; }; graceful restart; } protocol bgp 'Vultr_v6' from upstream{ local 2001:19f0:0006:0ff5:5400:05ff:fe96:881f as OWNAS; # local后面的地址即上游给的用于BGP Session的VPS上的地址 password "123456"; # 上游给你的BGP密码,若没密码就将这一行删除 neighbor 2001:19f0:ffff::1 as 64515; # 上游的BGP Session IP和ASN } 几个值得注意的点: 此处upstream模板的导入规则拒绝了 默认路由 ,这样写可以防止上游发来的路由表覆盖掉本地的默认网关等路由信息。如果我们有多个BGP邻居,则可能导致绕路甚至路由环路。 upstream中指定了多跳(multihop;),这是因为Vultr的BGP对端不能直达,若不设置多跳则会导致BGP会话卡在Idle状态。如果你的BGP上游是直连,可以不设置此行或者改为direct;。 填写完配置文件,运行birdc configure载入配置。 运行birdc show protocols查看状态,如果不出意外的话应该能看到BGP会话已经Established: 这个时候,你可以起身做点别的事情,等待全球路由收敛。大概半个小时之后,打开bgp.tools,查询自己的/48段,应该就能看到已经成功被全球互联网收敛,并且能看到我们的上游信息: 接着,我们在VPS上创建一个dummy网卡,并绑定我们为这个机器设置的段内的单个IPv6地址,如我给我这台机器分配了2a14:7583:f203::1: ip link add dummy0 type dummy ip addr add 2a14:7583:f203::1/128 dev dummy0 接着使用我们自己的PC ping这个地址就能通了,traceroute也能看到完整路由路径: 感谢米露大佬提供的技术支持! 参考文章: 自己在家开运营商 Part.2 - 向世界宣告 IP 段 (BGP Session & BIRD) 年轻人的第一个 ASN - 宝硕博客 BGPlayer 从零开始速成指北 - 开通 Vultr 的 BGP 广播功能 - AceSheep BGP (2) 在 Vultr 和 HE 使用自己的 IPV6 地址 - 131's Blog
2025年08月20日
42 阅读
0 评论
1 点赞
OneManISP - Ep.1 注册一个ASN
写在前面 本文记录了我在RIPE NCC申请ASN的完整过程,内容适合入门者参考,若有错误欢迎邮件联系我,我会在第一时间更正。 既然已经在DN42上学习了基本的BGP概念,不玩玩公网的有点说不过去吧( 基本概念 目前公网ASN和IP资源分配由世界上5个 区域互联网注册管理机构(Regional Internet registry, RIR) 管理: ARIN: 负责管理北美地区 RIPE NCC: 负责管理欧洲地区 APNIC: 亚洲地区 LACNIC: 拉丁美洲地区 AfriNIC: 非洲地区 RIR不直接对个人用户提供服务,而是通过将资源授权给 本地互联网注册管理机构(Local Internet Registry, LIR) ,再由LIR授权给个人。当然,个人用户也可以注册成为LIR,但是这一般而言一般是不划算的。 如果你愿意每年交几千美元作为会费的话当我没说。 其中,对个人申请比较友好的是RIPE NCC,其次是ARIN和APNIC。相较于RIPE NCC,APNIC的费用普遍要高30%左右;并且RIPE NCC提供了一套在线管理系统,用户可以自己修改信息、查询进度,而在APNIC则需要联系LIR处理。综合而言,我选择在RIPE NCC申请ASN。 申请到的资源(ASN、IP都算)一般分为两种: PA(Provider Aggregatable)资源: 属于LIR,由LIR注册授权给你用的资源 PI(Provider Independent)资源: 属于你自己的资源,一般而言价格较高 准备阶段 选择一个LIR 上网查询LIR Service,可以找到很多提供这类服务的商家。目前RIPE NCC会向PI资源收取一年50EUR的管理费用,也就是说一般而言LIR注册ASN的费用不会低于50EUR(截至文章发布,大概60USD)一年。此处我选择的群友推荐的NoPKT LLC,价格算是比较合理的并且随ASN附赠一段/48 PA IPv6地址,实测下号速度也很快,从提交完材料到下号只用了半天。 准备材料 身份证明 个人:提供身份证或者护照都可以(我提供的身份证正反面照片) 企业:提供有效的营业执照 若申请人为未成年人,通常需要其法定监护人提供书面同意书并履行相应监护职责。所有提交的文件应确保真实有效,且必须是原件或经过公证的副本。 联系信息 通信地址,被用于登记在RIPE Database 技术人员邮箱 滥用举报邮箱 技术要求证明 欧洲范围内的BGP服务商开具的账单,可以选择Vultr、BuyVM、iFog、V.PS等。 注:Vultr是先用后付制,每月初出账单。如果你着急备好材料,建议选择其他家。 两个你打算接入的上游的ASN(实际上审核方不会严格验证你填写的上游ASN,因此可以随意填写,但建议填写一些常见的公开ASN以显得合理,不用过多纠结。 甚至填我的也行 ) 注册RIPE DB账户并创建条目 打开RIPE Database并注册一个账户。此处填写姓名时建议填写你自己的真实姓名的拼音,并且强制要求开启2FA,请提前在手机上安装TOTP软件。 创建Role对象和Maintainer对象 打开Create role and maintainer pair - RIPE Database,创建一个role对象。 此处role为一个抽象概念,用来描述一个团队、部门或者职能角色的联系方式,代指一个角色,比如 NOC (Network Operations Center)、Abuse Team、Hostmaster 等。 mntner: maintainer对象的标识符,可包含大小写字母、数字、-_。例如我填写的是IYOROY-MNT role: role对象的名称,可包含大小写字母、数字、][)(._"*@,&:!'+/-。例如我填写的是IYOROY-NETWORK-NOC address: 此role对象的办公地址 e-mail: 此role的电子邮件地址 填写完成后SUBMIT即可创建role对象和maintainer对象。请记录下返回的主键名称,一般以-RIPE结尾,后续修改信息及提交到LIR需要用到。 此处maintainer对象标识符和role对象有所区别,前者意为谁有权限维护数据库中的对象(即写入/修改/删除权限控制),是维护者实体。关于RIPE Database中各个概念之间的归属,可参考文章后部的示意图。 添加滥用举报邮箱 打开Query - RIPE Database,查询刚刚获得的role主键名称,可以查询到刚刚创建的条目。点击右侧Update Object。 点击e-mail栏右侧的加号,创建一个abuse-mailbox属性,并且填入你的滥用举报邮箱: SUBMIT保存。 注:RIPE会定时检查滥用举报邮箱是否可用,请务必填写真实的邮箱地址 创建Organization对象 此处Organization对象是法律实体或组织(公司、大学、ISP、个人用户等)的抽象,是 RIPE Database 里资源对象(比如aut-num、inetnum、inet6num)的上层归属信息,也就是说后续的ASN、IP资源都将授权给Organization对象。 打开Create Organization - RIPE Database,填写如下信息: organisation: 唯一ID,保留为默认的AUTO-1即代表由RIPE NCC分配。 org-name: 组织的名称。如果是个人用户注册则需要填写你自己的姓名拼音全称。 address: 通信地址。 country: 国家代码,参考ISO 3166。中国就填写CN e-mail: 组织的电子邮件。 admin-c / tech-c: 联系对象(引用 role 的 handle)。 abuse-c: 指定abuse联系方式(必须是一个role对象,链接到role对象中的abuse-mailbox)。 mnt-ref: 指定可以创建引用该organisation的对象的维护者。 mnt-by: 谁能维护这个organisation本身。 填写完SUBMIT,并记下返回的对象标识符,类似于ORG-XXXX-RIPE的格式。 如果你在提交后发现需要修改,去Query - RIPE Database查找刚刚记录下的Role主键或者组织的对象标识符即可找到修改入口。 支付LIR费用并且提交材料 将以下材料提交给你的LIR: 身份证明 姓名 地址,推荐证件地址 身份证正反面照片 RIPE Database信息 org: 组织对象标识符 as-name: AS名称 admin-c: 上面创建的role对象主键 tech-c: 上面创建的role对象主键 abuse-c: 上面创建的role对象主键 nic-handle: 上面创建的role对象主键 mnt-by: 上面创建的maintainer对象名称 技术要求证明 VPS账单 上游的ASN LIR会要求你在你的Organization里添加一条mnt-ref,指向LIR的维护者,这样LIR那边才能够将AS和IP等资源授权到你的Organization。LIR那边审核没问题之后会将请求提交到RIPE,接着就是等待。一般而言需要3-5个工作日即可下号。 自此,我们已经在公网上注册了属于我们自己的ASN。 补充:RIPE Database中各个概念之间的关系 graph LR %% ========== ORG 层 ========== subgraph Org["Organisation"] ORG["organisation\n(ORG-XXX-RIPE)"] end %% ========== 资源层 ========== subgraph Resource["资源"] INETNUM["inetnum\n(IPv4 段)"] INET6NUM["inet6num\n(IPv6 段)"] AUTNUM["aut-num\n(ASN)"] ASSET["as-set\n(ASN 集合)"] end %% ========== 路由层 ========== subgraph Routing["路由"] ROUTE["route\n(IPv4 前缀公告)"] ROUTE6["route6\n(IPv6 前缀公告)"] end %% ========== 联系人层 ========== subgraph Contact["联系人"] ROLE["role\n(团队/职能)\nnic-hdl"] PERSON["person\n(个人)\nnic-hdl"] end %% ========== 权限层 ========== subgraph Maintainer["权限"] MNT["mntner\n(维护者)"] end %% ========== 联系 ========== INETNUM --> ROLE INET6NUM --> ROLE AUTNUM --> ROLE ASSET --> ROLE ROUTE --> ROLE ROUTE6 --> ROLE ROLE --> PERSON %% ========== 组织归属 ========== ORG --> INETNUM ORG --> INET6NUM ORG --> AUTNUM ORG --> ASSET %% ========== 权限 ========== ORG --> MNT INETNUM --> MNT INET6NUM --> MNT AUTNUM --> MNT ASSET --> MNT ROUTE --> MNT ROUTE6 --> MNT ROLE --> MNT PERSON --> MNT %% ========== 路由绑定 ========== ROUTE -->|origin| AUTNUM ROUTE6 -->|origin| AUTNUM %% ========== 路由范围 ========== ROUTE -->|属于| INETNUM ROUTE6 -->|属于| INET6NUM 特别感谢米露大佬提供部分技术支持和答疑解惑! 参考文章: 自己在家开运营商 Part.1 - 注册一个 ASN - LYC8503 从0开始注册一个ASN并广播IP | Pysio's Home 青年人的第一个运营商:注册一个 ASN | liuzhen932 的小窝
2025年08月18日
70 阅读
0 评论
1 点赞
DN42探究日记 - Ep.4 配置BGP Communities
写在前面 本人是BGP小白,文章中可能会存在不严谨内容/小白理解/低级错误,请诸位大佬们手下留情。若发现存在问题,您愿意的话可以邮件联系我,我会在第一时间更正。如果您不能接受,建议现在就关闭此文章。 什么是BGP Communities TL;DR: BGP Communities给路由“打标签”,其他人可以通过这个标签实现路由优选 这个概念对于刚入坑的小白 (比如我) 来说可能比较陌生,可能不理解它是干吗用的 简单来说,BGP Communities是一种标记路由的机制,类似于给路由打标签。它允许网络管理员给通过BGP传播的路由附加一个或多个“标签”(即社区值)。这些标签本身并不改变路由的路径属性(如AS_PATH、LOCAL_PREF、MED等),但它们提供了一种信号机制,用于向本AS内或下游对等AS中的其他路由器指示应该对该路由执行何种策略或处理。BGP Communities可以用来: 简化策略配置: 网络内部或下游 AS 的路由器只需配置基于社区值的策略(如设置LOCAL_PREF、添加NO_EXPORT、应用路由图等),无需知道具体的前缀细节。这使得策略更集中、更易管理、更不易出错 传达策略意图给下游AS: 可以将社区值附加在它通告给下游客户或对等AS的路由上。这些社区值传达了对这些路由应如何处理的要求或建议,如根据不同地理位置、不同延迟和带宽来进行路由优选等 在AS内部协调策: 在大型AS内部,IBGP全互联或使用路由反射器时,可以在 AS 边缘路由器(接收 EBGP 路由或重分发路由的路由器)给路由打上社区值,AS内部的核心路由器或路由反射器可以识别这些社区值,并应用相应的内部策略(如设置LOCAL_PREF、MED、决定是否向某些IBGP对等体通告、打上其他社区等),而无需在每个内部路由器上配置复杂的基于前缀的策略 DN42中有一套自己的Communities规范,详情可参考:BGP-communities - DN42 Wiki 配置 本文大致思路和方案来源于Xe_iu大佬,仅针对地理位置信息添加BGP Communities并进行优选。一般来说这样就足够了。(还有个原因是其他的我还没太搞明白) 注意: 我们应该只对自己的AS添加地理位置信息相关的BGP Communities,不应当对邻居传递来的路由添加相关条目。若对邻居的路由加上自己的地区Communities则会造成伪造路由起源,引发路由劫持。下游可能会误判流量路径,将本应直连的流量绕道至你的网络,增加延迟的同时大量消耗你的网络的流量。(Large Communities除外,Large Community有一套验证机制可以防止此类事情发生,但是不在本文讨论范围内) 思路已经很明白了,在导出路由时我们需要先验证是否是我们自己的路由,如果是则为路由打上communities标签即可。DN42官方给的样例配置中已经写好了两个函数is_self_net()和is_self_net_v6()用于检查是否是自己的路由,因此编写配置文件部分就很简单了。 为路由添加Communities 首先我们需要在节点配置文件开头定义好当前节点的地理区域信息,详情请查询BGP-communities - DN42 Wiki: define DN42_REGION = 52; # 52代表亚洲东部地区 define DN42_COUNTRY= 1344; # 1344代表香港 请将上述数值按照你的节点地理位置情况修改 随后在dnpeers模板中修改导出的过滤器: }; export filter { - if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; + if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then{ + if (is_self_net()) then { # 检查是否是自己的路由 + bgp_community.add((64511, DN42_REGION)); # 打上大洲级别的区域信息 + bgp_community.add((64511, DN42_COUNTRY)); # 打上国家/地区信息 + } + accept; + } reject; }; import limit 1000 action block; 在导出时检查,如果是自己的路由则按照上面设置的DN42_REGION和DN42_COUNTRY为该路由设置bgp_community。其中,64511是专门为地理标签(Region/Country)保留的公共AS号标识符,直接照抄即可。在IPv6的导出规则中也如法炮制,不过将is_self_net()换成is_self_net_v6()即可。 根据Communities优选 此处我们需要引入另一个概念:local_pref(Local Preference),他用于在AS内部标识路由的优先级。其默认值为100,值越大优先级越高。并且在BGP选路逻辑中,local_pref有着最高的优先级,甚至高于AS_PATH长度。也就是说,通过设置local_pref我们可以调整整个路由的优先级,以实现路由优选。 再结合上文的BGP Communities,我们可以根据Communities来为路由设置相应的local_pref来实现优选。同时,因为BGP.local_pref会在AS内部传递,所以需要同时更改eBGP和iBGP的路由导入和导出逻辑。 此处我处理BGP.local_pref的逻辑参考 (实际上是照抄) 了Xe_iu大佬的方案: 对于同一个大洲的路由,优先级+10 对于同一个国家,优先级再+5 对于直接和自己Peer的路由,优先级再+20 创建一个函数用于优先级计算: function ebgp_calculate_priority() { int priority = 100; # 基础优先级 # 同区域检测(+10) if bgp_community ~ [(64511, DN42_REGION)] then priority = priority + 10; # 同国家检测(+5) if bgp_community ~ [(64511, DN42_COUNTRY)] then priority = priority + 5; # eBGP直接邻居检测(+20) if bgp_path.len = 1 then priority = priority + 20; return priority; } 接着,在dnpeers模板中的导入过滤器中将bgp_local_pref设置为从函数计算出来的值: 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; } + bgp_local_pref = ebgp_calculate_priority(); accept; } reject; }; IPv6也如法炮制即可。 运行birdc configure之后,我们应该就能在自己的邻居那里看到我们的路由已经被打上了Communities标签: (此处截图来自:https://lg.milu.moe/route_all/hk/172.20.234.224) 特别感谢Nuro Trace大佬和Xe_iu大佬,他们帮助我加深了对BGP Communities的理解并提供了很多帮助 参考文章: [DN42] bird2的配置文件 – Xe_iu's Blog | Xe_iu的杂物间 [DN42] 谈一谈如何配置 BGP community – Xe_iu's Blog | Xe_iu的杂物间 BGP-communities - DN42 Wiki
2025年08月17日
33 阅读
0 评论
1 点赞
DN42探究日记 - Ep.1 加入DN42网络
写在前面 本人是BGP小白,文章中可能会存在不严谨内容/小白理解/低级错误,请诸位大佬们手下留情。若发现存在问题,您愿意的话可以邮件联系我,我会在第一时间更正。如果您不能接受,建议现在就关闭此文章。 欢迎与我建立对等连接!详情请查看:iYoRoy DN42 Network 想研究BGP,奈何租一个ASN和IP段实在是太贵了,又怕自己因为配置错误干掉半个互联网,因此决定研究一下DN42这个虚拟的网络。DN42是个大型去中心化网络,使用BGP协议建立路由,和当今互联网的结构很相像,因此适合用于BGP等网络技术学习。在DN42中,每个人都将扮演ISP(网络服务提供商)的角色,和其他用户Peer,以加入并参与建设整个DN42网络。DN42运行在172.20.0.0/14和fd00::/8上,这两个地址都是内网地址,因此不会影响到正常的互联网。 注册 你需要会使用基础的git指令、GPG、Linux,并且最好启用GPG签名Commit。 有Git使用基础的话可以参考我的commit:Add AS4242422024 · d1f9046ecb - registry - dn42 git Fork并克隆DN42注册表Git仓库 在dn42 git注册一个账号,并且Fork dn42/registry仓库。Clone下Fork出来的仓库并进入。 注册联系人 在data/person下创建文件<昵称>-DN42,填入如下内容: person: <姓名> e-mail: <邮箱> pgp-fingerprint: <GPG密钥指纹> nic-hdl: <NIC 句柄> mnt-by: <维护者> source: DN42 person: 名称 e-mail: 邮箱 pgp-fingerprint: GPG密钥指纹,会被用于一些认证服务 nic-hdl: NIC句柄,指向文件本身,直接填写当前文件名即可 mnt-by: 由谁维护,指向下文注册维护者一节中的维护者信息 source: 来源,保持DN42即可 www: 可选,可填网页地址 {collapse} {collapse-item label="示例"} data/person/IYOROY-DN42 @ dn42/registry@master person: Kagura iYoRoy e-mail:
[email protected]
www: https://www.iyoroy.cn pgp-fingerprint: 3ECCFFDEC2CB4CB8DA8089BE9AF2F2E03CE8FD67 nic-hdl: IYOROY-DN42 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册维护者 创建文件data/mntner/<昵称>-MNT,并填入如下内容: mntner: <昵称>-MNT admin-c: <联系人> tech-c: <联系人> auth: <验证方式> mnt-by: <维护者> source: DN42 mntner: 维护者名称,一般与文件名相同即可 admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 auth: 验证方式,支持pgp或者ssh-key mnt-by: 由谁维护,一般指向文件名本身即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/mntner/IYOROY-MNT @ dn42/registry@master mntner: IYOROY-MNT admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 auth: pgp-fingerprint 3ECCFFDEC2CB4CB8DA8089BE9AF2F2E03CE8FD67 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册ASN 在公网上,4200000000 - 4294967294为ASN保留范围。DN42使用了4242420000 - 4242429999,而目前开放注册的是4242420000 - 4242423999。官方不建议自己寻找可用ASN,而是推荐使用Burble的DN42 Free ASN Explorer,从中选取可用的ASN注册。 找好心仪的ASN后在data/aut-num创建<ASN,包含AS字母>文件,填写如下内容: aut-num: <ASN> as-name: <自治系统名称> descr: <自治系统描述> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> source: DN42 aut-num: 你选择的ASN,包含AS前缀。应该是AS424242xxxx的样式 as-name: 自治系统名称 descr: 自治系统描述,可以有空格 admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/aut-num/AS4242422024 @ dn42/registry@master aut-num: AS4242422024 as-name: IYOROYNET-AS-DN42 descr: iYoRoy DN42 Network admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册IPv4地址块并添加路由 如果你不想要注册IPv4,可以忽略本节 官方提供了一个用于检索可用地址块的工具:DN42 Free IPv4 Explorer 。同样不建议手动指定,而是建议用检索工具检索出来的可用地址块。 DN42同样面临IPv4地址短缺,所以请尽量按需注册。一般而言,一个/27地址块包含30个IPv4地址就够用了,如果是小型网络可以申请/28(14个可用地址)和/29(6个可用地址)。能直接申请的地址块最大是/26,也就是62个地址,若申请/25、/24则需要提交申请然后等待审核。详情可参考:DN42 实验网络介绍及注册教程(2022-12 更新) - Lan Tian @ Blog 选定你的IPv4地址块,然后在data/inetnum创建一个文件,命名为IPv4地址块的CIDR格式,并使用_代替/(如:我申请的IPv4地址块为172.20.234.224/28,则文件名为172.20.234.224_28),填入内容: inetnum: <IPv4地址块第一个地址> - <IPv4地址块最后一个地址> cidr: <IPv4地址块CIDR格式> netname: <IPv4地址块名称> descr: <IPv4地址块描述> country: <IPv4地址块所属国家代码> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> status: ASSIGNED source: DN42 inetnum: IPv4地址范围,从第一个地址到最后一个地址,中间用-连接 cidr: IPv4地址块CIDR格式,不需要用_代替/ netname: IPv4地址块名称,自行填写即可,无特殊要求 descr: IPv4地址块描述,中间可以有空格 country: ISO 3166中的两字符国家代码,中国就填CN admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 status: 状态,保存ASSIGNED即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/inetnum/172.20.234.224_28 @ dn42/registry@master inetnum: 172.20.234.224 - 172.20.234.239 cidr: 172.20.234.224/28 netname: IYOROYNET-DN42-V4 descr: iYoRoy DN42 Network IPv4 Block country: CN admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT status: ASSIGNED source: DN42 {/collapse-item} {/collapse} 接着,在data/route下同样创建一个名为IPv4地址块的 CIDR 格式,并使用_代替/的文件,填入内容: route: <IPv4地址CIDR格式> origin: <ASN> max-length: <IPv4掩码> mnt-by: <维护者> source: DN42 route: IPv4地址块,填写CIDR格式,无需转换/ origin: ASN,需要带AS max-lenth: 前缀长度(Prefix Length),即CIDR格式中/后面的数字 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/route/172.20.234.224_28 @ dn42/registry@master route: 172.20.234.224/28 origin: AS4242422024 max-length: 28 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 注册IPv6地址块并添加路由 如果你不想要注册IPv6,可以忽略本节 同样使用官方工具检索可用IPv6:DN42 Free IPv6 Explorer 。 选定地址块后在data/inet6num下创建名为IPv6地址块的CIDR格式,并使用_代替/的文件(如:我的IPv6地址块为fd18:3e15:61d0::/48,则文件名fd18:3e15:61d0::_48),填入内容: inet6num: <IPv6地址块第一个地址> - <IPv6地址块最后一个地址> cidr: <IPv6地址块CIDR格式> netname: <IPv6地址块名称> descr: <IPv6地址块描述> country: <IPv6地址块所属国家代码> admin-c: <管理员NIC句柄> tech-c: <技术人员NIC句柄> mnt-by: <维护者> status: ASSIGNED source: DN42 inet6num: IPv6地址范围,从第一个地址到最后一个地址,不可使用::简写,中间用-连接。也就是说,比如我的地址块是fd18:3e15:61d0::/48,我需要填入fd18:3e15:61d0:0000:0000:0000:0000:0000 - fd18:3e15:61d0:ffff:ffff:ffff:ffff:ffff。 cidr: IPv6地址块CIDR格式,不需要用_代替/ netname: IPv6地址块名称,自行填写即可,无特殊要求 descr: IPv6地址块描述,中间可以有空格 country: ISO 3166中的两字符国家代码,中国就填CN admin-c: 管理员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 tech-c: 技术人员联系信息,指向person文件夹中的文件,这里填上文注册联系人一节里的文件名即可 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 status: 状态,保存ASSIGNED即可 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/inet6num/fd18:3e15:61d0::_48 @ dn42/registry@master inet6num: fd18:3e15:61d0:0000:0000:0000:0000:0000 - fd18:3e15:61d0:ffff:ffff:ffff:ffff:ffff cidr: fd18:3e15:61d0::/48 netname: IYOROYNET-DN42-V6 descr: iYoRoy DN42 Network IPv6 Block country: CN admin-c: IYOROY-DN42 tech-c: IYOROY-DN42 mnt-by: IYOROY-MNT status: ASSIGNED source: DN42 {/collapse-item} {/collapse} 接着,在data/route6下同样创建一个名为IPv6地址块的 CIDR 格式,并使用_代替/的文件,填入内容: route6: <IPv6地址CIDR格式> origin: <ASN> max-length: <IPv6掩码> mnt-by: <维护者> source: DN42 route6: IPv6地址块,填写CIDR格式,无需转换/ origin: ASN,需要带AS max-lenth: 前缀长度(Prefix Length),即CIDR格式中/后面的数字 mnt-by: 由谁维护,指向上文创建维护者一节中的文件名 source: 来源,保持DN42即可 {collapse} {collapse-item label="示例"} data/route6/fd18:3e15:61d0::_48 @ dn42/registry@master route6: fd18:3e15:61d0::/48 origin: AS4242422024 max-length: 48 mnt-by: IYOROY-MNT source: DN42 {/collapse-item} {/collapse} 创建并上传commit,提交PR 最好使用GPG签名你的commit并且在dn42 git里上传你的公钥 填完上述信息,回到仓库根目录下,运行脚本./fmt-my-stuff <维护者>自动格式化配置文件。注意:此处<维护者>是上文注册维护者章节中的mntner的值。接着按照正常git commit流程git add data/、git commit -S -m "<commit-msg>"创建commit,git push origin master推送,接着,来到dn42 git网页端,打开你Fork的仓库并提交Pull Request即可。 如果配置有问题,自动审查机器人和管理员会告知你,请耐心按照要求修改并且合并到原来的commit中,不要新开commit,推荐add后使用git commit --amend指令。修改完直接强制推送(git push origin master --force) 即可。 DN42 Registry 的工作语言是英语。请使用英语完成全部流程,以免出现不必要的麻烦。 配置Bird 首先安装bird,以Ubuntu22.04为例: apt install bird2 -y 如果要一并安装后续使用的WireGuard,就再加上wireguard、wireguard-tools软件包: apt install bird2 wireguard wireguard-tools -y 编写配置文件 bird.conf 修改/etc/bird/bird.conf: define OWNAS = <AS 号>; define OWNIP = <DN42 IPv4 地址>; define OWNIPv6 = <DN42 IPv6 地址>; define OWNNET = <DN42 IPv4 地址块, CIDR 格式>; define OWNNETv6 = <DN42 IPv6 地址块, CIDR 格式>; define OWNNETSET = [ <DN42 IPv4 地址块, CIDR 格式>+ ]; define OWNNETSETv6 = [ <DN42 IPv6 地址块, CIDR 格式>+ ]; router id OWNIP; protocol device { scan time 10; } function is_self_net() { return net ~ OWNNETSET; } function is_self_net_v6() { return net ~ OWNNETSETv6; } function is_valid_network() { return net ~ [ 172.20.0.0/14{21,29}, # dn42 172.20.0.0/24{28,32}, # dn42 Anycast 172.21.0.0/24{28,32}, # dn42 Anycast 172.22.0.0/24{28,32}, # dn42 Anycast 172.23.0.0/24{28,32}, # dn42 Anycast 172.31.0.0/16+, # ChaosVPN 10.100.0.0/14+, # ChaosVPN 10.127.0.0/16{16,32}, # neonetwork 10.0.0.0/8{15,24} # Freifunk.net ]; } function is_valid_network_v6() { return net ~ [ fd00::/8{44,64} # ULA address space as per RFC 4193 ]; } protocol kernel { scan time 20; ipv6 { import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = OWNIPv6; accept; }; }; }; protocol kernel { scan time 20; ipv4 { import none; export filter { if source = RTS_STATIC then reject; krt_prefsrc = OWNIP; accept; }; }; } protocol static { route OWNNET reject; ipv4 { import all; export none; }; } protocol static { route OWNNETv6 reject; ipv6 { import all; export none; }; } include "rpki.conf"; include "ebgp.conf"; 此处OWNIP和OWNIPV6参数意为本机的DN42 IPv4和IPv6地址,不是地址块的地址,比如我申请到的地址段是172.20.234.224/28,我给A机器分配了172.20.234.225,则OWNIP为172.20.234.225,IPv6同理。 rpki.conf 你可能在其他教程里看到过使用定时任务+重载Bird的更新ROA方案,此处配置RPKI则是另一种配置ROA的方式。 创建/etc/bird/rpki.conf,填写如下内容: roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol rpki dn42_rpki_akix { roa4 { table dn42_roa; }; roa6 { table dn42_roa_v6; }; remote "<rpki服务器地址>" port 8082; # change it refresh 30; retry 5; expire 600; } RPKI服务器可以使用我朋友的AkaereIX提供的服务:rpki.akae.re {collapse} {collapse-item label="样例"} roa4 table dn42_roa; roa6 table dn42_roa_v6; protocol rpki dn42_rpki_akix { roa4 { table dn42_roa; }; roa6 { table dn42_roa_v6; }; remote "rpki.akae.re" port 8082; refresh 30; retry 5; expire 600; } {/collapse-item} {/collapse} ebgp.conf 创建/etc/bird/ebgp.conf,填入如下内容: template bgp dnpeers { local as OWNAS; path metric 1; ipv4 { import filter { if is_valid_network() && !is_self_net() then { if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then { print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } accept; } reject; }; export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; reject; }; import limit 1000 action block; }; ipv6 { import filter { if is_valid_network_v6() && !is_self_net_v6() then { if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then { print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last; reject; } accept; } reject; }; export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; reject; }; import limit 1000 action block; }; } include "peers/*"; 此配置项定义了DN42内部互相peer的模板,并且引用/etc/bird/peers下的所有配置文件,之后我们peer的时候就只需要在这里按照模板创建配置文件并编写即可。 创建/etc/bird/peers文件夹用作后续peer。 系统配置 内核 因为每个节点都可能会作为其他节点的路由器使用,因此需要打开Linux内核数据包转发;同时因为使用了WireGuard,并不是通过物理网卡转发,因此需要关闭rp_filter严格模式。 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.forwarding=1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.conf echo "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.conf echo "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.conf sysctl -p DN42虚拟网卡 因为MP-BGP通常使用LLA地址建立BGP,因此我们需要在系统里设置一个dummy网卡并绑定我们给这台机器分配的DN42 IP。运行以下指令: ip link add dn42 type dummy ip addr add <你给这这台机器分配的DN42 IPv4> dev dn42 ip addr add <你给这这台机器分配的DN42 IPv6> dev dn42 如果需要持久化配置,可以参考以下三种方式: {tabs} {tabs-pane label="systemd-networkd"} tee /etc/systemd/network/10-dn42.netdev > /dev/null <<EOF [NetDev] Name=dn42 Kind=dummy EOF tee /etc/systemd/network/20-dn42.network > /dev/null <<EOF [Match] Name=dn42 [Network] Address=<你给这台机器分配的DN42 IPv4>/32 Address=<你给这台机器分配的DN42 IPv6>/128 EOF systemctl enable systemd-networkd systemctl restart systemd-networkd {/tabs-pane} {tabs-pane label="netplan"} tee /etc/netplan/99-dn42.yaml > /dev/null <<EOF network: version: 2 renderer: networkd ethernets: dn42: match: name: dn42 addresses: - <你给这台机器分配的DN42 IPv4>/32 - "<你给这台机器分配的DN42 IPv6>/128" accept-ra: no EOF netplan apply {/tabs-pane} {tabs-pane label="/etc/network/interfaces"} tee -a /etc/network/interfaces > /dev/null <<EOF auto dn42 iface dn42 inet static address <你给这台机器分配的DN42 IPv4> netmask 255.255.255.255 iface dn42 inet6 static address <你给这台机器分配的DN42 IPv6>/128 EOF ifup dn42 {/tabs-pane} {/tabs} 与其他成员Peer 对新手较友好的应该就是Potat0大佬的自助Peer服务了,详情可参考他的DN42 Network页面。按照指引找到他的自动对等连接机器人,按照要求在机器人上注册你的账号,需要提供你的DN42 ASN、上文注册时Maintainer里记录的邮箱(这也是为什么在注册的时候最好需要填邮箱,很多验证服务都会使用),并且用该邮箱接收验证码,然后按照机器人的要求建立peer即可。以下是我通过Bot建立peer的过程,全程使用Ubuntu22.04系统的香港VPS操作。 安装WireGuard apt install wireguard wireguard-tools -y 注:现在的软件包管理一般会在安装wireguard的时候自动安装wireguard-tools以使用wg-quick指令。 生成密钥对 wg genkey | tee privatekey | wg pubkey > publickey 记下privatekey、publickey中的内容,代表私钥和公钥 建立Peer 一般而言有两种建立Peer的模式,即使用MP-BGP(Multiprotocol BGP,多协议BGP)和不使用MP-BGP。个人感觉MP-BGP更为常用,因为其配置较为简单。两种配置稍有不同,请根据你的需求参考。 使用MP-BGP 与Peer对方交换信息 你需要提供对方以下信息,同时你也需要知道对方的以下信息: 公钥 公网地址(非DN42地址) 公网WireGuard端口,一般是监听对方ASN的后5位 DN42 ASN LLA(Link-Local Address)地址,一般而言是fe80::<对方ASN后4位> 是否支持ENH(Extended Next Hop),注意,若使用v6交换路由而不启用ENH则无法交换v4路由 也有时会将公网地址和公网wg端口放在一起称作Endpoint。 配置WireGuard 在/etc/wireguard下创建一个配置文件,名称随意,但是我的命名习惯是dn42-<对方ASN后4位>.conf,其中dn42-xxxx即为隧道名。往文件内填入如下内容: [Interface] PrivateKey = <上文「生成密钥对」章节生成的私钥> ListenPort = <公网WireGuard监听端口> Table = off Address = <你的LLA地址>/64 PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对方给你的公钥> Endpoint = <对方的Endpoint,即IP:端口> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 编辑完成后保存,运行: wg-quick up <隧道名> 即可启动wg隧道。使用wg show <隧道名>即可查看连接状态。直接运行wg可查看所有隧道状态 如果需要让隧道开机自启动,可以运行: systemctl enable wg-quick@<隧道名> 配置Bird2的Peer部分 在/etc/bird/peers下新建文件<名称>.conf,填入如下内容: protocol bgp <BGP会话名称> from dnpeers{ neighbor <对方LLA地址> % '<WireGuard隧道名>' as <对方ASN,不带AS前缀>; }; 如果使用使用了Extended next hop(如上图交换信息时协商的),则配置: protocol bgp <BGP会话名称> from dnpeers{ neighbor <对方LLA地址> % '<WireGuard隧道名>' as <对方ASN,不带AS前缀>; ipv4{ extended next hop; }; }; 应用配置 运行birdc configure(或者birdc c,等同)重载Bird配置,然后运行birdc show protocols(或者birdc s p,等同)即可查看当前建立的BGP连接。 root@hkg2-202501092021514df2f0:~# birdc show protocols BIRD 2.0.12 ready. Name Proto Table State Since Info device1 Device --- up 07:24:14.255 static1 Static dn42_roa up 07:24:14.255 static2 Static dn42_roa_v6 up 07:24:14.255 kernel1 Kernel master6 up 07:24:14.255 kernel2 Kernel master4 up 07:24:14.255 static3 Static master4 up 07:24:14.255 static4 Static master6 up 07:24:14.255 dn42-0298 BGP --- up 08:03:13.347 Established dn42-1816 BGP --- up 07:53:05.028 Established 不使用MP-BGP 与Peer对方交换信息 你需要提供对方以下信息,同时你也需要知道对方的以下信息: 公钥 公网地址(非DN42地址) 公网WireGuard端口,一般是监听对方ASN的后5位 DN42 ASN DN42 IP,如果交换IPv4路由则需要IPv4地址,如果交换IPv6路由则需要IPv6地址 也有时会将公网地址和公网wg端口放在一起称作Endpoint。 配置WireGuard 在/etc/wireguard下创建一个配置文件,名称随意,但是我的命名习惯是dn42-<对方ASN后4位>.conf,其中dn42-xxxx即为隧道名。往文件内填入如下内容: [Interface] PrivateKey = <上文「生成密钥对」章节生成的私钥> ListenPort = <公网WireGuard监听端口> Table = off PostUp = ip addr add <LLA>/64 dev %i PostUp = ip addr add <本地DN42 IPv6> dev %i PostUp = ip addr add <本地DN42 IPv4> peer <对方DN42 IPv4> dev %i PostUp = sysctl -w net.ipv6.conf.%i.autoconf=0 [Peer] PublicKey = <对方给你的公钥> Endpoint = <对方的Endpoint,即IP:端口> AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe00::/8 编辑完成后保存,运行: wg-quick up <隧道名> 即可启动wg隧道。使用wg show <隧道名>即可查看连接状态。直接运行wg可查看所有隧道状态 如果需要让隧道开机自启动,可以运行: systemctl enable wg-quick@<隧道名> 配置Bird2的Peer部分 在/etc/bird/peers下新建文件<名称>.conf,填入如下内容: protocol bgp <v4BGP会话名称> from dnpeers{ neighbor <对方DN42 IPv4地址> as <对方ASN,不带AS前缀>; direct; ipv6{ import none; export none; }; }; protocol bgp <v6BGP会话名称> from dnpeers{ neighbor <对方DN42 IPv6地址> % '<WireGuard隧道名称>' as <对方ASN,不带AS前缀>; direct; ipv4{ import none; export none; }; }; 应用配置 运行birdc configure(或者birdc c,等同)重载Bird配置,然后运行birdc show protocols(或者birdc s p,等同)即可查看当前建立的BGP连接。 自此,我们成功加入了DN42网络。要想让网络更加稳定,我们可以与更多用户进行Peer,建立多条BGP线路以防止其中部分节点瘫痪导致失联。你可以加入DN42非官方tg交流群获取更多信息。 如果出现BGP Established但是无法Ping通DN42内部IP的情况,请检查bird.conf中设置的IP和dummy网卡分配的IP或WireGuard中的本地IP是否相同。 配置DNS DN42内有自己的公共DNS,泛播地址为172.20.0.53,并且也能解析正常互联网的域名。要想能够访问以dn42结尾的内部域名,需要将这个地址放到resolv.conf最上面: nameserver 172.20.0.53 nameserver 223.5.5.5 #下面是正常的DNS服务器配置 之后就可以解析DN42内部域名啦,同时ping、traceroute、mtr等命令查询内部IP时也能显示出来rDNS的解析结果。 欢迎与我建立对等连接!详情请查看:iYoRoy DN42 Network 参考文章: https://blog.baoshuo.ren/post/dn42-network/ https://dn42.dev/howto/Bird2#example-configuration https://dn42.eu/howto/wireguard https://blog.udon.eu.org/archives/dbf21067.html https://blog.byteloid.one/2025/06/02/babeld-over-wireguard/ https://blog.wcysite.com/2021/%E8%B8%A9%E5%9D%91DN42-p2-peer/ https://blog.chs.pub/p/23-14-joindn42/ https://www.cnblogs.com/FengZeng666/p/15583434.html
2025年06月28日
95 阅读
3 评论
1 点赞