前言
上一期介紹了如何通過frp的stcp/sudp
來固定訪問端口施掏,雖然可靠性和安全性都得到了保障,配置還是麻煩了一點(diǎn)僻他,每添加一個(gè)服務(wù)都要修改兩處frpc的配置文件萧朝,并需要每個(gè)訪問者都手動(dòng)更新。并且對于訪問者而言缨叫,處理端口沖突椭符、注冊服務(wù)也需要一點(diǎn)知識(shí)儲(chǔ)備,顯然不如無腦安裝軟件來的方便耻姥。如果你只打算小范圍內(nèi)共享销钝,那么直接使用tailscale也是個(gè)不錯(cuò)的選擇。
理論上只要有一方為NAT1琐簇,是一定能直連的蒸健,但由于tailscale的服務(wù)器都在墻外座享,內(nèi)陸的網(wǎng)絡(luò)環(huán)境也比較復(fù)雜,偶爾會(huì)出現(xiàn)打不通的情況似忧。然而我們可以另辟蹊徑渣叛,在本地自建DERP中繼服務(wù)器,并通過LUCKY穿透到公網(wǎng)上盯捌。
第一步 安裝并配置Tailscale
Tailscale官網(wǎng):https://tailscale.com/
關(guān)于Tailscale基本的安裝淳衙、配置在此不多贅述,教程非常多饺著,在此貼一篇OpenWrt的教程:
openwrt使用tailscale組建網(wǎng)對網(wǎng)的一些補(bǔ)充
如果你需要在外訪問整個(gè)內(nèi)網(wǎng)箫攀,請正確配置子網(wǎng)路由。
如果可能的話幼衰,盡量將Tailscale和DERP安裝在同一臺(tái)機(jī)器上靴跛。即使不行,最好也在部署DERP的機(jī)器上安裝Tailscale渡嚣,用于身份驗(yàn)證梢睛。
如果用于驗(yàn)證的Tailscale客戶端是通過docker安裝的,為了讓DERP能夠與Tailscale交互识椰,請?zhí)砑勇窂接成?br>-v /run/tailscale:/var/run/tailscale
我將Tailscale裝在路由器上绝葡,DERP安裝在路由器下面的Unraid上。如果以插件的形式直接安裝裤唠,則無法使用本地局域網(wǎng)地址訪問Unraid挤牛,只能使用Tailscale的100開頭的地址,因此我最后用Docker安裝种蘸,網(wǎng)絡(luò)選擇br0并指定了另外一個(gè)ip。
當(dāng)配置完成竞膳,已經(jīng)可以在外網(wǎng)通過Tailscale訪問后航瞭,再注冊一個(gè)用于共享的小號,并將其加入大號的Tailscale網(wǎng)絡(luò)坦辟,理由有以下兩點(diǎn):
- Tailscale免費(fèi)計(jì)劃只允許3個(gè)用戶刊侯,但是允許100臺(tái)設(shè)備。通過共享賬戶的方式锉走,可以允許更多人連接滨彻。
- DERP服務(wù)器若不開啟驗(yàn)證,那么誰都可以白嫖挪蹭;但一旦開啟驗(yàn)證亭饵,只有本機(jī)當(dāng)前登錄Tailscale的賬戶有權(quán)訪問,其他用戶均無法訪問梁厉。
然后將所有Tailscale客戶端上登錄的賬號換成小號辜羊,加入大號的網(wǎng)絡(luò)(也就是在最后一步,選擇connect device
的時(shí)候,點(diǎn)擊大號郵箱)八秃。
第二步 安裝并配置DERP服務(wù)器
首先先給DERP服務(wù)器準(zhǔn)備一個(gè)域名碱妆,并解析到STUN穿透的ipv4公網(wǎng)地址,如果你之前沒有用過ddns昔驱,直接使用Lucky的DDNS疹尾,通過接口獲取ipv4即可。
接著申請證書骤肛,使用Lucky申請非常方便航棱,并且可以映射證書路徑供其它服務(wù)使用,以及在證書更新時(shí)調(diào)用自定義腳本萌衬;如果Lucky和DERP沒有部署在同一個(gè)機(jī)器上饮醇,可以用Lucky的webdav功能將映射證書的路徑分享出來,或者通過自定義腳本運(yùn)行scp和ssh命令秕豫,上傳證書并重啟DERP朴艰。具體過程略過不表。
接下來安裝DERP混移,我使用docker安裝祠墅,記得修改證書的映射路徑、端口映射和域名歌径。我這里將8051作為derp端口毁嗦,3478作為stun端口。如果不想開啟身份驗(yàn)證回铛,請將第七行的true改為false狗准。
docker run --restart always \
-p 8051:443 -p 3478:3478/udp \
-e DERP_CERT_MODE=manual \
-v /your/cert/path:/app/certs \
-e DERP_ADDR=:443 \
-e DERP_DOMAIN=derp.xxxx.com \
-e DERP_VERIFY_CLIENTS=true \
-v /var/run/tailscale:/var/run/tailscale \
fredliang/derper
然后為DERP服務(wù)器創(chuàng)建STUN穿透規(guī)則,需要兩條茵肃。一條給derp端口腔长,協(xié)議選擇tcp,一條給stun端口验残,協(xié)議選擇udp捞附,不會(huì)的朋友可以去看看第一、第二期教程您没。
如果一切順利鸟召,就可以在瀏覽器里訪問https://derp域名:derp
穿透后的公網(wǎng)端口。
看到以上界面說明成功氨鹏。
第三步 將DERP服務(wù)器添加至Tailscale中
用大號進(jìn)入Tailscale后臺(tái)欧募,在頂部切換到Access Controls
選項(xiàng)卡,在acls
后添加derpMap
規(guī)則喻犁。
// 前面有一些注釋槽片,不修改
"acls": [
// Allow all connections.
// Comment this section out if you want to define specific restrictions.
{"action": "accept", "src": ["*"], "dst": ["*:*"]},
],
"derpMap": {
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "myderp",
"RegionName": "home",
"Nodes": [{
"Name": "1",
"RegionID": 900,
"HostName": "derp.xxxxx.xxx",
"DERPPort": 25814,
"STUNPort": 25876,
"InsecureForTests": true,
}],
},
},
},
// Define users and devices that can use Tailscale SSH.
//...后面是ssh的內(nèi)容何缓,不修改
修改Hostname為你DERP服務(wù)器的域名,DERPPort和STUNPort分別改為對應(yīng)的公網(wǎng)端口(不知道改成哪個(gè)端口就把我的規(guī)則和我之前的Lucky截圖對比一下)还栓。確認(rèn)無誤后點(diǎn)擊保存碌廓。
在安裝了Tailscale的機(jī)器(或容器)上執(zhí)行
tailscale netcheck
如果沒有出現(xiàn)測速結(jié)果里沒有出現(xiàn)myderp,請檢查規(guī)則是否編寫正確剩盒,如果沒有這個(gè)節(jié)點(diǎn)沒有測速結(jié)果谷婆,可以稍等一會(huì)兒再試。當(dāng)看到myderp節(jié)點(diǎn)的延遲后辽聊,證明配置成功纪挎。
第四步 自動(dòng)更新DERP服務(wù)器端口
Tailscale支持通過網(wǎng)頁后臺(tái)面板、GitOps和api更新acl規(guī)則跟匆。使用GitOps可以清晰的看到每一次更新的時(shí)間以及是否成功异袄,使用api則更加簡單,本文使用api進(jìn)行更新玛臂。
- 生成OAuth client并獲取id和secret
使用大號登錄Tailscale后臺(tái)烤蜕,在Settings
- OAuth clients
中點(diǎn)擊Generate OAuth client
。OAuth client的名稱隨便填迹冤,勾選對ACL
的read和write權(quán)限讽营。然后點(diǎn)擊Generate client
,并復(fù)制生成的id和secret泡徙。
不同于最大有效期為90天的api key橱鹏,OAuth clients不會(huì)過期,免去了手動(dòng)更新key的麻煩堪藐。
- 配置更新腳本
回到Lucky后臺(tái)莉兰,編輯derp端口的穿透規(guī)則,將以下腳本填入自定義腳本中庶橱。
記得修改client_id
和client_secret
為你剛才獲取到的值贮勃。
#set your oauth client here
client_id=XXXXXXXXXXXXXXXXX
client_secret=tskey-client-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
api_key=`curl -d "client_id=$client_id" \
-d "client_secret=$client_secret" \
"https://api.tailscale.com/api/v2/oauth/token"`
tskey=`echo $api_key | awk -F "\"" '{print $4}'`
DERPPort=${port}
tmp='/tmp/tailscale.hujson'
curl "https://api.tailscale.com/api/v2/tailnet/-/acl" \
-H "Authorization: Bearer $tskey" > $tmp
sed -i 's/"DERPPort".*/"DERPPort": '$DERPPort',/' $tmp
curl "https://api.tailscale.com/api/v2/tailnet/-/acl" \
-H "Authorization: Bearer $tskey" --data-binary @$tmp
編輯STUN端口的穿透規(guī)則,將以下腳本填入自定義腳本中苏章。
記得修改client_id
和client_secret
。
#set your oauth client here
client_id=XXXXXXXXXXXXXXXXX
client_secret=tskey-client-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
api_key=`curl -d "client_id=$client_id" \
-d "client_secret=$client_secret" \
"https://api.tailscale.com/api/v2/oauth/token"`
tskey=`echo $api_key | awk -F "\"" '{print $4}'`
STUNPort=${port}
tmp='/tmp/tailscale.hujson'
curl "https://api.tailscale.com/api/v2/tailnet/-/acl" \
-H "Authorization: Bearer $tskey" > $tmp
sed -i 's/"STUNPort".*/"STUNPort": '$STUNPort',/' $tmp
curl "https://api.tailscale.com/api/v2/tailnet/-/acl" \
-H "Authorization: Bearer $tskey" --data-binary @$tmp
目前Lucky并未提供自定義腳本的測試功能奏瞬,不過只是填寫兩個(gè)變量而已枫绅,應(yīng)該不會(huì)出什么幺蛾子...吧。
第五步 為Tailscale添加本地DNS并劫持域名
愿意折騰到這一步的朋友硼端,有很大概率已經(jīng)開啟了ipv6并淋,并配置好了反向代理。如果想要實(shí)現(xiàn)“一個(gè)域名珍昨,在內(nèi)網(wǎng)/Tailscale中用內(nèi)網(wǎng)ipv4县耽,在外網(wǎng)中用ipv6”的效果句喷,可以嘗試一下添加本地DNS。如果不想配置反向代理兔毙,那么可以跳過這步唾琼。
本地劫持泛域名
首先在你是用的dns服務(wù)中添加HOSTS,劫持你要訪問的泛域名澎剥。如果不想在內(nèi)網(wǎng)劫持锡溯,僅想在Tailscale中劫持,可以用Docker再裝一個(gè)SmartDNS哑姚,記得用網(wǎng)橋(如br0)把容器IP綁定到與宿主機(jī)同網(wǎng)段祭饭,并使用53端口。
-
對于dnsmasq(也就是OpenWrt的默認(rèn)dns)
打開
/etc/dnsmasq.conf
叙量,添加address = /mydomain.com/192.168.0.1
并重啟dnsmasq倡蝙,這會(huì)劫持mydomain.com和它的所有子域名到192.168.0.1。
-
對于SmartDNS
在自定義規(guī)則
或域名地址
中添加address /mydomain.com/192.168.0.1
并重啟SmartDNS绞佩,這會(huì)劫持mydomain.com和它的所有子域名到192.168.0.1寺鸥。
然后在內(nèi)網(wǎng)機(jī)器上清除dns緩存,使用nslookup查詢剛才劫持的域名征炼。
由于OpenWrt會(huì)默認(rèn)劫持所有訪問53端口的流量到OpenWrt的53端口析既,因此如果你是用OpenWrt作為主路由,但自定義DNS不在OpenWrt的ip上谆奥,則需要在網(wǎng)絡(luò)
- 防火墻
- 自定義規(guī)則
中注釋掉所有跟53端口相關(guān)的規(guī)則眼坏。
如果還不成功,大概率是某些科學(xué)插件修改或劫持dns導(dǎo)致的酸些,請關(guān)閉劫持功能或者直接在科學(xué)插件中設(shè)置DNS劫持宰译。
在Tailscale中添加本地DNS
進(jìn)入Tailscale后臺(tái),進(jìn)入DNS魄懂,點(diǎn)擊Add nameserver
- Custom
沿侈,輸入你內(nèi)網(wǎng)DNS的IP地址,可以為Tailscale的100開頭的地址市栗,也可以是添加進(jìn)Tailscale的子網(wǎng)地址缀拭,并開啟Restrict to domain
,填入需要劫持的頂級域名填帽。(如填入mydomain.com蛛淋,會(huì)劫持它的所有子域名)請注意,Tailscale不支持指定協(xié)議和端口篡腌,默認(rèn)使用53端口褐荷、udp協(xié)議。
可能部分DNS服務(wù)默認(rèn)拒絕外網(wǎng)請求嘹悼,需要手動(dòng)開啟叛甫。以O(shè)penWrt為例层宫,需要在網(wǎng)絡(luò)
- DHCP/DNS
- 基本設(shè)置
中取消勾選僅本地服務(wù)
。
結(jié)語
至此Tailscale和DERP服務(wù)器的配置就結(jié)束了其监,經(jīng)過這一番折騰萌腿,我們實(shí)現(xiàn)了100%直連率,并統(tǒng)一了內(nèi)網(wǎng)棠赛、Tailscale哮奇、ipv6的使用體驗(yàn)。在SVCB/HTTPS記錄普及之前睛约,對STUN穿透的折騰大約就止步如此了吧鼎俘。
如果你仍對安全性抱有擔(dān)憂,可以自行修改acl規(guī)則辩涝,默認(rèn)拒絕共享賬戶訪問子網(wǎng)贸伐,僅允許訪問特定的ip和端口。如果你想讓特定的設(shè)備不受用戶權(quán)限的限制怔揩,可以給它打上tag捉邢,再對該tag單獨(dú)設(shè)置權(quán)限。