讓我們用 Node.js 寫自己的 DDNS 動態(tài)域名程序

原文鏈接:http://xcoder.in/2014/09/20/lets-build-ourselves-ddns/

起因

一開始我在移動的寬帶中庵朝。那個時候雖然還不是完全的局域網(wǎng)悄谐,但是電信網(wǎng)絡訪問不了我的外網(wǎng) IP隆嗅。又因為我需要一個 DDNS 服務來維持我的 kacaka.ca(目前暫失效)折柠。

為了解決讓電信網(wǎng)絡也能訪問我的 Web,于是我想到了免費 CDN 當中比較有名的 CloudFlare偏形。而且它也有提供 API 讓開發(fā)者自己開發(fā)通過他的服務解析域名的服務谎柄。

再然后,去年的九月份朋鞍,我的早期 Node.js 作品 dloucflare 發(fā)布了已添。所以就有了這個帖子

現(xiàn)在滥酥,我已經(jīng)搬到電信了更舞,然后舊版的貌似不能用了,因為 CloudFlare 貌似 API 都遷移到了 https 上面坎吻。然后我為了我的小伙伴們能訪問我出租屋里的舊電腦缆蝉,又重構了一遍這個項目

使用 dlouc-flare 構建

首先安裝最新的 dlouc-flare 包:

$ npm install dlouc-flare

然后去創(chuàng)建一個 DF 對象:

var DloucFlare = require("dlouc-flare");
var df = DloucFlare.create("你的郵箱", "API KEY", "域名(不需要 www)");

CloudFlare 如何使用的話這里就不多做解釋了瘦真,至于 API KEY 的話刊头,可以在這里獲取到。

然后調(diào)用 df.dynamicDomains 函數(shù)去把你這個域名下面的一些子域名加入你這個腳本的動態(tài)域名范疇當中:

df.dynamicDomains([ "@", "www", "子域名3", "子域名4", ... ], 檢測時間間隔);

其中 "@" 代表的是域名沒有 www 前綴的本身吗氏。檢測時間間隔以毫秒為單位芽偏。

事實上雷逆,你也可以自定義一個檢測你當前主機的 IP 地址的函數(shù)(如果你不喜歡用包內(nèi)的默認檢測 IP 函數(shù))弦讽。

只要你寫一個函數(shù):

function checkIp(callback) {
    // blahblah...
    callback(undefined, IP地址);
}

然后覆蓋掉默認的 IP 檢測函數(shù)即可:

df.getIpFunction = checkIp;

最后保存退出并用 node 執(zhí)行你的程序就好了,程序就會開始歡快地跑了膀哲。

Preview
Preview

如何自己寫往产?

其實要完全自己寫也是很簡單的——無非就是調(diào)用一下 CloudFlare 的 API 而已。

我們定位明確就是要做 DDNS某宪,所以沒必要關系其它很多不相關的 API仿村,只需要最基礎的幾個就夠了。

API 解析

所有 API 的基礎 URI 都為:https://www.cloudflare.com/api_json.html兴喂。

驗證信息

根據(jù) CloudFlare 文檔所說蔼囊,所有的提交都要黏上驗證信息給 POST 過去。而驗證的字段如下:

  • tkn: 從你的個人頁面當中復制出來的 API KEY衣迷。
  • email: 你的登錄郵箱畏鼓。
  • a: 操作名,每種操作都有其特有的操作名壶谒。

獲取域名下的子域名記錄

其操作名為 rec_load_all云矫,我們不關心其它不重要的參數(shù),只需要再傳一個 z 字段代表其域名就好了汗菜,舉個例子:

var self = this;
var param = {
    a       : "rec_load_all",
    tkn     : this.apiKey,
    email   : this.email,
    z       : this.domain
};

var url = "https://www.cloudflare.com/api_json.html";
spidex.post(url, function(html, status) {
    if(status !== 200) {
        return callback(new Error("Error status while fetching DNS records."));
    }

    var json;
    try {
        json = JSON.parse(html);
    } catch(e) {
        return callback(new Error("Error while parsing DNS records: " + e.message));
    }

    if(json.result === "error") {
        var msg = json.msg;
        if(undefined === msg) msg = "Unknown error.";
        return callback(new Error(msg));
    } else if(json.result === "success") {
        var count = json.response.recs.count;
        var objects = json.response.recs.objs;
        for(var i = 0; i < count; i++) {
            self.records.push(new DNSRecordObject(self, objects[i]));
        }

        callback(undefined, self.records);
    } else {
        callback(new Error("Unknown error."));
    }
}, param, "utf8").on("error", callback);

上述代碼就是把 param 數(shù)據(jù)給 POST 到 API 的 RESTful 里面去让禀。然后根據(jù)返回值進行解析挑社。

關于 DNSRecordObject 的代碼可以自行翻閱這里

以及 spidex 的文檔在這里巡揍。

修改某記錄

其操作名為 rec_edit痛阻,如文檔所說,除了固有的幾個參數(shù)之外腮敌,我們還需要有如下參數(shù):

  • z: 域名录平。
  • id: 域名記錄編號,從 rec_load_all 中獲取缀皱。
  • type: 記錄類型斗这。如 A / CNAME 等等。
  • name: 子域名名啤斗,如果無前綴子域名則與域名相同表箭。
  • content: 值。如果我們只是做動態(tài)域名的話钮莲,這里的值就是 IP免钻。
  • service_mode: 服務類型,填原值即可崔拥。
  • ttl: TTL极舔,填原值即可。

上面參數(shù)的解說只是對于我們要做 DDNS 腳本而言的解釋链瓦。

所以說在 dnsrecordobject.js 中我是這么做的:

var param = {
    a       : "rec_edit",
    tkn     : this.dloucflare.apiKey,
    email   : this.dloucflare.email,
    id      : this.recordId(),

    z       : this.domain,
    type    : this.recordType(),
    name    : this.name,
    content : ip,

    service_mode    : this.object.service_mode,
    ttl     : this.object.ttl
};

var self = this;
spidex.post(config.baseUrl, function(html, status, respHeader) {
    if(status !== 200) {
        return callback(new Error("Error status while editing " + self.name + "."));
    }

    var json;
    try {
        json = JSON.parse(html);
    } catch(e) {
        return callback(new Error("Error whileparsing editing result: " + e.message));
    }

    if(json.result === "success") {
        self.object.content = ip;
        return callback();
    } else {
        var msg = json.msg || "Unknown error.";
        return callback(new Error(msg));
    }
}, param, "utf8").on("error", callback);

上面的代碼就能將你某個域名(this.domain)下的子域名 this.name 的 IP 給修改成 ip 了拆魏。

探測 IP

這種 API 網(wǎng)上就多了去了。

舉個簡單的例子慈俯,我的 dlouc-flare 的獲取 IP 的 API 就是從

http://www.telize.com/ip

來的渤刃。

請求上面的地址之后,輸出的內(nèi)容(注意有換行符)就是你當前機子所在的網(wǎng)絡的公網(wǎng) IP 了贴膘。

類似的 API 還有很多:

流程

有了上面的仨 API洋闽,一切都好說了,流程很簡單:

  • 獲取自己某個使用 CloudFlare 解析的域名下的子域名突梦。
  • 自己設置幾個子域名名拿來做 DDNS诫舅。
  • 設置一個定時器,每次定時器到時的時候都進行如下操作:
    1. 通過 IP 的 API 獲取當前 IP阳似。
    2. 循環(huán)遍歷每個自己設置的子域名名骚勘。
    3. 對于每個子域名,都判斷其當前記錄 IP 是否等于當前剛探測的 IP。

有了上面的幾個步驟,加上之前我們講的幾個 API泽疆,大家就能輕松加愉快地完成自己的 DDNS 腳本了户矢。

當然,如果自己懶的話也可以用本文一開始的方法殉疼,使用 dlouc-flare 這個包梯浪,通過簡單的編碼就能實現(xiàn)自己的 DDNS 動態(tài)域名腳本了。

這里的定時器時間自己按需而定瓢娜,就我自己而言挂洛,我是給設置了 1000 * 60 毫秒的間隔。

小結(jié)

最早與動態(tài)域名結(jié)緣的時候是初中的時候眠砾,大概七八年前了吧虏劲,那個時候花生殼什么的,但是最終用的是 3322.org褒颈。

其實基本的動態(tài)域名的原理很簡單柒巫,無非就是本地開一個腳本,不停去探測本機 IP谷丸,一旦有變化就去解析服務器修改堡掏。

本人在這里拋磚引玉。如果哪里有別的解析商的 API刨疼,大家自己也可以舉一反三泉唁,寫什么 DNSPod 的動態(tài)域名,寫什么 jiasule 的動態(tài)域名等等等等币狠。

喵~?(?ˊ?ˋ)?* ?????

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末游两,一起剝皮案震驚了整個濱河市砾层,隨后出現(xiàn)的幾起案子漩绵,更是在濱河造成了極大的恐慌,老刑警劉巖肛炮,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件止吐,死亡現(xiàn)場離奇詭異,居然都是意外死亡侨糟,警方通過查閱死者的電腦和手機碍扔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秕重,“玉大人不同,你說我怎么就攤上這事。” “怎么了二拐?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵服鹅,是天一觀的道長。 經(jīng)常有香客問我百新,道長企软,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任饭望,我火速辦了婚禮仗哨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铅辞。我一直安慰自己厌漂,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布斟珊。 她就那樣靜靜地躺著桩卵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪倍宾。 梳的紋絲不亂的頭發(fā)上雏节,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音高职,去河邊找鬼钩乍。 笑死,一個胖子當著我的面吹牛怔锌,可吹牛的內(nèi)容都是我干的寥粹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼埃元,長吁一口氣:“原來是場噩夢啊……” “哼涝涤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起岛杀,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤阔拳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后类嗤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糊肠,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年遗锣,在試婚紗的時候發(fā)現(xiàn)自己被綠了货裹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡精偿,死狀恐怖弧圆,靈堂內(nèi)的尸體忽然破棺而出赋兵,到底是詐尸還是另有隱情,我是刑警寧澤搔预,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布毡惜,位于F島的核電站,受9級特大地震影響斯撮,放射性物質(zhì)發(fā)生泄漏经伙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一勿锅、第九天 我趴在偏房一處隱蔽的房頂上張望帕膜。 院中可真熱鬧,春花似錦溢十、人聲如沸垮刹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荒典。三九已至,卻和暖如春吞鸭,著一層夾襖步出監(jiān)牢的瞬間寺董,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工刻剥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遮咖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓造虏,卻偏偏與公主長得像御吞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子漓藕,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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

  • 從三月份找實習到現(xiàn)在陶珠,面了一些公司,掛了不少享钞,但最終還是拿到小米揍诽、百度、阿里嫩与、京東寝姿、新浪、CVTE划滋、樂視家的研發(fā)崗...
    時芥藍閱讀 42,209評論 11 349
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,745評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)埃篓,斷路器处坪,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • Nmap掃描原理與用法 1Nmap介紹 Nmap掃描原理與用法PDF:下載地址 Nmap是一款開源免費的網(wǎng)絡發(fā)現(xiàn)(...
    y0ungta1a閱讀 5,374評論 0 50
  • 已記不得究竟是在怎樣的機緣巧合下,去年年底的某一天,30歲的我懵懵懂懂的加入到了一個21天的理財群里同窘,而后捶胸頓足...
    A張爽閱讀 252評論 0 0