Tailscale 基础教程:Headscale 的部署方法和使用教程
Tailscale 是一種基于 WireGuard 的虛擬組網工具,它在用戶態實現了 WireGuard 協議,相比于內核態 WireGuard 性能會有所損失,但在功能和易用性上下了很大功夫:
- 開箱即用
- 無需配置防火墻
- 沒有額外的配置
- 高安全性/私密性
- 自動密鑰輪換
- 點對點連接
- 支持用戶審查端到端的訪問記錄
- 在原有的 ICE、STUN 等 UDP 協議外,實現了 DERP TCP 協議來實現 NAT 穿透
- 基于公網的控制服務器下發 ACL 和配置,實現節點動態更新
- 通過第三方(如 Google) SSO 服務生成用戶和私鑰,實現身份認證
簡而言之,我們可以將 Tailscale 看成是更為易用、功能更完善的 WireGuard。
光有這些還不夠,作為一個白嫖黨,咱更關心的是免費與開源。
Tailscale 是一款商業產品,但個人用戶是可以白嫖的,個人用戶在接入設備不超過 20 臺的情況下是可以免費使用的(雖然有一些限制,比如子網網段無法自定義,且無法設置多個子網)。除 Windows 和 macOS 的圖形應用程序外,其他 Tailscale 客戶端的組件(包含 Android 客戶端)是在 BSD 許可下以開源項目的形式開發的,你可以在他們的 GitHub 倉庫找到各個操作系統的客戶端源碼。
對于大部份用戶來說,白嫖 Tailscale 已經足夠了,如果你有更高的需求,比如自定義網段,可以選擇付費。
原文鏈接:https://icloudnative.io/posts/how-to-set-up-or-migrate-headscale/
我就不想付費行不行?行,不過得往下看。
Headscale 是什么
Tailscale 的控制服務器是不開源的,而且對免費用戶有諸多限制,這是人家的搖錢樹,可以理解。好在目前有一款開源的實現叫 Headscale,這也是唯一的一款,希望能發展壯大。
Headscale 由歐洲航天局的 Juan Font 使用 Go 語言開發,在 BSD 許可下發布,實現了 Tailscale 控制服務器的所有主要功能,可以部署在企業內部,沒有任何設備數量的限制,且所有的網絡流量都由自己控制。
Headscale 部署
使用 Sealos 一鍵部署
如果你嫌下面太長不看,可以選擇直接使用 Sealos 應用模板一鍵部署,有手就行,啥都不需要設置。
直接復制下面的鏈接粘貼到瀏覽器打開 Sealos 的應用模板部署界面:
- https://template.cloud.sealos.io/deploy?templateName=headscale
如果您是第一次打開 Sealos,需要先注冊登錄賬號。
然后點擊「部署應用」按鈕開始部署。部署完成后,你會看到兩個應用,一個是 Headscale,另一個則是 Headscale 可視化界面。
點擊 Headscale 應用的「詳情」進入詳情頁面。內網端口 8080 對應的外網地址就是 Headscale 的公網域名。
Headscale 公網域名后面跟上路徑 /admin/ 即可打開可視化界面。
在 Linux 上部署
在 Linux 上的部署步驟就稍微復雜點了
理論上來說只要你的 Headscale 服務可以暴露到公網出口就行,但最好不要有 NAT,所以推薦將 Headscale 部署在有公網 IP 的云主機上。
首先需要到其 GitHub 倉庫的 Release 頁面下載最新版的二進制文件。
$ wget --output-document=/usr/local/bin/headscale \
https://github.com/juanfont/headscale/releases/download/v<HEADSCALE VERSION>/headscale_<HEADSCALE VERSION>_linux_<ARCH>
$ chmod +x /usr/local/bin/headscale
創建配置目錄:
$ mkdir -p /etc/headscale
創建目錄用來存儲數據與證書:
$ mkdir -p /var/lib/headscale
創建空的 SQLite 數據庫文件:
$ touch /var/lib/headscale/db.sqlite
創建 Headscale 配置文件:
$ wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /etc/headscale/config.yaml
- 修改配置文件,將
server_url改為公網 IP 或域名。如果是國內服務器,域名必須要備案。我的域名無法備案,所以我就直接用公網 IP 了。 - 如果暫時用不到 DNS 功能,可以先將
magic_dns設為 false。 -
server_url設置為http://<PUBLIC_ENDPOINT>:8080,將<PUBLIC_ENDPOINT>替換為公網 IP 或者域名。 - 建議打開隨機端口,將 randomize_client_port 設為 true。
- 可自定義私有網段,也可同時開啟 IPv4 和 IPv6:
ip_prefixes: # - fd7a:115c:a1e0::/48 - 100.64.0.0/16
創建 SystemD service 配置文件:
# /etc/systemd/system/headscale.service
[Unit]
Description=headscale controller
After=syslog.target
After=network.target
[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5
# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/headscale /var/run/headscale
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=headscale
[Install]
WantedBy=multi-user.target
創建 headscale 用戶:
$ useradd headscale -d /home/headscale -m
修改 /var/lib/headscale 目錄的 owner:
$ chown -R headscale:headscale /var/lib/headscale
修改配置文件中的 unix_socket:
unix_socket: /var/run/headscale/headscale.sock
Reload SystemD 以加載新的配置文件:
$ systemctl daemon-reload
啟動 Headscale 服務并設置開機自啟:
$ systemctl enable --now headscale
查看運行狀態:
$ systemctl status headscale
查看占用端口:
$ ss -tulnp|grep headscale
tcp LISTEN 0 1024 [::]:9090 [::]:* users:(("headscale",pi
d=10899,fd=13))
tcp LISTEN 0 1024 [::]:50443 [::]:* users:(("headscale",pi
d=10899,fd=10))
tcp LISTEN 0 1024 [::]:8080 [::]:* users:(("headscale",pi
d=10899,fd=12))
創建用戶
命令行
Tailscale 中有一個概念叫 tailnet,你可以理解成租戶,租戶與租戶之間是相互隔離的,具體看參考 Tailscale 的官方文檔:What is a tailnet。Headscale 也有類似的實現叫 user,即用戶。我們需要先創建一個 user,以便后續客戶端接入,例如:
$ headscale user create default
查看命名空間:
$ headscale user list
ID | Name | Created
1 | default | 2022-03-09 06:12:06
如果你是通過 Sealos 一鍵部署的 Headscale,可以在 Headscale 應用的詳情頁面點擊右側的「終端」按鈕進入 Headscale 容器的終端:
然后在終端中執行上述命令創建 user。
可視化界面
Headscale-Admin 需要通過 API Key 來接入 Headscale,所以在使用之前我們需要先創建一個 API key。在 Headscale 應用的詳情頁面點擊右側的「終端」按鈕進入 Headscale 容器的終端:
然后執行以下命令創建 API Key:
$ headscale apikey create
將 Headscale 公網域名和 API Key 填入 Headscale-Admin 的設置頁面,同時取消勾選 Legacy API,然后點擊「Save」:
接入成功后,點擊左邊側欄的「Users」,然后點擊「Create」開始創建用戶:
Tailscale 客戶端接入
目前除了 iOS 客戶端,其他平臺的客戶端都有辦法自定義 Tailscale 的控制服務器。
| OS | 是否支持 Headscale |
|---|---|
| Linux | Yes |
| OpenBSD | Yes |
| FreeBSD | Yes |
| macOS | Yes |
| Windows | Yes 參考 Windows 客戶端文檔 |
| Android | Yes |
| iOS | Yes |
我們先來看下 Linux 平臺的接入。
Linux
Tailscale 官方提供了各種 Linux 發行版的軟件包,但國內的網絡你懂得,軟件源根本用不了。好在官方還提供了靜態編譯的二進制文件,我們可以直接下載。例如:
$ wget https://pkgs.tailscale.com/stable/tailscale_1.22.2_amd64.tgz
解壓:
$ tar zxvf tailscale_1.22.2_amd64.tgz
x tailscale_1.22.2_amd64/
x tailscale_1.22.2_amd64/tailscale
x tailscale_1.22.2_amd64/tailscaled
x tailscale_1.22.2_amd64/systemd/
x tailscale_1.22.2_amd64/systemd/tailscaled.defaults
x tailscale_1.22.2_amd64/systemd/tailscaled.service
將二進制文件復制到官方軟件包默認的路徑下:
$ cp tailscale_1.22.2_amd64/tailscaled /usr/sbin/tailscaled
$ cp tailscale_1.22.2_amd64/tailscale /usr/bin/tailscale
將 systemD service 配置文件復制到系統路徑下:
$ cp tailscale_1.22.2_amd64/systemd/tailscaled.service /lib/systemd/system/tailscaled.service
將環境變量配置文件復制到系統路徑下:
$ cp tailscale_1.22.2_amd64/systemd/tailscaled.defaults /etc/default/tailscaled
啟動 tailscaled.service 并設置開機自啟:
$ systemctl enable --now tailscaled
查看服務狀態:
$ systemctl status tailscaled
Tailscale 接入 Headscale:
# 如果你是在自己的服務器上部署的,請將 <HEADSCALE_PUB_ENDPOINT> 換成你的 Headscale 公網 IP 或域名
$ tailscale up --login-server=http://<HEADSCALE_PUB_ENDPOINT>:8080 --accept-routes=true --accept-dns=false
# 如果你是使用 Sealos 一鍵部署的,請將 <HEADSCALE_PUB_ENDPOINT> 換成上文提到的 Sealos 中的 Headscale 公網域名
$ tailscale up --login-server=https://<HEADSCALE_PUB_ENDPOINT> --accept-routes=true --accept-dns=false
你也可以在 Headsca-Admin 的 Deploy 界面獲取接入命令:
這里推薦將 DNS 功能關閉,因為它會覆蓋系統的默認 DNS。如果你對 DNS 有需求,可自己研究官方文檔,這里不再贅述。
執行完上面的命令后,會出現下面的信息:
To authenticate, visit:
https://qgemohpy.cloud.sealos.io/register/mkey:e13651ddbfc269513723f1afd6f42465e56922b67ecea8f37d61a35b1b357e0c
在瀏覽器中打開該鏈接,就會出現如下的界面:
將其中的命令復制粘貼到 headscale 所在機器的終端中,并將 USERNAME 替換為前面所創建的 user。
$ headscale nodes register --user default --key 905cf165204800247fbd33989dbc22be95c987286c45aac3033937041150d846
Machine register
注冊成功,查看注冊的節點:
$ headscale nodes list
ID | Name | NodeKey | Namespace | IP addresses | Ephemeral | Last seen | Onlin
e | Expired
1 | coredns | [Ew3RB] | default | 100.64.0.1 | false | 2022-03-20 09:08:58 | onlin
e | no
回到 Tailscale 客戶端所在的 Linux 主機,可以看到 Tailscale 會自動創建相關的路由表和 iptables 規則。路由表可通過以下命令查看:
$ ip route show table 52
查看 iptables 規則:
$ iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N ts-forward
-N ts-input
-A INPUT -j ts-input
-A FORWARD -j ts-forward
-A ts-forward -i tailscale0 -j MARK --set-xmark 0x40000/0xffffffff
-A ts-forward -m mark --mark 0x40000 -j ACCEPT
-A ts-forward -s 100.64.0.0/10 -o tailscale0 -j DROP
-A ts-forward -o tailscale0 -j ACCEPT
-A ts-input -s 100.64.0.5/32 -i lo -j ACCEPT
-A ts-input -s 100.115.92.0/23 ! -i tailscale0 -j RETURN
-A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP
$ iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A ts-postrouting -m mark --mark 0x40000 -j MASQUERADE
macOS
macOS 有 3 種安裝方法:
- 直接通過應用商店安裝,地址:https://apps.apple.com/ca/app/tailscale/id1475387142。前提是你需要一個美區 ID。。。
- 下載安裝包直接安裝,繞過應用商店。
- 安裝開源的命令行工具
tailscale和tailscaled。相關鏈接:https://github.com/tailscale/tailscale/wiki/Tailscaled-on-macOS。
這三種安裝包的核心數據包處理代碼是相同的,唯一的區別在于在于打包方式以及與系統的交互方式。
應用商店里的應用運行在一個應用沙箱中,與系統的其他部分隔離。在沙箱內,應用可以是一個網絡擴展,以實現 VPN 或者類 VPN 的功能。網絡擴展實現的功能對應用商店之外的應用是無法生效的。
從 macOS 從 10.15 開始新增了系統擴展,說白了就是運行在用戶態的內核擴展,它相比于傳統的網絡擴展增強了很多功能,比如內容過濾、透明代理、DNS 代理等。Tailscale 獨立于應用商店的安裝包使用的就是系統擴展,通過 DMG 或者 zip 壓縮包進行分發。
{{< alert >}}
不要同時安裝應用商店版本和獨立分發版本,同時只能裝一個。
而命令行工具既沒有使用網絡擴展也沒有使用系統擴展,而是使用的 utun 接口,相比于 GUI 版本缺少了部分功能,比如 MagicDNS 和 Taildrop。
總覽:
| 應用商店(網絡擴展) | 獨立應用(系統擴展) | 命令行版本 | |
|---|---|---|---|
| 是否可用 | yes | yes, beta | yes |
| 圖形界面 | yes | yes | no; CLI |
| macOS 最低版本 | macOS 10.13 | macOS 10.15 | macOS 10.13 |
| 后臺運行 | no; sandboxed | 理論上支持; 尚未實現 | yes |
| 使用的鑰匙串?? | 用戶級 | 系統級 | 直接存放在文件中 |
| 沙盒隔離 | yes | no | no |
| 自動更新 | yes; 應用商店直接更新 | yes; Sparkle | no |
| 是否開源 | no | no | yes |
| MagicDNS | yes | yes | yes |
| Taildrop | yes | yes | 未實現 |
安裝完 GUI 版應用后還需要做一些騷操作,才能讓 Tailscale 使用 Headscale 作為控制服務器。當然,Headscale 已經給我們提供了詳細的操作步驟,你只需要在瀏覽器中打開 URL:https://<HEADSCALE_PUB_ENDPOINT>/apple,便會出現如下的界面:
對于 1.34.0 及以上的 Tailscale 版本,可以按照下面的方法來操作:
-
長按「ALT」鍵,然后點擊頂部菜單欄的 Tailscale 圖標,然后將鼠標指針懸停在「Debug」菜單上。
-
在「Custom Login Server」下方選擇「Add Account...」。
-
在打開的彈窗中填入 Headscale 的公網域名,然后點擊「Add Account」。
-
然后立馬就會跳轉到瀏覽器并打開一個頁面。
-
接下來與之前 Linux 客戶端相同,回到 Headscale 所在的機器執行瀏覽器中的命令即可,注冊成功:
回到 Headscale 所在主機,查看注冊的節點:
$ headscale nodes list
ID | Name | NodeKey | Namespace | IP addresses | Ephemeral | Last seen | Onlin
e | Expired
1 | coredns | [Ew3RB] | default | 100.64.0.1 | false | 2022-03-20 09:08:58 | onlin
e | no
2 | carsondemacbook-pro | [k7bzX] | default | 100.64.0.2 | false | 2022-03-20 09:48:30 | online | no
回到 macOS,測試是否能 ping 通對端節點:
$ ping -c 2 100.64.0.1
PING 100.64.0.1 (100.64.0.1): 56 data bytes
64 bytes from 100.64.0.1: icmp_seq=0 ttl=64 time=37.025 ms
64 bytes from 100.64.0.1: icmp_seq=1 ttl=64 time=38.181 ms
--- 100.64.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 37.025/37.603/38.181/0.578 ms
也可以使用 Tailscale CLI 來測試:
$ /Applications/Tailscale.app/Contents/MacOS/Tailscale ping 100.64.0.1
pong from coredns (100.64.0.1) via xxxx:41641 in 36ms
對于版本號低于 1.32.0 的 Tailscale 客戶端,你只需要按照圖中所述的步驟操作即可,本文就不再贅述了。
Android
Android 客戶端從 1.30.0 版本開始支持自定義控制服務器(即 coordination server),你可以通過 Google Play 或者 F-Droid 下載最新版本的客戶端。
安裝完成后打開 Tailscale App,會出現如下的界面:
點開右上角的“三個點”,你會看到只有一個 About 選項:
接下來就需要一些騷操作了,你需要反復不停地點開再關閉右上角的“三個點”,重復三四次之后,便會出現一個 Change server 選項:
點擊 Change server,將 headscale 控制服務器的地址填進去:
然后點擊 Save and restart 重啟,點擊 Sign in with other,就會跳出這個頁面:
將其中的命令粘貼到 Headscale 所在主機的終端,將 USER 替換為之前創建的 user,然后執行命令即可。注冊成功后可將該頁面關閉,回到 App 主頁,效果如圖:
Windows
Windows Tailscale 客戶端想要使用 Headscale 作為控制服務器,只需在瀏覽器中打開 URL:https://<HEADSCALE_PUB_ENDPOINT>/windows,便會出現如下的界面:
按照其中的步驟操作即可。
其他 Linux 發行版
除了常規的 Linux 發行版之外,還有一些特殊場景的 Linux 發行版,比如 OpenWrt、威聯通(QNAP)、群暉等,這些發行版的安裝方法已經有人寫好了,這里就不詳細描述了,我只給出相關的 GitHub 倉庫,大家如果自己有需求,直接去看相關倉庫的文檔即可。
- OpenWrt:https://github.com/adyanth/openwrt-tailscale-enabler
- 群暉:https://github.com/tailscale/tailscale-synology
- 威聯通:https://github.com/tailscale/tailscale-qpkg
iOS
iOS 系統直接從應用商店安裝即可,當然前提是你需要有一個美區 ID。
-
安裝完成后打開 Tailscale 確認你沒有登錄任何賬號。然后打開「設置」,向下滑動,在「Game Center」或者「電視提供商」下方找到「Tailscale」,然后點擊進去。
如果你的設備之前登錄過 Tailscale 服務端,需要將「Reset Keychain」選項打開。
-
在「Alternate Coordination Server URL」下方輸入你的 Headscale 公網域名。
-
從 iOS 應用程序切換器中關閉 Tailscale 再重新打開,然后選擇「Log in」,就會彈出一個 Headscale 身份認證頁面。
-
將 Headscale 身份認證頁面中的命令復制粘貼到 headscale 所在容器的終端中,并將 USERNAME 替換為前面所創建的 user。
$ headscale nodes register --user default --key mkey:1fbd9696ebb03b9394033949514345bc5dba0e570bc0d778f15f92a02d2dcb66 2023-12-29T09:55:38Z TRC DNS configuration loaded dns_config={"Nameservers":["1.1.1.1"],"Proxied":true,"Resolvers":[{"Addr":"1.1.1.1"}]} Node localhost registered -
注冊成功。
通過 Pre-Authkeys 接入
前面的接入方法都需要服務端同意,步驟比較煩瑣,其實還有更簡單的方法,可以直接接入,不需要服務端同意。
首先在服務端生成 pre-authkey 的 token,有效期可以設置為 24 小時:
$ headscale preauthkeys create -e 24h --user default
查看已經生成的 key:
$ headscale --user default preauthkeys list
ID | Key | Reusable | Ephemeral | Used | Expiration | Created
1 | 57e419c40e30b0dxxxxxxxf15562c18a8c6xxxx28ae76f57 | false | false | false | 2022-05-30 07:14:17 | 2022-05-29 07:14:17
當然你也可以在 Headscale-Admin 中生成。點擊客戶端想加入的 User:
在彈出的界面中點擊「PreAuth Keys」右側的 Create,設置一個過期時間(比如 100 年~),如果想重復利用這個 Key,可以勾選 Reusable,最后點擊 ?:
創建成功后,點擊紅框區域便可復制該 PreAuth Key:
現在新節點就可以無需服務端同意直接接入了:
$ tailscale up --login-server=http://<HEADSCALE_PUB_ENDPOINT>:8080 --accept-routes=true --accept-dns=false --authkey $KEY
打通局域網
到目前為止我們只是打造了一個點對點的 Mesh 網絡,各個節點之間都可以通過 WireGuard 的私有網絡 IP 進行直連。但我們可以更大膽一點,還記得我在文章開頭提到的訪問家庭內網的資源嗎?我們可以通過適當的配置讓每個節點都能訪問其他節點的局域網 IP。這個使用場景就比較多了,你可以直接訪問家庭內網的 NAS,或者內網的任何一個服務,更高級的玩家可以使用這個方法來訪問云上 Kubernetes 集群的 Pod IP 和 Service IP。
假設你的家庭內網有一臺 Linux 主機(比如 OpenWrt)安裝了 Tailscale 客戶端,我們希望其他 Tailscale 客戶端可以直接通過家中的局域網 IP(例如 192.168.100.0/24) 訪問家庭內網的任何一臺設備。
配置方法很簡單,首先需要設置 IPv4 與 IPv6 路由轉發:
$ echo 'net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/ipforwarding.conf
$ echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.d/ipforwarding.conf
$ sysctl -p /etc/sysctl.d/ipforwarding.conf
客戶端修改注冊節點的命令,在原來命令的基礎上加上參數 --advertise-routes=192.168.100.0/24,告訴 Headscale 服務器“我這個節點可以轉發這些地址的路由”。
$ tailscale up --login-server=http://<HEADSCALE_PUB_ENDPOINT>:8080 --accept-routes=true --accept-dns=false --advertise-routes=192.168.100.0/24 --reset
在 Headscale 端查看路由,可以看到相關路由是關閉的。
$ headscale nodes list|grep openwrt
6 | openwrt | [7LdVc] | default | 100.64.0.6 | false | 2022-03-20 15:50:46 | onlin
e | no
$ headscale routes list -i 6
Route | Enabled
192.168.100.0/24 | false
開啟路由:
$ headscale routes enable -i 6 -r "192.168.100.0/24"
Route | Enabled
192.168.100.0/24 | true
如果有多條路由需要用 , 隔開:
$ headscale routes enable -i 6 -r "192.168.100.0/24,xxxx"
也可以通過參數 -a 開啟所有路由:
$ headscale routes enable -i 6 -a
其他節點查看路由結果:
$ ip route show table 52|grep "192.168.100.0/24"
192.168.100.0/24 dev tailscale0
其他節點啟動時需要增加 --accept-routes=true 選項來聲明 “我接受外部其他節點發布的路由”。
現在你在任何一個 Tailscale 客戶端所在的節點都可以 ping 通家庭內網的機器了,你在公司或者星巴克也可以像在家里一樣用同樣的 IP 隨意訪問家中的任何一個設備,就問你香不香?
總結
目前從穩定性來看,Tailscale 比其他機遇 WireGuard 的組網工具略勝一籌,基本上不會時不時出現 ping 不通的情況,這取決于 Tailscale 在用戶態對 NAT 穿透所做的種種優化,他們還專門寫了一篇文章介紹 NAT 穿透的原理,中文版翻譯自國內的 eBPF 大佬趙亞楠,墻裂推薦大家閱讀。放一張圖給大家感受一下:
總結
以上是生活随笔為你收集整理的Tailscale 基础教程:Headscale 的部署方法和使用教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 新技术:虚拟线程使用指南(二)
- 下一篇: 请注意,你的 Pulsar 集群可能有删