前段時間應公司需求,需要將內網的服務映射到公網。由於公司使用的是類似家庭寬帶的線路,沒有固定的公網 IP 地址,所以決定使用域名來完成。
當時有幾種方案:
1、花生殼:但是目前需要亂七八糟的認證備案,舍棄!
2、NAT123:花里胡哨的,感覺像垃圾軟件,也舍棄!
3、holer:GITHUB 上面的一個項目,但是我們只能安裝 Client 端,Server 端在別人手里,不安全,舍棄!
...
還有其它的亂七八糟的很多,但是都覺得要么是 C/S 架構,麻煩。要么就是使用別人的,定制要么收費,要么不安全,也都放棄了,最后決定參考網上的 Python 調用阿里雲 API 通過 Linux 定時任務來更新解析!
簡單的網絡拓撲如下圖:
說明:
1、電信 ASDL 撥號,會有一個會變化的公網 IP 地址,我們的域名就是要解析到最新的該 IP 地址上面
2、公司內網是一個路由器接交換機的方式,路由器比較 Low,H3C 的,簡單的進行一個端口轉發到指定的服務器 192.168.1.100
3、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 反向代理,網上的方法很多,這里就不一一綴訴!
這里感謝提供這個腳本的大神,但是我寫這個的時候已經離找到這個腳本有一段時間了,所以就無法具體到哪位,有些遺憾!