無需花生殼闷祥,阿里云解析實現(xiàn)內(nèi)網(wǎng)穿透

家里閑置著一臺老款的Mac mini Server,跑OS X越來越慢构挤,索性裝上了Cent OS 7髓介,變成了一臺家庭服務(wù)器,裝上了Plex媒體服務(wù)器和Transmission下載服務(wù)筋现,同時唐础,也裝上了Nginx、Mysql矾飞、MongoDB一膨、Redis等,可以調(diào)試代碼洒沦,甚至擔(dān)當(dāng)一些小型項目的服務(wù)器豹绪。

不過,只在家庭內(nèi)網(wǎng)使用微谓,功能太有限森篷,于是接下來面臨的一個問題就是內(nèi)網(wǎng)穿透。使用過花生殼和花生棒豺型,服務(wù)相當(dāng)不穩(wěn)定仲智,而且種種受限,每要多加一個端口就要多花錢姻氨,安全性也有問題钓辆。

其實想想,內(nèi)網(wǎng)穿透的最大難題無非就是家里是動態(tài)公網(wǎng)IP,每變換一次公網(wǎng)IP前联,需要重新解析一次域名功戚。而阿里云等大型的云服務(wù)商,目前都已經(jīng)實現(xiàn)了域名解析管理的API接口似嗤,而且基本都是立即就可生效 啸臀。

所以我的思路就是,系統(tǒng)運行一個定期執(zhí)行的程序烁落,每隔一段時間掃描一下最新的公網(wǎng)IP乘粒,如果發(fā)現(xiàn)最新的公網(wǎng)IP與域名解析到的IP地址不一致,就通過阿里云API自動更新解析設(shè)置即可伤塌。這樣的花費不過每年一個域名的費用灯萍,最貴也就幾十塊錢。

具體實現(xiàn)步驟如下:

1. 阿里云設(shè)置

首先每聪,要確定一個準(zhǔn)備用于外網(wǎng)訪問的域名旦棉,并將此域名轉(zhuǎn)入到阿里云的云解析服務(wù)來解析。如圖所示药薯,添加需要管理的域名绑洛。

阿里云云解析服務(wù)

轉(zhuǎn)入后,在解析設(shè)置中果善,設(shè)置一下A記錄解析诊笤,解析的IP地址可以填當(dāng)前的公網(wǎng)IP。如果不知道自己的公網(wǎng)IP巾陕,在CentOS系統(tǒng)下讨跟,可以輸入使用以下命令獲取當(dāng)前的公網(wǎng)IP。

curl ifconfig.me

獲取公網(wǎng)IP后鄙煤,在阿里云云解析中設(shè)置完A記錄解析晾匠。

設(shè)置A記錄解析

在阿里云賬戶管理后臺,點擊右上角的賬戶頭像梯刚,然后點擊accesskeys凉馆,或者直接登陸https://ak-console.aliyun.com,獲取阿里云的AccessKeyIDAccessKeySecret亡资。

2. 路由器設(shè)置

阿里云的設(shè)置完成后澜共,需要對路由器設(shè)置端口映射,使外網(wǎng)對公網(wǎng)IP的端口訪問能轉(zhuǎn)發(fā)到內(nèi)網(wǎng)服務(wù)器的相應(yīng)端口锥腻。絕大部分的路由器都支持端口映射嗦董。

常見的服務(wù)端口包括,用于WEB訪問的80端口瘦黑、SSH遠(yuǎn)程管理的22端口京革、Mysql數(shù)據(jù)庫的3306端口奇唤、Transmission下載服務(wù)管理的9091端口和Plex媒體服務(wù)的32400端口等等。不用花生殼的好處就是沒有端口數(shù)量限制匹摇,想設(shè)置多少就可以設(shè)置多少咬扇。

當(dāng)然,在設(shè)置端口映射之前廊勃,應(yīng)確保服務(wù)器的內(nèi)網(wǎng)IP已經(jīng)設(shè)置為靜態(tài)IP懈贺,而不是DHCP動態(tài)獲取。

3. 服務(wù)器設(shè)置

服務(wù)器端安裝好想要使用的各種服務(wù)后坡垫,別忘了在防火墻中開啟相應(yīng)的端口隅居,在CentOS 7中,防火墻永久開啟端口的命令是:

firewall-cmd --add-port=80/tcp --permanent

開啟之后別忘了重新載入防火墻的設(shè)置以使其生效葛虐,命令如下:

firewall-cmd --reload

4. 自動更新域名解析程序

準(zhǔn)備工作都做好了,接下來就是通過程序檢測公網(wǎng)IP棉钧,并在公網(wǎng)IP發(fā)生變化時屿脐,及時更新阿里云的域名解析。

這個程序是用Python寫的宪卿,先使用Python的包管理工具pip下載安裝阿里云的Python SDK的诵。如果沒有安裝pip,則先安裝pip:

yum install pip

安裝好pip后佑钾,安裝阿里云的Python核心SDK以及云解析SDK:

pip install aliyun-python-sdk-core
pip install aliyun-python-sdk-alidns

導(dǎo)入項目所需要的包西疤,如果缺少則使用pip安裝:

import os
import json
from urllib2 import urlopen
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest

完整代碼如下:

#!/usr/bin/env python
# coding= utf-8

import os
import json
from urllib2 import urlopen
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest

class DnsHandler:
    # 從阿里云開發(fā)者后臺獲取Access_Key_Id和Access_Key_Secret
    access_key_id = ""
    access_key_secret = ""

    # 填入自己的域名
    domain_name = ""
    # 填入二級域名的RR值
    rr_keyword = ""

    # 解析記錄類型,一般為A記錄
    record_type = "A"

    # 用于儲存解析記錄的文件名
    file_name = ".ip_addr"

    client = None
    record = None
    current_ip  = ''

    # 初始化休溶,獲取client實例
    def __init__(self):
        self.client = AcsClient(
            self.access_key_id,
            self.access_key_secret,
            self.region_id
        )
        self.record = self.get_record()
        self.current_ip = self.get_current_ip()

    # 如果公網(wǎng)IP發(fā)生變化代赁,則自動修改阿里云解析記錄
    def reset(self):
        if self.current_ip <> self.get_record_value():
            print self.update_record(self.current_ip)
            self.get_record()

    # 獲取阿里云域名解析完整記錄,并使用文件緩存
    def get_record(self):
        if os.path.isfile(self.file_name) :
            file_handler = open(self.file_name, 'r')
            r = file_handler.read()
            file_handler.close()
        else :
            request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
            request.set_PageSize(10)
            request.set_action_name("DescribeDomainRecords")
            request.set_DomainName(self.domain_name)
            request.set_RRKeyWord(self.rr_keyword)
            request.set_TypeKeyWord(self.record_type)
            r = self.client.do_action_with_exception(request)
            file_handler = open(self.file_name, 'w')
            file_handler.write(r)
            file_handler.close()
        return json.loads(r)

    # 獲取阿里云域名解析記錄ID
    def get_record_id(self) :
        return self.record["DomainRecords"]["Record"][0]["RecordId"]

    # 獲取當(dāng)前域名解析記錄
    def get_record_value(self) :
        return self.record["DomainRecords"]["Record"][0]["Value"]

    # 修改阿里云解析記錄
    def update_record(self, value):
        request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
        request.set_action_name("UpdateDomainRecord")
        request.set_RecordId(self.get_record_id())
        request.set_Type(self.record_type)
        request.set_RR(self.rr_keyword)
        request.set_Value(value)
        return self.client.do_action_with_exception(request)

    # 獲取當(dāng)前公網(wǎng)IP
    def get_current_ip(self):
        return json.load(urlopen('http://jsonip.com'))['ip']

# 實例化類并啟動更新程序
dns = DnsHandler()
dns.reset()

將以上代碼保存為dns.py文件兽掰,并賦予執(zhí)行權(quán)限:

chmod +x dns.py

5. 設(shè)置定時運行

CentOS內(nèi)置有強大的計劃任務(wù)工具Crontab芭碍,如果系統(tǒng)里沒有則先使用yum安裝:

yum install crontabs

首先,設(shè)置執(zhí)行用戶的環(huán)境變量孽尽,比如窖壕,我們使用root用戶來執(zhí)行這一程序,則先在用戶目錄下建立.profile文件杉女,或者在已有的.profile文件下加入如下一行瞻讽,以使得可以使用VI來編輯cron文件:

EDITOR=vi; export EDITOR

建立mycron文件,加入如下內(nèi)容:

*/10 * * * * /root/ddns/dns.py

這意味著每10分鐘執(zhí)行一次任務(wù)熏挎,即掃描公網(wǎng)IP速勇,若與阿里云解析不一致,則修改阿里云解析婆瓜。

然后快集,提交crontab任務(wù):

crontab mycron

好了贡羔,大功告成,接下來个初,程序會每隔10分鐘自動掃描公網(wǎng)IP乖寒,然后自動更新阿里云的解析,速度院溺、穩(wěn)定性和安全性都遠(yuǎn)勝于第三方的DDNS服務(wù)楣嘁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市珍逸,隨后出現(xiàn)的幾起案子逐虚,更是在濱河造成了極大的恐慌,老刑警劉巖谆膳,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叭爱,死亡現(xiàn)場離奇詭異,居然都是意外死亡漱病,警方通過查閱死者的電腦和手機买雾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杨帽,“玉大人漓穿,你說我怎么就攤上這事∽⒂” “怎么了晃危?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長老客。 經(jīng)常有香客問我僚饭,道長,這世上最難降的妖魔是什么沿量? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任浪慌,我火速辦了婚禮,結(jié)果婚禮上朴则,老公的妹妹穿的比我還像新娘权纤。我一直安慰自己,他們只是感情好乌妒,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布汹想。 她就那樣靜靜地躺著,像睡著了一般撤蚊。 火紅的嫁衣襯著肌膚如雪古掏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天侦啸,我揣著相機與錄音槽唾,去河邊找鬼丧枪。 笑死,一個胖子當(dāng)著我的面吹牛庞萍,可吹牛的內(nèi)容都是我干的拧烦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼钝计,長吁一口氣:“原來是場噩夢啊……” “哼恋博!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起私恬,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤债沮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后本鸣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疫衩,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年荣德,在試婚紗的時候發(fā)現(xiàn)自己被綠了隧土。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡命爬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辐脖,到底是詐尸還是另有隱情饲宛,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布嗜价,位于F島的核電站艇抠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏久锥。R本人自食惡果不足惜家淤,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瑟由。 院中可真熱鬧絮重,春花似錦、人聲如沸歹苦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殴瘦。三九已至狠角,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚪腋,已是汗流浹背丰歌。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工姨蟋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人立帖。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓眼溶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厘惦。 傳聞我的和親對象是個殘疾皇子偷仿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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