打通大內(nèi)網(wǎng)第四期 部署并穿透DERP服務(wù)器 (基于Lucky的STUN穿透)

前言

上一期介紹了如何通過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):

  1. Tailscale免費(fèi)計(jì)劃只允許3個(gè)用戶刊侯,但是允許100臺(tái)設(shè)備。通過共享賬戶的方式锉走,可以允許更多人連接滨彻。
  2. 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_idclient_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_idclient_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)限。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末商膊,一起剝皮案震驚了整個(gè)濱河市伏伐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晕拆,老刑警劉巖藐翎,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異实幕,居然都是意外死亡吝镣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門昆庇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來末贾,“玉大人,你說我怎么就攤上這事整吆」澳欤” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵表蝙,是天一觀的道長裕膀。 經(jīng)常有香客問我,道長勇哗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任寸齐,我火速辦了婚禮欲诺,結(jié)果婚禮上抄谐,老公的妹妹穿的比我還像新娘。我一直安慰自己扰法,他們只是感情好蛹含,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著塞颁,像睡著了一般浦箱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上祠锣,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天酷窥,我揣著相機(jī)與錄音,去河邊找鬼伴网。 笑死蓬推,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澡腾。 我是一名探鬼主播沸伏,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼动分!你這毒婦竟也來了毅糟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤澜公,失蹤者是張志新(化名)和其女友劉穎姆另,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玛瘸,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜕青,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了糊渊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片右核。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖渺绒,靈堂內(nèi)的尸體忽然破棺而出贺喝,到底是詐尸還是另有隱情,我是刑警寧澤宗兼,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布躏鱼,位于F島的核電站,受9級特大地震影響殷绍,放射性物質(zhì)發(fā)生泄漏染苛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茶行。 院中可真熱鬧躯概,春花似錦、人聲如沸畔师。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽看锉。三九已至姿锭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伯铣,已是汗流浹背呻此。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懂傀,地道東北人趾诗。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像蹬蚁,于是被迫代替她去往敵國和親恃泪。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容