前段時間應公司需求,須要將內網的服務映射到公網。因爲公司使用的是相似家庭寬帶的線路,沒有固定的公網 IP 地址,因此決定使用域名來完成。python
當時有幾種方案:json
一、花生殼:可是目前須要亂七八糟的認證備案,捨棄!安全
二、NAT123:花裏胡哨的,感受像垃圾軟件,也捨棄!服務器
三、holer:GITHUB 上面的一個項目,可是咱們只能安裝 Client 端,Server 端在別人手裏,不安全,捨棄!網絡
...架構
還有其它的亂七八糟的不少,可是都以爲要麼是 C/S 架構,麻煩。要麼就是使用別人的,定製要麼收費,要麼不安全,也都放棄了,最後決定參考網上的 Python 調用阿里雲 API 經過 Linux 定時任務來更新解析!運維
簡單的網絡拓撲以下圖: 阿里雲
說明:url
一、電信 ASDL 撥號,會有一個會變化的公網 IP 地址,咱們的域名就是要解析到最新的該 IP 地址上面spa
二、公司內網是一個路由器接交換機的方式,路由器比較 Low,H3C 的,簡單的進行一個端口轉發到指定的服務器 192.168.1.100
三、192.168.1.100 上面安裝 Nginx,作反向代理,同時也做爲統一的管理入口,方便管理,同時也作定時更新 DNS 解析的任務
首先,咱們須要去阿里雲建立一個 Accesskey ,這個東西將做爲咱們登陸阿里雲更新解析的用戶,具體建立方法能夠參考百度,建立完成後記得保留好生成的 Key 和 Secret:
注意:建立的 AccessKey 用戶必定要記得受權 DNS 管理 的權限,不然沒法更新!
其次,咱們須要有一個已經備案完成的域名,如 abc.com!
最後,有一臺內網的 Linux 機器,我的推薦 CentOS,幾年運維下來,幾乎用的都是這個,不爲別的,就爲了比較好管理。
【1】CentOS 服務器安裝 Python: 默認狀況下,CentOS 是擁有 Python 的,通常都是 2.6 或者 2.7,可是不必定有 pip,咱們須要安裝 pip,這裏採用的 epel 源:
yum -y install epel-release yum -y install python-pip
【2】安裝依賴的阿里雲 Python 包:前者是阿里雲鬚要的包,後者是模擬請求須要的包
pip install aliyun-python-sdk-alidns pip install requests
【3】編輯更新腳本 ddns_update.py,內容以下:
備註:腳本參考網上的老哥的分享,而後本身作了一些修改
注意:這裏解析有一個前提條件,就是你須要修改的那條解析規則必須已經存在,該腳本不能新增,只能修改舊的
#coding:utf-8 from aliyunsdkcore import client from aliyunsdkalidns.request.v20150109 import DescribeDomainsRequest,DescribeDomainRecordsRequest,UpdateDomainRecordRequest import json,urllib,re ###################################################################################### # 我的配置區域 ##################################################################################### # 建立的 AccessKey ID="xxxxx" Secret="xxxxx" # 默認 RegionId="cn-hangzhou" # 你的域名 DomainName="abc.com" # 你想解析的二級域名,是一個列表,能夠寫多個 HostNameList = ['test','hello', 'world'] # 默認 Types = "A" clt = client.AcsClient(ID,Secret,RegionId) ###################################################################################### # 動態獲取當前公司對外的公網 IP def GetLocalIP(): IPInfo = urllib.urlopen("http://ip.chinaz.com/getip.aspx").read() IP = re.findall(r"ip:'(.*?)',", IPInfo)[0] return IP # 更新域名 IP def EditDomainRecord(HostName, RecordId, Types, IP): UpdateDomainRecord = UpdateDomainRecordRequest.UpdateDomainRecordRequest() UpdateDomainRecord.set_accept_format('json') UpdateDomainRecord.set_RecordId(RecordId) UpdateDomainRecord.set_RR(HostName) UpdateDomainRecord.set_Type(Types) UpdateDomainRecord.set_TTL('600') UpdateDomainRecord.set_Value(IP) UpdateDomainRecordJson = json.loads(clt.do_action_with_exception(UpdateDomainRecord)) print UpdateDomainRecordJson # 獲取域名信息 def GetAllDomainRecords(DomainName, Types, IP): DomainRecords = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest() DomainRecords.set_accept_format('json') DomainRecords.set_DomainName(DomainName) DomainRecordsJson = json.loads(clt.do_action_with_exception(DomainRecords)) print DomainRecordsJson['DomainRecords']['Record'] for HostName in HostNameList: for x in DomainRecordsJson['DomainRecords']['Record']: RR = x['RR'] Type = x['Type'] if RR == HostName and Type == Types: RecordId = x['RecordId'] print RecordId EditDomainRecord(HostName, RecordId, Types, IP) IP = GetLocalIP() GetAllDomainRecords(DomainName, Types, IP)
【4】添加定時任務: 每兩小時更新一次
# 授執行權限 chmod 755 /scripts/ddns_update.py # 添加定時任務 echo "* */2 * * * /usr/bin/python /scripts/ddns_update.py" >> /var/spool/cron/root
【5】配置完成,此時你能夠手動執行檢驗該腳本是否可以正常的修改域名解析!至於後面的 Nginx 反向代理,網上的方法不少,這裏就不一一綴訴!
這裏感謝提供這個腳本的大神,可是我寫這個的時候已經離找到這個腳本有一段時間了,因此就沒法具體到哪位,有些遺憾!