一款超牛逼的 P2P 內(nèi)網(wǎng)穿透神器(附安裝、使用教程)

鏈接:https://mritd.com/2022/10/19/use-headscale-to-build-a-p2p-network/
一、內(nèi)網(wǎng)穿透簡(jiǎn)述
由于國(guó)內(nèi)網(wǎng)絡(luò)環(huán)境問(wèn)題, 普遍家庭用戶寬帶都沒(méi)有分配到公網(wǎng) IP(我有固定公網(wǎng) IP, 嘿嘿); 這時(shí)候一般我們需要從外部訪問(wèn)家庭網(wǎng)絡(luò)時(shí)就需要通過(guò)一些魔法手段, 比如 VPN、遠(yuǎn)程軟件(向日葵…)等; 但是這些工具都有一個(gè)普遍存在的問(wèn)題: 慢+卡!
1.1、傳統(tǒng)星型拓?fù)?/h6>
究其根本因素在于, 在傳統(tǒng)架構(gòu)中如果兩個(gè)位于多層 NAT(簡(jiǎn)單理解為多個(gè)路由器)之后的設(shè)備, 只能通過(guò)一些中央(VPN/遠(yuǎn)程軟件)中轉(zhuǎn)服務(wù)器進(jìn)行鏈接, 這時(shí)網(wǎng)絡(luò)連接速度取決于中央服務(wù)器帶寬和速度; 這種網(wǎng)絡(luò)架構(gòu)我這里簡(jiǎn)稱(chēng)為: 星型拓?fù)?/p>

從這張圖上可以看出, 你的 “工作筆記本” 和 “家庭 NAS” 之間通訊的最大傳輸速度為 Up/Down: 512K/s; 因?yàn)榱髁拷?jīng)過(guò)了中央服務(wù)器中轉(zhuǎn), 由于網(wǎng)絡(luò)木桶效應(yīng)存在, 即使你兩側(cè)的網(wǎng)絡(luò)速度再高也沒(méi)用, 整體的速度取決于這個(gè)鏈路中最低的一個(gè)設(shè)備網(wǎng)速而不是你兩端的設(shè)備.
在這種拓?fù)湎? 想提高速度只有一個(gè)辦法: 加錢(qián)! 在不使用 “鈔能力” 的情況下, 普遍免費(fèi)的軟件提供商不可能給予過(guò)多的資源來(lái)讓用戶白嫖, 而自己弄大帶寬的中央服務(wù)器成本又過(guò)高.
1.2、NAT 穿透與網(wǎng)狀拓?fù)?/span>
本部分只做簡(jiǎn)述, 具體里面有大量細(xì)節(jié)和規(guī)則可能描述不準(zhǔn)確, 細(xì)節(jié)部分推薦閱讀 How NAT traversal works.
既然傳統(tǒng)的星型拓?fù)溆羞@么多問(wèn)題, 那么有沒(méi)有其他騷操作可以解決呢? 答案是有的, 簡(jiǎn)單來(lái)說(shuō)就是利用 NAT 穿透原理. NAT 穿透簡(jiǎn)單理解如下: 在 A 設(shè)備主動(dòng)向 B 設(shè)備發(fā)送流量后, 整個(gè)鏈路上的防火墻會(huì)短時(shí)間打開(kāi)一個(gè)映射規(guī)則, 該規(guī)則允許 B 設(shè)備短暫的從這個(gè)路徑上反向向 A 設(shè)備發(fā)送流量. 更通俗的講大概就是所謂的: “順著網(wǎng)線來(lái)打你”

搞清了這個(gè)規(guī)則以后, 我們就可以弄一臺(tái) “低配” 的中央服務(wù)器, 讓中央服務(wù)器來(lái)幫助我們協(xié)商兩邊的設(shè)備誰(shuí)先訪問(wèn)誰(shuí)(或者說(shuō)是訪問(wèn)規(guī)則); 兩個(gè)設(shè)備一起無(wú)腦訪問(wèn)對(duì)方, 然后觸發(fā)防火墻的 NAT 穿透規(guī)則(防火墻打開(kāi)), 此后兩個(gè)設(shè)備就可以不通過(guò)中央服務(wù)器源源不斷的通訊了. 在這種架構(gòu)下我們的設(shè)備其實(shí)就組成了一個(gè)非標(biāo)準(zhǔn)的網(wǎng)狀拓?fù)?

在這種拓?fù)湎? 兩個(gè)設(shè)備之間的通訊速度已經(jīng)不在取決于中央服務(wù)器, 而是直接取決于兩端設(shè)備的帶寬, 也就是說(shuō)達(dá)到了設(shè)備網(wǎng)絡(luò)帶寬峰值. 當(dāng)然 NAT 穿透也不是百分百能夠成功的, 在復(fù)雜網(wǎng)絡(luò)情況下有些防火墻不會(huì)按照預(yù)期工作或者說(shuō)有更嚴(yán)格的限制; 比如 IP、端口、協(xié)議限制等等, 所以為了保證可靠性可以讓中央服務(wù)器中轉(zhuǎn)做后備方案, 即盡量嘗試 NAT 穿透, 如果不行走中央服務(wù)器中繼.
Tailscale 簡(jiǎn)介
第一部分是為了方便讀者理解一些新型內(nèi)網(wǎng)穿透的大致基本原理, 現(xiàn)在回到本文重點(diǎn): Tailscale
Tailscale 就是一種利用 NAT 穿透(aka: P2P 穿透)技術(shù)的 VPN 工具. Tailscale 客戶端等是開(kāi)源的, 不過(guò)遺憾的是中央控制服務(wù)器目前并不開(kāi)源; Tailscale 目前也提供免費(fèi)的額度給用戶使用, 在 NAT 穿透成功的情況下也能保證滿速運(yùn)行.
不過(guò)一旦無(wú)法 NAT 穿透需要做中轉(zhuǎn)時(shí), Tailscale 官方的服務(wù)器由于眾所周知的原因在國(guó)內(nèi)訪問(wèn)速度很拉胯; 不過(guò)萬(wàn)幸的是開(kāi)源社區(qū)大佬們搓了一個(gè)開(kāi)源版本的中央控制服務(wù)器(Headscale), 也就是說(shuō): 我們可以自己搭建中央服務(wù)器啦, 完全 “自主可控” 啦.
搭建 Headscale 服務(wù)端
以下命令假設(shè)安裝系統(tǒng)為 Ubuntu 22.04, 其他系統(tǒng)請(qǐng)自行調(diào)整.
3.1、宿主機(jī)安裝
Headscale 是采用 Go 語(yǔ)言編寫(xiě)的, 所以只有一個(gè)二進(jìn)制文件, 在 Github Releases 頁(yè)面下載最新版本即可:
# 下載
wget https://github.com/juanfont/headscale/releases/download/v0.16.4/headscale_0.16.4_linux_amd64 -O /usr/local/bin/headscale
# 增加可執(zhí)行權(quán)限
chmod +x /usr/local/bin/headscale
下載完成后為了安全性我們需要?jiǎng)?chuàng)建單獨(dú)的用戶和目錄用于 Headscale 運(yùn)行
# 配置目錄
mkdir -p /etc/headscale
# 創(chuàng)建用戶
useradd \
--create-home \
--home-dir /var/lib/headscale/ \
--system \
--user-group \
--shell /usr/sbin/nologin \
headscale
為了保證 Headscale 能持久運(yùn)行, 我們需要?jiǎng)?chuàng)建 SystemD 配置文件
# /lib/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
3.1、配置 Headscale
安裝完成以后我們需要在 /etc/headscale/config.yaml 中配置 Headscale 的啟動(dòng)配置, 以下為配置樣例以及解釋(僅列出重要配置):
---
# Headscale 服務(wù)器的訪問(wèn)地址
#
# 這個(gè)地址是告訴客戶端需要訪問(wèn)的地址, 即使你需要在跑在
# 負(fù)載均衡器之后這個(gè)地址也必須寫(xiě)成負(fù)載均衡器的訪問(wèn)地址
server_url: https://your.domain.com
# Headscale 實(shí)際監(jiān)聽(tīng)的地址
listen_addr: 0.0.0.0:8080
# 監(jiān)控地址
metrics_listen_addr: 127.0.0.1:9090
# grpc 監(jiān)聽(tīng)地址
grpc_listen_addr: 0.0.0.0:50443
# 是否允許不安全的 grpc 連接(非 TLS)
grpc_allow_insecure: false
# 客戶端分配的內(nèi)網(wǎng)網(wǎng)段
ip_prefixes:
- fd7a:115c:a1e0::/48
- 100.64.0.0/10
# 中繼服務(wù)器相關(guān)配置
derp:
server:
# 關(guān)閉內(nèi)嵌的 derper 中繼服務(wù)(可能不安全, 還沒(méi)去看代碼)
enabled: false
# 下發(fā)給客戶端的中繼服務(wù)器列表(默認(rèn)走官方的中繼節(jié)點(diǎn))
urls:
- https://controlplane.tailscale.com/derpmap/default
# 可以在本地通過(guò) yaml 配置定義自己的中繼接待你
paths: []
# SQLite config
db_type: sqlite3
db_path: /var/lib/headscale/db.sqlite
# 使用自動(dòng)簽發(fā)證書(shū)是的域名
tls_letsencrypt_hostname: ""
# 使用自定義證書(shū)時(shí)的證書(shū)路徑
tls_cert_path: ""
tls_key_path: ""
# 是否讓客戶端使用隨機(jī)端口, 默認(rèn)使用 41641/UDP
randomize_client_port: false
3.3、證書(shū)及反向代理
可能很多人和我一樣, 希望使用 ACME 自動(dòng)證書(shū), 又不想占用 80/443 端口, 又想通過(guò)負(fù)載均衡器負(fù)載, 配置又看的一頭霧水; 所以這里詳細(xì)說(shuō)明一下 Headscale 證書(shū)相關(guān)配置和工作邏輯:
1、Headscale 的 ACME 只支持 HTTP/TLS 挑戰(zhàn), 所以使用后必定占用 80/443 2、當(dāng)配置了 tls_letsencrypt_hostname 時(shí)一定會(huì)進(jìn)行 ACME 申請(qǐng) 3、在不配置 tls_letsencrypt_hostname 時(shí)如果配置了 tls_cert_path 則使用自定義證書(shū) 4、兩者都不配置則不使用任何證書(shū), 服務(wù)端監(jiān)聽(tīng) HTTP 請(qǐng)求 5、三種情況下(ACME 證書(shū)、自定義證書(shū)、無(wú)證書(shū))主服務(wù)都只監(jiān)聽(tīng) listen_addr 地址, 與 server_url 沒(méi)半毛錢(qián)關(guān)系 6、只有在有證書(shū)(ACME 證書(shū)或自定義證書(shū))的情況下或者手動(dòng)開(kāi)啟了 grpc_allow_insecure 才會(huì)監(jiān)聽(tīng) grpc 遠(yuǎn)程調(diào)用服務(wù)
綜上所述, 如果你想通過(guò) Nginx、Caddy 反向代理 Headscale, 則你需要滿足以下配置:
1、刪除掉 tls_letsencrypt_hostname 或留空, 防止 ACME 啟動(dòng) 2、刪除掉 tls_cert_path 或留空, 防止加載自定義證書(shū) 3、server_url 填寫(xiě) Nginx 或 Caddy 被訪問(wèn)的 HTTPS 地址 4、在你的 Nginx 或 Caddy 中反向代理填寫(xiě) listen_addr 的 HTTP 地址
Nginx 配置參考 官方 Wiki, Caddy 只需要一行 reverse_proxy headscale:8080 即可(地址自行替換).
至于 ACME 證書(shū)你可以通過(guò)使用 acme.sh 自動(dòng)配置 Nginx 或者使用 Caddy 自動(dòng)申請(qǐng)等方式, 這些已經(jīng)與 Headscale 無(wú)關(guān)了, 不在本文探討范圍內(nèi).
3.4、內(nèi)網(wǎng)地址分配
請(qǐng)盡量不要將 ip_prefixes 配置為默認(rèn)的 100.64.0.0/10 網(wǎng)段, 如果你有興趣查詢了該地址段, 那么你應(yīng)該明白它叫 CGNAT; 很不幸的是例如 Aliyun 底層的 apt 源等都在這個(gè)范圍內(nèi), 可能會(huì)有一些奇怪問(wèn)題.
3.5、啟動(dòng) Headscale
在處理完證書(shū)等配置后, 只需要愉快的啟動(dòng)一下即可:
# 開(kāi)機(jī)自啟動(dòng) 并 立即啟動(dòng)
systemctl enable headscale --now
再啰嗦一嘴, 如果你期望使用 Headscale ACME 自動(dòng)申請(qǐng)證書(shū), 你的關(guān)鍵配置應(yīng)該像這樣:
server_url: https://your.domain.com
listen_addr: 0.0.0.0:443
tls_letsencrypt_hostname: "your.domain.com"
tls_cert_path: ""
tls_key_path: ""
如果你期望使用自定義證書(shū), 則你的關(guān)鍵配置應(yīng)該像這樣:
server_url: https://your.domain.com
listen_addr: 0.0.0.0:443
tls_letsencrypt_hostname: ""
tls_cert_path: "/path/to/cert"
tls_key_path: "/path/to/key"
如果你期望使用負(fù)載均衡器, 那么你的關(guān)鍵配置應(yīng)該像這樣:
server_url: https://your.domain.com
listen_addr: 0.0.0.0:8080
tls_letsencrypt_hostname: ""
tls_cert_path: ""
tls_key_path: ""
在使用負(fù)載均衡器配置時(shí), 啟動(dòng)后會(huì)有一行警告日志, 忽略即可:
2022-09-18T07:57:36Z WRN Listening without TLS but ServerURL does not start with http://
3.6、Docker Compose 安裝
Compose 配置樣例文件如下:
# docker-compose.yaml
version: "3.9"
services:
headscale:
container_name: headscale
image: headscale/headscale:0.16.4
ports:
- "8080:8080"
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
restart: always
volumes:
- ./conf:/etc/headscale
- data:/var/lib/headscale
command: ["headscale", "serve"]
volumes:
config:
data:
你需要在與 docker-compose.yaml 同級(jí)目錄下創(chuàng)建 conf 目錄用于存儲(chǔ)配置文件; 具體配置請(qǐng)參考上面的配置詳解等部分, 最后不要忘記你的 Compose 文件端口映射需要和配置文件保持一致.
客戶端安裝
對(duì)于客戶端來(lái)說(shuō), Tailscale 提供了多個(gè)平臺(tái)和發(fā)行版的預(yù)編譯安裝包, 并且部分客戶端直接支持設(shè)置自定義的中央控制服務(wù)器.
4.1、Linux 客戶端
Linux 用戶目前只需要使用以下命令安裝即可:
curl -fsSL https://tailscale.com/install.sh | sh
默認(rèn)該腳本會(huì)檢測(cè)相關(guān)的 Linux 系統(tǒng)發(fā)行版并使用對(duì)應(yīng)的包管理器安裝 Tailscale, 安裝完成后使用以下命令啟動(dòng):
tailscale up --login-server https://your.domain.com --advertise-routes=192.168.11.0/24 --accept-routes=true --accept-dns=false
關(guān)于選項(xiàng)設(shè)置:
--login-server: #指定使用的中央服務(wù)器地址(必填)
--advertise-routes: #向中央服務(wù)器報(bào)告當(dāng)前客戶端處于哪個(gè)內(nèi)網(wǎng)網(wǎng)段下, 便于中央服務(wù)器讓同內(nèi)網(wǎng)設(shè)備直接內(nèi)網(wǎng)直連(可選的)或者將其他設(shè)備指定流量路由到當(dāng)前內(nèi)網(wǎng)(可選)
--accept-routes: #是否接受中央服務(wù)器下發(fā)的用于路由到其他客戶端內(nèi)網(wǎng)的路由規(guī)則(可選)
--accept-dns: #是否使用中央服務(wù)器下發(fā)的 DNS 相關(guān)配置(可選, 推薦關(guān)閉)
啟動(dòng)完成后, tailscale 將會(huì)卡住, 并打印一個(gè)你的服務(wù)器訪問(wèn)地址; 瀏覽器訪問(wèn)該地址后將會(huì)得到一條命令:


注意: 瀏覽器上顯示的命令需要在中央控制服務(wù)器執(zhí)行(Headscale), NAMESAPCE 位置應(yīng)該替換為一個(gè)具體的 Namespace, 可以使用以下命令創(chuàng)建 Namespace (名字隨意)并讓設(shè)備加入:
在 Headscale 服務(wù)器上執(zhí)行命令成功后客戶端命令行在稍等片刻便會(huì)執(zhí)行完成, 此時(shí)該客戶端已經(jīng)被加入 Headscale 網(wǎng)絡(luò)并分配了特定的內(nèi)網(wǎng) IP; 多個(gè)客戶端加入后在 NAT 穿透成功時(shí)就可以互相 ping 通, 如果出現(xiàn)問(wèn)題請(qǐng)閱讀后面的調(diào)試細(xì)節(jié), 只要能注冊(cè)成功就算是成功了一半, 暫時(shí)不要慌.
4.2、MacOS 客戶端
MacOS 客戶端安裝目前有兩種方式, 一種是使用標(biāo)準(zhǔn)的 AppStore 版本(好像還有一個(gè)可以直接下載的), 需要先設(shè)置服務(wù)器地址然后再啟動(dòng) App:
首先訪問(wèn)你的 Headscale 地址 https://your.domain.com/apple:

復(fù)制倒數(shù)第二行命令到命令行執(zhí)行(可能需要 sudo 執(zhí)行), 然后去 AppStore 搜索 Hailscale 安裝并啟動(dòng); 啟動(dòng)后會(huì)自動(dòng)打開(kāi)瀏覽器頁(yè)面, 與 Linux 安裝類(lèi)似, 復(fù)制命令到 Headscale 服務(wù)器執(zhí)行即可(Namespace 創(chuàng)建一次就行).
第二種方式也是比較推薦的方式, 直接編譯客戶端源碼安裝, 體驗(yàn)與 Linux 版本一致:
# 安裝 go
brew install go
# 編譯命令行客戶端
go install tailscale.com/cmd/tailscale{,d}@main
# 安裝為系統(tǒng)服務(wù)
sudo tailscaled install-system-daemon
安裝完成后同樣通過(guò) tailscale up 命令啟動(dòng)并注冊(cè)即可, 具體請(qǐng)參考 Linux 客戶端安裝部分.
4.3、其他客戶端
關(guān)于 Windows 客戶端大致流程就是創(chuàng)建一個(gè)注冊(cè)表, 然后同樣安裝官方 App 啟動(dòng), 接著瀏覽器復(fù)制命令注冊(cè)即可. 至于移動(dòng)端本人沒(méi)有需求, 所以暫未研究. Windows 具體的安裝流程請(qǐng)?jiān)L問(wèn) https://your.domain.com/windows 地址查看(基本與 MacOS AppStore 版本安裝類(lèi)似).
中繼服務(wù)器搭建
在上面的 Headscale 搭建完成并添加客戶端后, 某些客戶端可能無(wú)法聯(lián)通; 這是由于網(wǎng)絡(luò)復(fù)雜情況下導(dǎo)致了 NAT 穿透失敗; 為此我們可以搭建一個(gè)中繼服務(wù)器來(lái)進(jìn)行傳統(tǒng)的星型拓?fù)渫ㄐ?
5.1、搭建 DERP Server
首先需要注意的是, 在需要搭建 DERP Server 的服務(wù)器上, 請(qǐng)先安裝一個(gè) Tailscale 客戶端并注冊(cè)到 Headscale; 這樣做的目的是讓搭建的 DERP Server 開(kāi)啟客戶端認(rèn)證, 否則你的 DERP Server 可以被任何人白嫖.
目前 Tailscale 官方并未提供 DERP Server 的安裝包, 所以需要我們自行編譯安裝; 在編譯之前請(qǐng)確保安裝了最新版本的 Go 語(yǔ)言及其編譯環(huán)境.
# 編譯 DERP Server
go install tailscale.com/cmd/derper@main
# 復(fù)制到系統(tǒng)可執(zhí)行目錄
mv ${GOPATH}/bin/derper /usr/local/bin
# 創(chuàng)建用戶和運(yùn)行目錄
useradd \
--create-home \
--home-dir /var/lib/derper/ \
--system \
--user-group \
--shell /usr/sbin/nologin \
derper
接下來(lái)創(chuàng)建一個(gè) SystemD 配置:
# /lib/systemd/system/derper.service
[Unit]
Description=tailscale derper server
After=syslog.target
After=network.target
[Service]
Type=simple
User=derper
Group=derper
ExecStart=/usr/local/bin/derper -c=/var/lib/derper/private.key -a=:8989 -stun-port=3456 -verify-clients
Restart=always
RestartSec=5
# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/derper /var/run/derper
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=derper
[Install]
WantedBy=multi-user.target
最后使用以下命令啟動(dòng) Derper Server 即可:
systemctl enable derper --now
注意: 默認(rèn)情況下 Derper Server 會(huì)監(jiān)聽(tīng)在 :443 上, 同時(shí)會(huì)觸發(fā)自動(dòng) ACME 申請(qǐng)證書(shū). 關(guān)于證書(shū)邏輯如下:
1、如果不指定 -a 參數(shù), 則默認(rèn)監(jiān)聽(tīng) :443 2、如果監(jiān)聽(tīng) :443 并且未指定 --certmode=manual 則會(huì)強(qiáng)制使用 --hostname 指定的域名進(jìn)行 ACME 申請(qǐng)證書(shū) 3、如果指定了 --certmode=manual 則會(huì)使用 --certmode 指定目錄下的證書(shū)開(kāi)啟 HTTPS 4、如果指定了 -a 為非 :443 端口, 且沒(méi)有指定 --certmode=manual 則只監(jiān)聽(tīng) HTTP
如果期望使用 ACME 自動(dòng)申請(qǐng)只需要不增加 -a 選項(xiàng)即可(占用 443 端口), 如果期望通過(guò)負(fù)載均衡器負(fù)載, 則需要將 -a 選項(xiàng)指定到非 443 端口, 然后配置 Nginx、Caddy 等 LB 軟件即可. 最后一點(diǎn) stun 監(jiān)聽(tīng)的是 UDP 端口, 請(qǐng)確保防火墻打開(kāi)此端口.
5.2、配置 Headscale
在創(chuàng)建完 Derper 中繼服務(wù)器后, 我們還需要配置 Headscale 來(lái)告訴所有客戶端在必要時(shí)可以使用此中繼節(jié)點(diǎn)進(jìn)行通信; 為了達(dá)到這個(gè)目的, 我們需要在 Headscale 服務(wù)器上創(chuàng)建以下配置:
# /etc/headscale/derper.yaml
regions:
901:
regionid: 901
regioncode: private-derper
regionname: "My Private Derper Server"
nodes:
- name: private-derper
regionid: 901
# 自行更改為自己的域名
hostname: derper.xxxxx.com
# Derper 節(jié)點(diǎn)的 IP
ipv4: 123.123.123.123
# Derper 設(shè)置的 STUN 端口
stunport: 3456
在創(chuàng)建好基本的 Derper Server 節(jié)點(diǎn)信息配置后, 我們需要調(diào)整主配置來(lái)讓 Headscale 加載:
derp:
server:
# 這里關(guān)閉 Headscale 默認(rèn)的 Derper Server
enabled: false
# urls 留空, 保證不加載官方的默認(rèn) Derper
urls: []
# 這里填寫(xiě) Derper 節(jié)點(diǎn)信息配置的絕對(duì)路徑
paths:
- /etc/headscale/derper.yaml
# If enabled, a worker will be set up to periodically
# refresh the given sources and update the derpmap
# will be set up.
auto_update_enabled: true
# How often should we check for DERP updates?
update_frequency: 24h
接下來(lái)重啟 Headscale 并重啟 client 上的 tailscale 即可看到中繼節(jié)點(diǎn):
~ ??? tailscale netcheck
Report:
* UDP: true
* IPv4: yes, 124.111.111.111:58630
* IPv6: no, but OS has support
* MappingVariesByDestIP: false
* HairPinning: false
* PortMapping: UPnP, NAT-PMP, PCP
* CaptivePortal: true
* Nearest DERP: XXXX Derper Server
* DERP latency:
- XXXX: 10.1ms (XXXX Derper Server)
到此中繼節(jié)點(diǎn)搭建完成.
5.3、Docker Compose 安裝
目前官方似乎也沒(méi)有提供 Docker 鏡像, 我自己通過(guò) GitHub Action 編譯了一個(gè) Docker 鏡像, 以下是使用此鏡像的 Compose 文件樣例:
version: '3.9'
services:
derper:
image: mritd/derper
container_name: derper
restart: always
ports:
- "8080:8080/tcp"
- "3456:3456/udp"
environment:
TZ: Asia/Shanghai
volumes:
- /etc/timezone:/etc/timezone
- /var/run/tailscale:/var/run/tailscale
- data:/var/lib/derper
volumes:
data:
該鏡像默認(rèn)開(kāi)啟了客戶端驗(yàn)證, 所以請(qǐng)確保 /var/run/tailscale 內(nèi)存在已加入 Headscale 成功的 tailscaled 實(shí)例的 sock 文件. 其他具體環(huán)境變量等參數(shù)配置請(qǐng)參考 Earthfile.
客戶端網(wǎng)絡(luò)調(diào)試
在調(diào)試中繼節(jié)點(diǎn)或者不確定網(wǎng)絡(luò)情況時(shí), 可以使用一些 Tailscale 內(nèi)置的命令來(lái)調(diào)試網(wǎng)絡(luò).
6.1、Ping 命令
tailscale ping 命令可以用于測(cè)試 IP 連通性, 同時(shí)可以看到時(shí)如何連接目標(biāo)節(jié)點(diǎn)的. 默認(rèn)情況下 Ping 命令首先會(huì)使用 Derper 中繼節(jié)點(diǎn)通信, 然后嘗試 P2P 連接; 一旦 P2P 連接成功則自動(dòng)停止 Ping:
~ ??? tailscale ping 10.24.0.5
pong from k8s13 (10.24.0.5) via DERP(XXXXX) in 14ms
pong from k8s13 (10.24.0.5) via DERP(XXXXX) in 13ms
pong from k8s13 (10.24.0.5) via DERP(XXXXX) in 14ms
pong from k8s13 (10.24.0.5) via DERP(XXXXX) in 12ms
pong from k8s13 (10.24.0.5) via DERP(XXXXX) in 12ms
pong from k8s13 (10.24.0.5) via 3.4.170.23:2495 in 9ms
由于其先走 Derper 的特性也可以用來(lái)測(cè)試 Derper 連通性.
6.2、Status 命令
通過(guò) tailscale status 命令可以查看當(dāng)前節(jié)點(diǎn)與其他對(duì)等節(jié)點(diǎn)的連接方式, 通過(guò)此命令可以查看到當(dāng)前節(jié)點(diǎn)可連接的節(jié)點(diǎn)以及是否走了 Derper 中繼:
~ ??? tailscale status
10.24.0.8 xmac kovacs macOS -
alivpn kovacs linux active; direct 4.3.4.5:41644, tx 1264 rx 944
aliyun kovacs linux -
bob kovacs macOS offline
bob-imac kovacs macOS offline
company kovacs linux active; direct 114.114.114.114:41642, tx 1296 rx 880
6.3、NetCheck 命令
有些情況下我們可以確認(rèn)是當(dāng)前主機(jī)的網(wǎng)絡(luò)問(wèn)題導(dǎo)致沒(méi)法走 P2P 連接, 但是我們又想了解一下當(dāng)前的網(wǎng)絡(luò)環(huán)境; 此時(shí)可以使用 tailscale netcheck 命令來(lái)檢測(cè)當(dāng)前的網(wǎng)絡(luò)環(huán)境, 此命令將會(huì)打印出詳細(xì)的網(wǎng)絡(luò)環(huán)境報(bào)告:
~ ??? tailscale netcheck
2022/10/19 21:15:27 portmap: [v1] Got PMP response; IP: 123.123.123.123, epoch: 297671
2022/10/19 21:15:27 portmap: [v1] Got PCP response: epoch: 297671
2022/10/19 21:15:27 portmap: [v1] UPnP reply {Location:http://192.168.11.1:39735/rootDesc.xml Server:AsusWRT/386 UPnP/1.1 MiniUPnPd/2.2.0 USN:uuid:23345-2380-45f5-34534-04421abwb7cf0::urn:schemas-upnp-org:device:InternetGatewayDevice:1}, "HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=120\r\nST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\nUSN: uuid:34564645-2380-45f5-b069-sdfdght3245....."
2022/10/19 21:15:27 portmap: UPnP meta changed: {Location:http://192.168.11.1:39735/rootDesc.xml Server:AsusWRT/386 UPnP/1.1 MiniUPnPd/2.2.0 USN:uuid:23345-2380-45f5-b069-04421abwb7cf0::urn:schemas-upnp-org:device:InternetGatewayDevice:1}
Report:
* UDP: true
* IPv4: yes, 123.123.123.123:5935
* IPv6: no, but OS has support
* MappingVariesByDestIP: false
* HairPinning: true
* PortMapping: UPnP, NAT-PMP, PCP
* CaptivePortal: true
* Nearest DERP: XXXXX Aliyun
* DERP latency:
- XXXXX: 9.5ms (XXXXX Aliyun)
- XXXXX: 53.1ms (XXXXX BandwagonHost)其他補(bǔ)充
7.1、某些代理工具兼容性
MacOS 下使用一些增強(qiáng)代理工具時(shí), 如果安裝 App Store 的官方圖形化客戶端, 則可能與這些軟件沖突, 推薦使用純命令行版本并添加進(jìn)程規(guī)則匹配 tailscale 和 tailscaled 兩個(gè)進(jìn)程, 讓它們始終走 DIRECT 規(guī)則即可.
7.2、MacOS 下 CPU 占用突然起飛
在使用一些網(wǎng)絡(luò)代理工具時(shí), 網(wǎng)絡(luò)工具會(huì)設(shè)置默認(rèn)路由; 這可能導(dǎo)致 tailscaled 無(wú)法獲取到默認(rèn)路由接口, 然后進(jìn)入死循環(huán)并把 CPU 吃滿, 同時(shí)會(huì)與 Derper 服務(wù)器產(chǎn)生大量上傳流量. 截止本文發(fā)布此問(wèn)題已修復(fù), 請(qǐng)使用 mian 分支編譯安裝, 具體見(jiàn) ISSUE/5879.
7.3、阿里云安裝客戶端后無(wú)法更新軟件
Tailscale 默認(rèn)使用 CGNAT(100.64.0.0/10) 網(wǎng)段作為內(nèi)部地址分配網(wǎng)段, 目前 Tailscale 僅允許自己的接口使用此網(wǎng)段, 不巧的是阿里云的 DNS、Apt 源等也采用此網(wǎng)段. 這會(huì)導(dǎo)致阿里云服務(wù)器安裝客戶端后 DNS、Apt 等不可用, 解決方案目前只能修改源碼刪除掉這兩個(gè) DROP 規(guī)則并重新編譯.

7.4、開(kāi)啟路由轉(zhuǎn)發(fā)
大多數(shù)時(shí)候我們可能并不會(huì)在每個(gè)服務(wù)器上都安裝 Tailscale 客戶端, 通常只安裝 2、3 臺(tái), 然后想通過(guò)這兩三臺(tái)轉(zhuǎn)發(fā)該內(nèi)網(wǎng)的所有流量. 此時(shí)你需要
啟動(dòng) tailscale 時(shí)設(shè)置正確的路由提示 --advertise-routes=192.168.1.0/24來(lái)告訴 Headscale 服務(wù)器 “我這個(gè)節(jié)點(diǎn)可以轉(zhuǎn)發(fā)這些地址的路由”其他節(jié)點(diǎn)啟動(dòng)時(shí)需要增加 --accept-routes=true選項(xiàng)來(lái)聲明 “我接受外部其他節(jié)點(diǎn)發(fā)布的路由”
以上兩個(gè)選項(xiàng)配置后, 只需要 Headscale 服務(wù)器上使用 headscale node route enable -a -i XX(ID) 開(kāi)啟即可. 開(kāi)啟后目標(biāo)節(jié)點(diǎn)(ID)的路由就會(huì)發(fā)布到接受外部路由的所有節(jié)點(diǎn), 想要關(guān)閉的話去掉 -a 即可.
7.5、其他問(wèn)題
以上也只是我個(gè)人遇到的一些問(wèn)題, 如果有其他問(wèn)題推薦先搜索然后查看 ISSUE, 最后不行可以看看源碼. 目前來(lái)說(shuō) Tailscale 很多選項(xiàng)很模糊, 可能需要閱讀源碼以后才能知道到底應(yīng)該怎么做.
有收獲,點(diǎn)個(gè)在看


