前言 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 會影響我們後續操作,因此我們先把它關掉:
1 2 root@CT:~# systemctl disable systemd-resolved root@CT:~# systemctl stop systemd-resolved
然後我們拿一些必要套件。
1 2 root@CT:~# apt update && apt install curl wide-dhcpv6-client gnupg2 dnsmasq root@CT:~# curl -s https://install.zerotier.com | bash
接著加入我們的 ZeroTier Network:
1 root@CT:~# zerotier-cli join [ID]
然後把新增的網路卡名稱記著,之後會用到:
接著開啟轉發:
1 2 root@CT:~# nano /etc/sysctl.conf root@CT:~# sysctl -p
1 2 3 4 5 6 7 8 9 10 # /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 網卡名稱:
1 2 3 4 root@CT:~# nano /etc/wide-dhcpv6/dhcp6c.conf root@CT:~# nano /etc/systemd/system/wide-dhcpv6.service root@CT:~# systemctl enable wide-dhcpv6.service root@CT:~# reboot
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # /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; }; };
1 2 3 4 5 6 7 8 9 10 11 12 13 # /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 網卡名稱:
1 2 3 root@CT:~# nano /etc/dnsmasq.conf root@CT:~# systemctl enable dnsmasq.service root@CT:~# systemctl restart dnsmasq.service
1 2 3 4 5 6 7 8 9 10 11 # /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/
然後我們新增預設路由並讓他開機自動啟動:
1 2 root@CT:~# nano route.sh root@CT:~# nano /etc/init/route.conf
請將 fe80::908c:eeff:fe18:5c56
換成上游的 IP,ztnfapdryf
換成 ZT 的網卡名稱:
1 2 3 4 5 6 7 #!/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
附上完整的指令列表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/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