Table of Contents
前言
DN42 是一個大型、去中心化的 VPN 網路,使用到了如 BGP, whois database, DNS 等等的網路技術,你可以在上面模擬一個真實的網路環境。
其實這篇文章我很早就想寫了,不過最近在期中考,還有一堆報告要做就一直拖到現在了 (去年 11/29 就註冊了)。
能力需求
-
一定的英文能力 (查看官方文檔)
-
一個 Linux 環境 (雙系統 / 虛擬機 / VPS)
-
知道如何使用 Linux 指令,編輯器等
-
Git 的基本使用
-
一定程度的網路知識
開始註冊
-
首先先去 https://git.dn42.dev/ 註冊帳號
-
到 dn42/registry Fork 該儲存庫到自己的帳戶
-
將 Fork 到你帳戶的儲存庫 Clone 下來
-
進入你 Clone 下來的儲存庫,在裡面創建以下文件:
- 在
data/mntner/中創建一個名叫[暱稱]-MNT的檔案
mntner: [暱稱]-MNTadmin-c: [暱稱]-DN42tech-c: [暱稱]-DN42mnt-by: [暱稱]-MNTauth: ssh-ed25519 0123456789ABCDEF0123456789ABCDEF01234567source: DN42注意,中間的間隔不要刪減,這是 DN42 的規定
auth 是驗證方式,若要使用需在 gitea 中新增金鑰,支援方式有 SSH 或 GPG- 在
data/person/中創建一個名叫[暱稱]-DN42的檔案
person: [你的名字]e-mail: example@example.comnic-hdl: [暱稱]-DN42mnt-by: [暱稱]-MNTsource: DN42- 註冊 AS 號碼,在
data/aut-num/中創建一個名叫AS424242XXXX的檔案,AS424242XXXX為你的 AS 號碼
你可以在 dn42regsrv 挑選喜歡的號碼
aut-num: AS424242XXXXas-name: AS-[暱稱]-DN42admin-c: [暱稱]-DN42tech-c: [暱稱]-DN42mnt-by: [暱稱]-MNTsource: DN42-
註冊網路區段
- IPv6:
你可以在 dn42regsrv 挑選喜歡的號碼,然後在data/inet6num/中創建一個你挑選的網段的檔案,(e.gfd63:c95c:25a0::_48)
inet6num: fd63:c95c:25a0:0000:0000:0000:0000:0000 - fd63:c95c:25a0:ffff:ffff:ffff:ffff:ffffcidr: fd63:c95c:25a0::/48netname: [暱稱]-NETWORKdescr: Network of [暱稱]country: TWadmin-c: [暱稱]-DN42tech-c: [暱稱]-DN42mnt-by: [暱稱]-MNTstatus: ASSIGNEDsource: DN42- IPv4 (舊版):
你可以在 dn42regsrv 挑選喜歡的號碼,然後在data/inetnum/中創建一個你挑選的網段的檔案,(e.g172.22.125.0_27)
inetnum: 172.22.125.0 - 172.22.125.31cidr: 172.22.125.0/27netname: [暱稱]-NETWORKdescr: Network of [暱稱]country: TWadmin-c: [暱稱]-DN42tech-c: [暱稱]-DN42mnt-by: [暱稱]-MNTstatus: ASSIGNEDsource: DN42 - IPv6:
-
創建 route 對象
- IPv6:
在data/route6/中創建一個你挑選的網段的檔案,(e.gfd63:c95c:25a0::_48)
route6: fd63:c95c:25a0::/48origin: AS424242XXXXmax-length: 48mnt-by: [暱稱]-MNTsource: DN42- IPv4:
在data/route/中創建一個你挑選的網段的檔案,(e.g172.22.125.0_27)
route: 172.22.125.0/27origin: AS424242XXXXmax-length: 27mnt-by: [暱稱]-MNTsource: DN42 - IPv6:
- 在
-
推送到儲存庫,你已經創建完所需的檔案了,回到儲存庫的根目錄,接著進行以下步驟:
-
執行這三個指令以驗證你的更改:
./fmt-my-stuff [暱稱]-MNT./check-my-stuff [暱稱]-MNT./check-pol origin/master [暱稱]-MNT
-
設定 Git 簽署金鑰,這邊示範的是 SSH,有需要可以參考 Github:
git config --global gpg.format sshgit config --global user.signingkey /PATH/TO/.SSH/KEY.PUB
-
執行
git add .及git commit -S -m "commit message",commit message視情況修改,由於你是第一次註冊,你可以打Join DN42之類的 -
執行
./squash-my-commits -S --push,這個腳本將會把你目前的儲存庫與上游進行同步並推送
-
-
最後到 dn42/registry 發起 Pull Request,記得用英文,然後就是等管理員合併你的 Pull Request
尋找 Peers
你可以使用 DN42 PingFinder,測試與其他使用者的延遲,根據他們留下的資訊去聯繫他們。
重要系統配置
執行下方指令,開啟封包轉送功能及關閉 rp_filter
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.confecho "net.ipv6.conf.default.forwarding=1" >> /etc/sysctl.confecho "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.confecho "net.ipv4.conf.default.rp_filter=0" >> /etc/sysctl.confecho "net.ipv4.conf.all.rp_filter=0" >> /etc/sysctl.confsysctl -p防火牆請自行配置,不要使用 UFW 等幫助你簡單設定 iptables 的軟體,最好是自己手動配置 iptables。
建立隧道
在 DN42 上,幾乎每個 Peering 都是建立在隧道上 (VPN),推薦的有 Wireguard 及 OpenVPN,我個人偏好使用 Wireguard,本篇文章也是以 Wireguard 來撰寫。
首先安裝 Wireguard,輸入這串指令安裝 Wireguard
apt install wireguard -y接著進入 /etc/wireguard,執行這串指令創建公鑰及私鑰
wg genkey | tee privatekey | wg pubkey > publickey創建一個名叫 wg_[PEER_NAME].conf 的檔案,其實前面不用加 wg,名稱可以自訂,不過這樣會比較好分辨隧道
[Interface]# 你的 Wireguard 私鑰PrivateKey = ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFA=# 你監聽的連接埠,一般是 Peer 的 ASN 後五碼ListenPort = 21816# 新增 Link-Local IPv6 (如 fe80::1111)PostUp = ip addr add <Link-Local>/64 dev %iTable = off
[Peer]# 你的 Peer 的 Wireguard 公鑰PublicKey = ABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFABCDEFA=# 你的 Peer 的伺服器位址及連接埠Endpoint = <Peer 的公網位址>:<Peer 的連接埠>AllowedIPs = 10.0.0.0/8, 172.20.0.0/14, 172.31.0.0/16, fd00::/8, fe80::/64之後創建一個 dummy 網卡把你 DN42 的 IP 綁上去,不然路由可能無法寫到內核
ip link add dn42_dummy type dummyip addr add <你 DN42 的 IPv4 位址的第一個 IP>/32 dev dn42_dummyip addr add <你 DN42 的 IPv6 位址的第一個 IP>/128 dev dn42_dummyip link set dn42_dummy up接著輸入 wg-quick up wg_[PEER_NAME] 啟動隧道
輸入 systemctl enable wg-quick@wg_[PEER_NAME] 讓隧道在開機後能自行啟動
輸入 wg 確認隧道狀態,應該會像下圖
接著可以 ping 看看對面
ping fe80::XXXX%wg_[PEER_NAME]由於 dummy 網卡重啟後就會消失,因此需要寫入配置文件,Ubuntu 可以使用 netplan
在 /etc/netplan 創建一個名叫 51-dn42-dummy.yaml 的檔案,前面的數字依該目錄檔案而決定,如果有其他檔案記得數字一定要大於該檔案的數字
network: version: 2 dummy-devices: dn42_dummy: addresses: - <你 DN42 的 IPv4 位址的第一個 IP>/32 - <你 DN42 的 IPv6 位址的第一個 IP>/128建立 BGP 會話
我使用的是 BIRD,配置過程複雜,像是在寫程式,不習慣的人最好還是用 FRRouting 之類的路由程式
記得修改前面的區塊成自己的
################################################# Variable header #################################################
define OWNAS = <你的 ASN>;define OWNIP = <你 DN42 的 IPv4 位址的第一個 IP>;define OWNIPv6 = <你 DN42 的 IPv6 位址的第一個 IP>;define OWNNET = <你 DN42 的 IPv4 位址區段>/27;define OWNNETv6 = <你 DN42 的 IPv6 位址區段>/48;define OWNNETSET = [<你 DN42 的 IPv4 位址區段>/27+];define OWNNETSETv6 = [<你 DN42 的 IPv6 位址區段>/48+];
################################################# Header end #################################################因為我們要使用 extended next hops,因此還需新增一段內容
template bgp dnpeers { local as OWNAS; path metric 1;
ipv4 { # 開啟 extended next hops 功能 extended next hop on;
import filter { if is_valid_network() && !is_self_net() then { if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then { # Reject when unknown or invalid according to ROA 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 9000 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 { # Reject when unknown or invalid according to ROA 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 9000 action block; };}ROA 的配置也請參考官方 Wiki 的配置
接著在 /etc/bird/ 中創建名叫 peers 的資料夾,在裡面創建名叫 dn42_[PEER_NAME].conf 的檔案
protocol bgp dn42_[PEER_NAME]_v6 from dnpeers { # 設置對面的 Link-Local IPv6,隧道介面及 ASN neighbor fe80::XXXX % '<Wireguard 隧道介面>' as <對方的 ASN>; direct;}之後輸入 birdc c 或 systemctl restart bird 重新加載配置
輸入 birdc s p 可查看連線狀況,如果是 Established 就代表 Peer 成功了
之後就可以 Ping 一下 DN42 裡的服務,如 DNS (172.20.0.53)
Peer with me!
我的 DN42 資訊:
- ASN:
AS4242421925 - IPv4 prefix:
172.21.75.128/27 - IPv6 prefix:
fd1c:4efc:f725::/48
聯絡方式:
- Email: bobchen3310@bob0623.net
結語
其實可以做的事還很多,目前這樣就只是最基礎的,接下來可以做的還有深入了解 Bird2 的配置,在 DN42 中架設服務等等的,之後我會再寫一篇文章來記錄。
目前我正在研究 AutoPeer 服務,想跟我 Peer 的敬請期待