前言
Leko 其實一直都在煩惱,有沒有甚麼 VPN 可以支援 L2 讓我能發 SLAAC 的 :(
昨天和友人在聊天的時候,對方正在用 OpenVPN 打 Tunnel,我靈光一現突然想到,ZeroTier 不也是 L2 的嗎?
試了一下果真成功了,就在這邊紀錄一下。
環境
Leko 的環境如下:
- RouterOS VM (發放 DHCP-PD 給有 ZT 的 CT)
- Ubuntu 18.04 CT (ZeroTier Host,負責發 SLAAC)
環境非常自由,前二者只要能達到括號內的需求應該都可以,甚至可以放在同一台。
CT 網路說明
網路卡 int0
負責上網 (接入公網),這裡我的配置是帶有 UPnP 的 IPv4 NAT。
(UPnP 讓 ZeroTier 可以自動穿透)
網路卡 eth0
用來接收 RouterOS 發放的 DHCP-PD。
步驟
以下操作都假設在 root 下進行。
因為 Ubuntu 預設有一個 systemd-resolved
負責解析 Hostname,占用 53 Port 會影響我們後續操作,因此我們先把它關掉:
[email protected]:~# systemctl disable systemd-resolved
[email protected]:~# systemctl stop systemd-resolved
然後我們拿一些必要套件。
[email protected]:~# apt update && apt install curl wide-dhcpv6-client gnupg2 dnsmasq
[email protected]:~# curl -s https://install.zerotier.com | bash
接著加入我們的 ZeroTier Network:
[email protected]:~# zerotier-cli join [ID]
然後把新增的網路卡名稱記著,之後會用到:
[email protected]:~# ip a
接著開啟轉發:
[email protected]:~# nano /etc/sysctl.conf
[email protected]:~# sysctl -p
# /etc/sysctl.conf
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1
net.ipv6.conf.all.accept_ra = 2
然後設定 DHCPv6-PD 並重新啟動,注意把 config 內的 ztnfapdryf
換成自己的 ZT 網卡名稱:
[email protected]:~# nano /etc/wide-dhcpv6/dhcp6c.conf
[email protected]:~# nano /etc/systemd/system/wide-dhcpv6.service
[email protected]:~# systemctl enable wide-dhcpv6.service
[email protected]:~# reboot
# /etc/wide-dhcpv6/dhcp6c.conf
interface eth0 {
# request a non-temporary address
# request prefix delegation address
send ia-pd 1;
request domain-name-servers;
request domain-name;
};
id-assoc pd 1 {
prefix ::/64 infinity;
prefix-interface ztnfapdryf {
sla-len 0;
# elated with ia-pd to configure subnet on lan interface - eth1
sla-id 1;
# "postfix" of IPv6 address on lan interface.
# if not configured interface will has EUI-64 (mac based) address.
# In this case, eth1 will get a IPv6 ending with ::1
ifid 1;
};
};
# /etc/systemd/system/wide-dhcpv6.service
[Unit]
Description=wide-dhcpv6
Before=dnsmasq.service
After=network.target ypbind.service nfs.service nfsserver.service rpcbind.service SuSEfirewall2_init.service
[Service]
ExecStart=/usr/sbin/dhcp6c -c /etc/wide-dhcpv6/dhcp6c.conf -P default -d -D -f eth0
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
重新啟動後,應該可以看到 ZeroTier 的網卡上多了一個 [Prefix]::1
的 IP。
接著我們設定 SLAAC 和 RA,注意把 config 內的 ztnfapdryf
換成自己的 ZT 網卡名稱:
[email protected]:~# nano /etc/dnsmasq.conf
[email protected]:~# systemctl enable dnsmasq.service
[email protected]:~# systemctl restart dnsmasq.service
# /etc/dnsmasq.conf
except-interface=eth0
bogus-priv
enable-ra
# Create a IPv6 range from address on the interface. The ::1 is related to the ifid in /etc/wide-dhcpv6/dhcp6c.conf.
dhcp-range=tag:ztnfapdryf,::1,constructor:ztnfapdryf, ra-names, 12h
# ra-names - it gives DNS names to IPv6 hosts
local=/lan/
然後我們新增預設路由並讓他開機自動啟動:
[email protected]:~# nano route.sh
[email protected]:~# nano /etc/init/route.conf
請將 fe80::908c:eeff:fe18:5c56
換成上游的 IP,ztnfapdryf
換成 ZT 的網卡名稱:
#!/bin/sh
# route.sh
ip -6 r add default via fe80::908c:eeff:fe18:5c56 dev eth0
ip6tables -A FORWARD -m state --state NEW -i ztnfapdryf -o eth0 -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -P FORWARD DROP
接著在 ZT 內新增一段預設路由:
其中 10.147.18.45
是我的 CT IP,記得換成你的哦。
然後 ZT 加入其他 Peer 的時候記得開啟 Allow Default Route 跟 Allow Global,應該就能拿到 IPv6 了。
yay
附上完整的指令列表:
#!/bin/sh
systemctl disable systemd-resolved
systemctl stop systemd-resolved
apt update
apt install curl wide-dhcpv6-client gnupg2 dnsmasq
curl -s https://install.zerotier.com | bash
zerotier-cli join [ID]
# ztnfapdryf
nano /etc/sysctl.conf
sysctl -p
nano /etc/wide-dhcpv6/dhcp6c.conf
nano /etc/systemd/system/wide-dhcpv6.service
systemctl enable wide-dhcpv6.service
reboot
nano /etc/dnsmasq.conf
systemctl enable dnsmasq.service
systemctl restart dnsmasq.service
nano route.sh
nano /etc/init/route.conf