|
#!/usr/bin/env python |
|
# -*- coding:utf-8 -*- |
|
|
|
|
|
import socket |
|
import requests |
|
import time |
|
import logging |
|
|
|
logging.basicConfig(level=logging.WARNING) |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
class DNSPod(object): |
|
"""DNSPod ddns application.""" |
|
|
|
def __init__(self, params): |
|
"""Initialize with params.""" |
|
self._params = params |
|
|
|
def run(self, params=None): |
|
if params is None: |
|
params = self._params |
|
public_ip = self.get_public_ip() |
|
# get record_id of sub_domain |
|
record_list = self.get_record_list(params) |
|
if record_list['code'] == '10': |
|
# create record for empty sub_domain |
|
record_id = self.create_record(params, public_ip) |
|
remote_ip = public_ip |
|
elif record_list['code'] == '1': |
|
# get record id |
|
record_id = record_list['record_id'] |
|
remote_ip = record_list['ip_value'] |
|
else: |
|
logger.error('!!!can not get record_id!!!') |
|
return -1 |
|
params['record_id'] = record_id |
|
|
|
current_ip = remote_ip |
|
while True: |
|
try: |
|
public_ip = self.get_public_ip() |
|
if current_ip != public_ip: |
|
logger.warning("update IP from %s to %s" % (current_ip, public_ip)) |
|
if self.ddns(params, public_ip): |
|
current_ip = public_ip |
|
else: |
|
logger.info("IP remains %s" % public_ip) |
|
except Exception as e: |
|
logger.error(e) |
|
pass |
|
time.sleep(30) |
|
|
|
def get_public_ip(self): |
|
"""Get public ip via dnspod.""" |
|
sock = socket.create_connection(('ns1.dnspod.net', 6666), timeout=30) |
|
ip = sock.recv(16) |
|
sock.close() |
|
return ip.decode('utf-8') |
|
|
|
def get_record_list(self, params): |
|
"""Get record list. |
|
|
|
https://www.dnspod.cn/docs/records.html#record-list |
|
:return: dict of code, record_id and IP value |
|
""" |
|
record_list_url = 'https://dnsapi.cn/Record.List' |
|
r = requests.post(record_list_url, data=params) |
|
code = r.json()['status']['code'] |
|
record_id = r.json()['records'][0]['id'] if code == '1' else "" |
|
ip_value = r.json()['records'][0]['value'] if code == '1' else "" |
|
return dict(code=code, record_id=record_id, ip_value=ip_value) |
|
|
|
def create_record(self, params, ip): |
|
"""Create record if not created before. |
|
|
|
https://www.dnspod.cn/docs/records.html#record-create |
|
:return: record_id of new record |
|
""" |
|
params['value'] = ip |
|
record_create_url = 'https://dnsapi.cn/Record.Create' |
|
r = requests.post(record_create_url, data=params) |
|
logger.warning('create new record %s.%s with IP %s' % (params['sub_domain'], params['domain'], ip)) |
|
assert r.json()['status']['code'] == '1' |
|
record_id = r.json()['record']['id'] |
|
return record_id |
|
|
|
def ddns(self, params, ip): |
|
"""Update ddns ip. |
|
|
|
https://www.dnspod.cn/docs/records.html#dns |
|
""" |
|
params['value'] = ip |
|
ddns_url = 'https://dnsapi.cn/Record.Ddns' |
|
r = requests.post(ddns_url, data=params) |
|
logger.info('status: %s, reason: %s' % (r.status_code, r.reason)) |
|
return r.json()['status']['code'] == '1' |
|
|
|
|
|
def main(): |
|
# initialize params |
|
# Use Token, check https://support.dnspod.cn/Kb/showarticle/tsid/227 |
|
ID = '23333' # replace with your ID |
|
Token = '233333333333333333333333' # replace with your Token |
|
params = dict( |
|
login_token=("%s,%s" % (ID, Token)), |
|
format='json', |
|
domain='example.com', # replace with your domain |
|
sub_domain='test', # replace with your sub_domain |
|
record_type='A', |
|
record_line='默认' |
|
) |
|
|
|
dnspod = DNSPod(params) |
|
dnspod.run() |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |
readme 有手误,
sudo wget -O /etc/systemd/system/dnspod-ddns.py.service https://gist.github.com/billryan/239778f0821937939c8c140bdddd6840/raw/dnspod-ddns.service
应为
sudo wget -O /etc/systemd/system/dnspod-ddns.service https://gist.github.com/billryan/239778f0821937939c8c140bdddd6840/raw/dnspod-ddns.service