1. 程式人生 > >使用阿里雲 dns sdk 解決電信公網ip自動變化問題;自己動手實現ddns

使用阿里雲 dns sdk 解決電信公網ip自動變化問題;自己動手實現ddns

首先說下情況,我的樹莓派通過電信光貓dmz主機設定全埠對映得到了公網ip,ssh等連線都很迅速,ping值為60ms。上海電信200M寬頻,上傳25mbps。由於是動態公網ip,電信隔幾天就換ip,這個差不多十天,不一定。我寫了簡單的指令碼,用計劃任務每分鐘訪問我的vultr伺服器上的nginx服務(curl命令),nginx可以記錄來訪的ip,我就知道該樹莓派的動態ip了。所以有時候訪問不了了,ip變化了,我就看一下nginx日誌後去阿里雲手動修改dns解析。

以上的操作還是略麻煩的,後來百度下,得知阿里雲dns有sdk,直接用指令碼就能修改dns解析記錄了。該方法比我原來手動的省事很多,而且能根據計劃每分鐘檢查,所以可以說就算電信ip一天變一次也感覺不到。

下面記錄如何設定的,安裝配置sdk就不說了,github都有,應該不會出問題。獲取阿里雲的授權碼也百度下即可,這裡不說。下面是指令碼內容(參考:http://zhangzr.com/2017/09/01/aliyunddns/):

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
 
import json
import os
import re
import sys
from datetime import datetime
 
from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest, DescribeDomainRecordsRequest, \
    DescribeDomainRecordInfoRequest
from aliyunsdkcore import client
 
#請填寫你的Access Key ID
access_key_id = "LTAIdR"
 
#請填寫你的Access Key Secret
access_key_secret = "lv535M"
 
#如果選擇yes,則執行程式後僅現實域名資訊,並不會更新記錄,用於獲取解析記錄ID。
#如果選擇no,則執行程式後不顯示域名資訊,僅更新記錄
#i_dont_know_record_id = 'yes'
i_dont_know_record_id = 'no'

#請填寫解析記錄ID
rc_record_id = '3995858176'
 
#請填寫你的一級域名
rc_domain = 'beavermagic.com'
 
#請填寫你的解析記錄,對應的主機記錄
rc_rr = 'server'
 
#請填寫你的記錄型別,DDNS請填寫A,表示A記錄
rc_type = 'A'
 
#請填寫解析有效生存時間TTL,單位:秒
#rc_ttl = '1'
rc_ttl = '600'
 
#請填寫返還內容格式,json,xml
rc_format = 'json'
 
 
def my_ip():
    get_ip_method = os.popen('curl -s ip.cn')
    get_ip_responses = get_ip_method.readlines()[0]
    get_ip_pattern = re.compile(r'\d+\.\d+\.\d+\.\d+')
    get_ip_value = get_ip_pattern.findall(get_ip_responses)[0]
    return get_ip_value
 
 
def check_records(dns_domain):
    clt = client.AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
    request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
    request.set_DomainName(dns_domain)
    request.set_accept_format(rc_format)
    #result = clt.do_action(request)
    result = clt.do_action_with_exception(request)
    return result
 
 
def old_ip():
    clt = client.AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
    request = DescribeDomainRecordInfoRequest.DescribeDomainRecordInfoRequest()
    request.set_RecordId(rc_record_id)
    request.set_accept_format(rc_format)
    #result = clt.do_action(request)
    result = clt.do_action_with_exception(request)
    result = json.JSONDecoder().decode(result)
    result = result['Value']
    return result
 
 
def update_dns(dns_rr, dns_type, dns_value, dns_record_id, dns_ttl, dns_format):
    clt = client.AcsClient(access_key_id, access_key_secret, 'cn-hangzhou')
    request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
    request.set_RR(dns_rr)
    request.set_Type(dns_type)
    request.set_Value(dns_value)
    request.set_RecordId(dns_record_id)
    request.set_TTL(dns_ttl)
    request.set_accept_format(dns_format)
    #result = clt.do_action(request)
    result = clt.do_action_with_exception(request)
    return result
 
def write_to_file():
    time_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    #current_script_path = sys.path[7]
    current_script_path = sys.path[0]
    print current_script_path
    log_file = current_script_path + '/' + 'aliyun_ddns_log.txt'
    write = open(log_file, 'a')
    write.write(time_now + ' ' + str(rc_value_old) + '--->' + str(rc_value) + '\n')
    write.close()
    return
 
if i_dont_know_record_id == 'yes':
    pass
    #print check_records(rc_domain)
elif i_dont_know_record_id == 'no':
    rc_value = my_ip()
    rc_value_old = old_ip()
    if rc_value_old == rc_value:
        pass
        #print 'The specified value of parameter Value is the same as old'
    else:
        #print update_dns(rc_rr, rc_type, rc_value, rc_record_id, rc_ttl, rc_format)
        update_dns(rc_rr, rc_type, rc_value, rc_record_id, rc_ttl, rc_format)
        write_to_file()

這裡rc_domain = 'beavermagic.com'是一級域名,rc_rr = 'server'是對應的二級域名,如我這裡二者組合就是server.beavermagic.com。剛開始不知道record id,所以設定為yes,然後獲取到後將其改為no。

程式有時候報異常,如後去ip失敗陣列越界,或者修改了記錄寫日誌,這樣會導致Linux上自己收到郵件,比較煩。那麼就將其輸出重定向即可,我的crontab設定如下:

* * * * * /home/ssss/bin/ddns_pi.py >> /tmp/ddns_output.txt 2>&1

看一下它修改dns記錄成功的截圖: