入坑DN42
网络就像一片浩瀚的海洋,多多探索总能发现许多有趣的东西,最近本来想着注册一个ASN,并学习与实践一下BGP,但是注册一个公网的ASN需要一笔钱,并且在公网中配置路由一旦出错可能还会造成严重的后果(除此之外,个人身份注册的ASN还有实名上网之忧),在查询资料的时候了解到了DN42这个实验网络。 并且在Lan Tian的博客中看到了非常详细的教程,于是决定公网ASN的注册先放一边,从DN42开始BGP学习与折腾之路。
DN42 全称 Decentralized Network 42(42 号去中心网络)。DN42 的目的是模拟一个互联网。它使用了大量在目前互联网骨干上应用的技术(例如 BGP 和递归 DNS),可以很好地模拟一个真实的网络环境
注册部分蓝天的博客和DN42的wiki以及这篇文章都有详细的介绍,我这里就不再赘述了。
填好信息发起合并请求后的一到两天内,管理员就会把提交的信息合并进入主分支。
我的ASN是AS4242420945,欢迎各位大佬来和我peer(虽然我现在自己都不是特别熟悉)
建立内网
在peer他人之前还是先把自己的网络给整明白了,我的计划是使用wireguard建立一个接近全网状的网络,为什么说是“接近”,因为考虑到我有部分没有公网ip的设备在未来可能也要接入这个网络,所以并不是还是需要依靠部分节点来作为中继。
初期使用五台服务器建立ASN内部网络(可以把他们都看成网络中的路由器,因为它们都需要开启包转发功能,可以进行转发)
网络内部服务器之间的连接
首先尝试让网络内部的机器直接或间接连接,我的网络地址范围是 172.20.210.0/26,即 172.20.210.0 - 172.20.210.63 这一段的地址,那么给下面的五个节点分配ip如下:
lax-1(洛杉矶) 172.20.210.1
lax-2(洛杉矶) 172.20.210.2
icn-1(首尔) 172.20.210.3
hkg-1(香港) 172.20.210.4
ovb-1(新西伯利亚) 172.20.210.5
首先这五台机器都得装好了wireguard
老内核的话先更新内核(可能还得使用backports源):
使用backports源 更新
1 2 3 4 5 6 7
echo "deb http://deb.debian.org/debian $(lsb_release -sc)-backports main" | tee /etc/apt/sources.list.d/backports.list apt update apt -t $(lsb_release -sc)-backports install linux-image-$(dpkg --print-architecture) linux-headers-$(dpkg --print-architecture) --install-recommends -y apt install net-tools iproute2 wireguard
手动下载安装
1 2 3 4 5
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10.63/amd64/linux-headers-5.10.63-051063-generic_5.10.63-051063.202109080732_amd64.deb wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10.63/amd64/linux-headers-5.10.63-051063_5.10.63-051063.202109080732_all.deb wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10.63/amd64/linux-image-unsigned-5.10.63-051063-generic_5.10.63-051063.202109080732_amd64.deb wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.10.63/amd64/linux-modules-5.10.63-051063-generic_5.10.63-051063.202109080732_amd64.deb dpkg -i *.deb
再开启了ip包转发,并关闭rp_filter严格模式:
|
|
然后启动wireguard接口,注意,在每两台建立连接的服务器之间都要创建一个接口,我一开始配置的时候采用了一个配置文件中写上所有其他的Peer对象的方式,但是这样是有问题的,如果我们需要路由目的地址在我们的内部网络之外的数据包时,如果采用了单一接口的方式,那么所有的Peer中的Alllowips都是0.0.0.0/0,这里的路由会出现问题。而分成多个接口时,wireguard可以只负责传输数据,路由(接口选择)在数据包进入wireguard的接口之前就进行。
注意,务必加上Table=off 避免wg-quick修改路由,在这里,wireguard只应该负责传输数据。
wireguard的配置方式有多种,我尝试了其中的两种:
wg的接口另外分配链路本地地址,单独将dn42地址绑定到dummy接口或lo接口
这种情况下,我们可以将两个链路本地地址分别绑定在wireguard两端的端点上,并将dn42地址绑定到dummy接口或者lo接口上,下面是我的配置文件:
wireguard和bird的配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12
[Interface] Address = fe80::3/64 ListenPort = 50000 PrivateKey = MTU = 1420 PostUp = ip addr add dev %i 169.254.3.4/32 peer 169.254.4.3/32 Table = off [Peer] PublicKey = AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = hkg1:50000 PersistentKeepalive = 16
之后创建dummy接口并绑定地址
1 2 3 4 5
ip link del dummy ip link add dummy type dummy ip addr add 172.20.210.3/32 dev dummy ip addr add fde5:2a75:1037::3/128 dev dummy ip link set dummy up
在所有服务器的wireguard都启动后,服务器之间已经建立了直接或间接地连接,但是此时还没有路由规则,我们需要来设置路由。
wg的接口直接分配dn42地址,详见howto/wireguard的wg-quick部分,其实多个接口是可以绑定同一个ip的,和绑定链路本地地址的区别就是在bird中设置neighbor的时候需要使用对方的DN42地址,这种方式可能也需要添加一个dummy接口,方便导出路由。(也许有其他的方法,不过我还没找到。)
1 2 3 4 5 6 7 8 9 10 11
[Interface] ListenPort = 50001 PrivateKey = [privatekey] PostUp = ip addr add 172.20.210.1/32 peer 172.20.210.2/32 dev %i PostUp = ip addr add fde5:2a75:1037::1/128 peer fde5:2a75:1037::2/128 dev %i Table = off [Peer] PublicKey = [pubkey] AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = icn1:50001 PersistentKeepalive = 16
网络内部的路由
现在asn内部的节点是可以直接互联了,但是他们当前的连接方式是直接连接,而不是像现实中采取一条最佳的路径(如延迟最低),并且如果我们需要动态的加入一些只和部分节点连接的节点时,这个网络内的其他节点会找不到到新节点的路径,所以我们还需要使用内部的动态路由协议。
路由软件使用 bird2,先apt-get install bird2
进行安装,因为是初次接触bird,所以这里踩了很多的坑,最终才产出了一个“勉强能用,但是不知道有什么问题“的网络。
ospf
首先尝试使用ospf来进行网络内部的动态路由。
这部分可以参考下面的文章:
- Multiple servers on dn42: iBGP and IGPs
- Wireguard的搭建与使用配置
- BIRD 与 BGP 的新手开场
- WireGuard + OSPF - NYC Mesh
- howto/wireguard
bird2的配置文件如下:
bird的配置如下(我强烈怀疑里面还有哪里存在未发现的问题…) 参考 BIRD 与 BGP 的新手开场
|
|
|
|
各台服务器上都设置好bird之后,使用systemctl start bird
启动服务,之后便可以试试 birdc show ospf neighbors
查看直接相连的邻居,或者 birdc show route
查看一下路由,或者干脆是mtr
一下看看实际的路径,在我的配置中存在一个节点只和网络中的部分相连,可以看到通过ospf配置后,其他节点也可以与其间接相连了。
另外可以尝试修改cost,看看路径会发生什么变化,如下图,我修改了lax1~lax2的开销,强制让两台离得很近的服务器绕路连接: lax1-hkg1-icn1-lax2,在实际使用中我将cost设置为了服务器间的延迟。
BGP互联
在整理好了内部网络之后,我们便可以尝试和他人peer了,这样才能算是真正加入了dn42网络,关于bird bgp的配置,wiki里面提供了比较详细的介绍,我就不再重复了。官方模板提供了充足的过滤检查规则,避免你一不小心导出了错误的信息劫持网络的路由。
我采取的对接方法是:
双方使用wireguard建立连接,两端分配链路本地地址,dn42的地址则分配给dummy接口
wireguard中的配置如下
1 2
PostUp = ip addr add dev %i [本机链路本地地址]/32 peer [对方的机器的链路本地地址]/32 PostDown = ip addr del dev %i [本机链路本地地址]/32 peer [对方的机器的链路本地地址]/32
在bird的配置文件中将peer的neighbor ip设置为对方的链路本地地址
双方启动bird,通过bird来配置dn42 ip的路由
另外还可以使用dn42 ip peer或者使用ipv6 link local地址peer,可以参考这篇文章.
peer之后没多久,便能在一些查看DN42网络图的网站上看见自己的as号了(前提是你peer的人能够到达dn42网络的较中心的位置),如图,我通过peer一个接入了不少网络的as4242422032得以访问到DN42网络的大多数地方,这点和现实中的网络非常像。
之后我们可以尝试ping一下dn42网络中的一些服务看看能否正常连接,比如
Service | Name | IP |
---|---|---|
Authoritative Service | ns1.burble.dn42 | 172.20.129.1 fd42:4242:2601:ac53::1 |
Recursive Service | dns.burble.dn42 | 172.20.129.2 fd42:4242:2601:ac53::53 |
DNS64 Service | dns64.burble.dn42 | fd42:4242:2601:ac53::64 |
BGP信息在内部的传输
在建立了bgp连接之后我们又会发现一个新的问题——bgp获得的路由信息只在建立了bgp连接的服务器上可用,网络中的其他服务器无法通过ospf获取到其他网络路由。 这时正常的 bgp获取的路由不应该使用igp在网络中传播,因为ospf在网络内传输路由的时候会丢失bgp的aspath等信息,如果网络中的另一台服务器和另外一个网络中的服务器建立了bgp会话,对方又没做ROA限制,那么你的其他网络的路由也会以你的ASN为起点传输出去,这样相当于把别人的路由给劫持掉了。关于BGP中存在的一些隐患可以查看 如何引爆 DN42 网络。
于是我们需要一个方法来解决内部的路由传播。
ipv4 的链路本地地址没有作用域的概念,所有地址都是属于主机的
蓝天提供了模拟confederation来在内部传播bgp的路由,不过我打算先从简单的开始,先使用ibgp,需要注意的是,为了避免出现环路,路由器不会向其他路由器发送从同一个AS下的路由器收到的BGP路由,所以我们要让网络中的所有路由器(服务器)都与所有的边界路由器(与其他AS建立BGP会话的服务器)建立起BGP会话,这样才能够让网络中的所有服务器都收到跨ASN的路由信息,另外提一点,由于我们在内网使用了OSPF,所以建立BGP会话并不需要建立一个直接连接的隧道,间接连接也是可以的。
iBGP
这部分参考了: Multiple servers on dn42: iBGP and IGPs
在 bird.conf 中添加一个模板
|
|
并在配置文件后面追加 include "/etc/bird/ibgps/*";
。
再新建一个ibgps文件夹,里面存放边界路由器相关的配置,如 lax1.conf: (放多个邻居在这个文件中也是可以的),边界路由器和内部的路由器都要设置ibgp,邻居ip设置为对方的ip即可,内部的路由会由ospf负责。
|
|
重启bird之后再尝试在我们内部的服务器上ping dns42网络内部其他asn内的ip,比如 ping 172.20.129.1
,此时已经能得到回应了。之后在网络内的每一台服务器都配置了与边界服务器的bgp会话,由此,整个网络才算真正接入到了DN42中。
尝试由新加坡trace到dn42内的权威域名服务器。
后记
之前BGP、IGP这些概念不过是书本上抽象的知识,直到这次加入DN42网络,我才第一次在实际中使用到了这些协议,不过目前我的配置还基本上是"知其然,不知其所以然",很多配置都来源于照抄网上的资料,并没有真正弄明白为什么要这样写(可能存在BUG都不自知)。另外对于这些路由协议我依旧只有一个模糊的认识,缺少系统性的学习,接触到这些之后才发觉自己在网络方面的知识还是相当的匮乏,还有相当多的东西要学习,这些都需要在之后的实践中慢慢补足。在配置好BGP后,我又参考骏马金龙的第7章 DNS & bind从基础到深入为我的网络设置好了正向与反向解析。
另外,欢迎来和我peer~
ASN 4242420945
目前接入点有:
- 洛杉矶
- 首尔
- 香港
- 新西伯利亚
发邮件到 aoyou945@gmail.com 或者评论都可以。
参考
https://weiti.org/dn42/2018/01/13/ibgp-bgp-within-as4242423905
https://jlu5.com/blog/dn42-multiple-servers-ibgp-igps
https://miaotony.xyz/2021/03/25/Server_DN42/
https://idndx.com/ospf-over-wireguard/