各位都是程序員,工作中是不是遇到個類似情況。
在家里研究的一些開源代碼或寫的一些demo或試驗代碼,在工作中正好需要參考一下,但是在家里的電腦上。
雖然這些都可以用雲盤/網盤之類的來完成,源代碼也可以托管到源碼平台。
但是這些都有一定局限性,先不說你不可能把所有東西都上傳到雲盤或git,就算你真的全上傳了,在公司你也需要在重新部署一遍。
很多時候,我們只是想參考一下運行起來是很么樣子而已,重新部署跟據環境差異的不同往往需要浪費很多時間,有的時候還得重新錄入一些測試數據(因為數據庫同步就更麻煩)
。
試想一下,如果我們可以
直接訪問家里的電腦,而且可以直接連到家里電腦上數據庫上是不是很爽。
我們知道,如果想通過互聯網來訪問家里的電腦,那么首先就得要知道家里電腦的公網 IP 地址。但是,家用寬帶
一般
是沒有固定IP地址的,每次連接上網后該地址都會隨機改變,這樣我們要在外訪問家里的電腦就變得有些麻煩了。所以,這時候我們就需要用到
DDNS
(Dynamic Domain Name Server)
。
下面,我們就介紹一種利用
阿里雲解析DNS服務來實現一個DDNS服務(騰訊雲也有這個服務)。
在開始之前,大家先注意看一下下面這幾個前提條件,免得浪費時間。因為不是所有網絡都需要(或可以用到)DDNS的,而且DDNS也不能解決所有問題。
1.如果你的網絡有固定IP或沒有公網IP地址就不用看這篇文章了,前者沒有必要,后者靠DDNS也解決不了。
2.在全球IP資源緊張的情況下(當然也有別的原因),目前大多數
ISP對家用寬帶都不再提供公網IP,需要自己申請,目前已知的是電信/聯通可以自己申請,但其他二級
ISP都不再提供公網IP地址了
。
所以,如果你用的是長城、艾普、移動之類的寬帶也不用看了,實現不了。
3.目前全國所有家用寬帶上傳80端口都是被封了的,其它端口跟據運營商或地區也有被封的(21、8080之類常用的),注意自己測試,選可用的端口進行服務。
這個扯到錢的問題了,當然
如果你是土豪,請隨意(如果你真土豪的話,直接開通商業寬帶用固定IP地址就行了)。
5.阿里雲解析DNS服務是什么?
通過官方介紹我們知道,所謂雲解析,其它就是讓我們可以自己編寫程序通過調用API來管理域名,包括解析(目前官方提供 JAVA、PHP、Python、C#的開發SDK)。
為了方便描述,我們在這里作一些名詞約定,如果沒有特殊說明,文章中都使用簡稱。
API 默認是指 雲解析DNS服務API 的簡稱,
路由 是指 家庭環境的總路由器,
局域網 是指 家庭環境的局域網
,
公網IP 是指
家庭環境的公網IP
,
第三方服務 是指 一個能返回公網IP的服務真的第三方(例如:ip138)
,
“第三方服務”
(
帶引號的
) 是指 你自己可隨意控制的、能通過互聯網進行訪問,有固定訪問地址的服務(例如:你自己購買了雲服務器,一般都是有固定地址的)。
看完上面幾點,如果沒有問題的話,我們就可以正式搭建DDNS服務了。
首先
,我們需要一台在家庭網絡下運行的設備來運行一個DDNS客戶端。(不只局限於電腦,理論上只要是可以運行程序,能主動對外發出請求的設備都行,最好是可以24小時不間斷的工作,斷電或斷網后可以自行恢復的。可以是電腦/服務器、
樹莓派、可安裝插件的智能路由器都可行
)
其次,針對不同設備,解決方案也略有不同,主要原因是:
a.
上面的設備除了路由器外,其他設備都需要借助
第三方
服務
才能取得公網IP地址。
b.既然需要用到
第三方
服務,那
由誰發
向API發送更新請求呢?
但總體來說也就兩步:第一步,獲取到公網IP地址。第二步,在IP變化時,向API發送更新請求。
跟據以上情況,我們可得到三種最優的解決方案(相對而言,更小的成本、最小的風險、
最快的解析生效時間
)。
方案1,路由 + API
方案2,局域網內設備 + 第三方能返回公網IP的
服務 +
API
方案3,局域網內設備 + “
第三方服務
” +
API
第一種方案是最完美的方案,因為路由器耗電少,可以24小時不間斷工作,斷電或斷網都可以自動連接,可以第一時間檢測到公網IP的變化。但是,目前還沒見到市面上那款路由器集成這個的(有集成的花生殼的),所以你就需要一個智能路由器然后自己開發插件,大多數路由插件都是C/C++,但好在這個功能很簡單,而且相關的SDK官方雖然沒有提供,但開源社區里有。總體而言,這個方案相於而言要復雜些,但也是最理想的。
第二種方案,局域網內設備
上面運行一個DDNS客戶端或插件
直接與API
交互,缺點就是需要借助第三方服務來獲公網IP地址。我們知道,最大解析生效時間 = TTL + 獲取IP的周期時間
,所以我們希望獲取IP的周期當前是越短越好,但這樣被封的幾率就越大,增加了些不穩定的因數。
第三種方案,同樣是
局域網內設備
上面運行一個DDNS客戶端或插件,但不
直接與API
交互,只需要不停的向“第三方服務” 發送
心跳請求
就行
,然后“
第三方服務
”才
與API
交互
。
思路都介紹清楚了,下面我們就進入到實戰階段。
因為我是搞.net的,對.net最熟悉,所以代碼都是C#的。其實,其它語言像go,php,node.js,python的解決方案都比.net的多,只是我不熟悉這些語言,不好修改,所以就准備自己動手。
當然,動手之前去github上搜一下有沒有現成的,結果還真找到了一個,用的是上面第二種方案,代碼是基於.net core的,並支付
docker,可以說
相當不錯(github)。
不過
我使用的過程中遇到一些小問題。我家里服務器是windows server 2016的系統,雖然2016集成了
docker,但我折騰了好幾天並沒有在windows 2016上把docker跑起來,這樣就不能以服務的方式運行,也沒法開機啟動。
所以我就把原代碼修改了一下,改成windows服務了
。
還沒完呢,對我這種追求完美的人來說,用第三方的服務來獲取IP實現的還是有些不爽,而且我家里是台微服務器,還是乞丐版,配置很低(居然用了40多M內存),我自己在阿里雲上也有服務器。
所以,我又動手把源碼改成第三種方案了。
原先准備在家和阿里雲之間用TCP或UDP來鏈接,這樣實時性最好,最后一想太麻煩了,也沒有必要。就
直接HTTP協議來多好,還可以把原先阿里雲上的web網站利用起來,改一下就可以了。
代碼說明:
1.代碼分為兩部分,有個叫aspnetCore的項目,是第三種方案中用在遠程服務器上的,因為我是在已有的網站上改造的,所以單獨寫了一個示例代碼,你可能將它集成到你自己的網站上。
2.src目錄下的AliyunDDNS.Client項目是第二種方案的windows服務版,為了方便服務的安裝和卸載,我寫了兩個叫Install.bat、Uninstall.bat的批處理文件,在項目的
bin/Debug目錄下(注意:遠行時可能需要用管理員權限運行)。
3.src目錄下的AliyunDDNS.HeartbeatService的項目是第三種方案的客戶端,也是一個
windows服務,用於不斷的對外發出請求,同樣在
bin/Debug目錄下也有
Install.bat、Uninstall.bat
。
下面是遠行起來的一些效果截圖(有圖有真相嘛,哈哈)


一些知識點
a.局域網內的計算機或設備直接從本地是獲取不到公網IP地址的,必須借助於某個能夠返回IP的第三方服務才行(網上的方案大多是借助ip138)。
b.服務端可以很容易獲取到客戶端的公網IP地址,如果服務器端和客戶端不在同一個局域網,那么獲取的就是公網IP地址(這里不考慮代理的情況)。
c.解析生效時間 = TTL + 獲取IP的周期時間。阿里雲解析免費版TTL為10分鍾,收費的最高為1秒。所以
獲取IP的周期時間應該盡量短小,路由器能直接監聽到IP的變化,但其他設備就需要和第三方交互並通過不斷輪詢的方式來獲取。
題外話
像花生殼這類的公司
(其他的都差不多)
,主打功能是內網穿透,就成本而言,
內網版和
公網版可以說一個是天上,一個是地下
。
但是,在前面1、2、3的大背景下,內網版更有商業價值,所以這類公司,對
內網版
和
公網版
定價相差並不大, 所以造成公網版價格虛高,所有有些不划算。(公網版才是DDNS服務,內網穿透功能其實上是代理)。
就以花生殼來說吧,以前花錢買了個花生殼專業版,都經常性訪問不到。開始不知道原因,一直以為是自己網絡環境的問題,一個偶然情況下,發現了花生殼商城有個測試頁面沒有關閉,0元就可以買到全套花生殼服務,果斷下單買了一個“鉑金版終身服務”,那速度就很快了,用起來就一點兒問題都沒有。你想想,專業版都這樣,你要花多少錢才能買到一個穩定的服務呢。當然了,如果你沒有公網IP地址,這也不失為一個好的選擇(花生殼這公司我也是醉了。1.犯這么低級的錯誤。2.沒見過購買虛擬服務還要運費的。3.我把該BUG報告給他們管理員,他丫的招呼都不打就把訂單取消就算解決問題了,而且10塊錢運費也沒退還)。