SJ's Here
SJ's Here

NS 与 WG 与 DN42

NS 与 WG 与 DN42

前言

最近开始折腾 DN42 了。申请完了 ASN 和 IP 段,但却发现自己没有什么空闲服务器能拿来 peering ,在现有的服务器上做 peering 又怕影响已经存在的服务。经过一番探索后,发现了使用 Wireguard 与 netns 搭配的奇妙用法。

Network Namespaces

Network namespaces 是一个 Linux 内核特性,直接翻译过来叫做网络命名空间,下文简称为 netns 。

每个 netns 都会拥有自己的网络栈(网络接口、IP 地址、路由表、netfilter 规则等等)。

WireGuard

WireGuard 是一个 VPN 协议,现已成为 Linux 内核的一部分。由于配置简单、易于部署和管理、内核级实现和跨平台支持等优点,WireGuard 现已经成为了建立三层隧道的首选。在 DN42 网络中,大部分 Autopeer 系统都将 WireGuard 作为唯一选择。

但这次专门提到 WireGuard 并不是因为它的流行,而是因为它与 netns 配合使用时一个有趣的特性——当 WireGuard 接口被创建时,它会记住自己此时所属的 netns ,即使之后被移动到其它的 netns ,WireGuard 用于实际通信的 UDP socket 也属于接口创建时所属的 netns 。利用这个特性,我们便可以创建独立的 netns ,且其中仅有用于 peering 的 WireGuard 接口。

https://blog.seraphjack.top/wp-content/uploads/2023/03/image-1024x643.png
仅有一个 WireGuard 接口的 netns

DN42

有了以上这些发现,我们便可以创建单独的 netns 用于 DN42 Peering 。要做的事情只有以下几件:

创建 DN42 netns ,并配置 lo 接口

ip netns add dn42
ip netns exec dn42 ip addr add 127.0.0.1/8 scope host dev lo
ip netns exec dn42 ip link set lo up

创建 WireGuard 接口并配置 IP 地址

# 注意 WireGuard 配置中应使用 Table = off
wg-quick up $WG_INTERFACE
ip link set $WG_INTERFACE netns dn42

ip netns exec dn42 ip link set $WG_INTERFACE up
ip netns exec dn42 ip addr add $ROUTER_IP peer $PEER_IP dev $WG_INTERFACE
ip netns exec dn42 ip addr add $LOCAL_IP_V6 peer $PEER_IP_V6 dev $WG_INTERFACE

等所有 WireGuard 接口都创建完毕后,便可以启动 Bird 之类需要在 DN42 netns 中运行的服务。要让 Systemd service 运行在指定的 netns 中,只需稍微修改 Service unit 的定义:

...
[Service]
NetworkNamespacePath=/run/netns/dn42
...

这些步骤可以整理到一个 Systemd target 和多个 Service 中,具体可以在我的 GitHub 上查看。

See Also

Linux namespaces (Wikipedia)

Routing & Network namespaces – WireGuard

发表回复

textsms
account_circle
email

SJ's Here

NS 与 WG 与 DN42
前言 最近开始折腾 DN42 了。申请完了 ASN 和 IP 段,但却发现自己没有什么空闲服务器能拿来 peering ,在现有的服务器上做 peering 又怕影响已经存在的服务。经过一番探索后,发现了…
扫描二维码继续阅读
2023-03-17