Skip to content

Instantly share code, notes, and snippets.

Forked from chuangbo/
Last active August 30, 2022 13:41
Show Gist options
  • Save billryan/239778f0821937939c8c140bdddd6840 to your computer and use it in GitHub Desktop.
Save billryan/239778f0821937939c8c140bdddd6840 to your computer and use it in GitHub Desktop.
DNSPod DDNS Python Script

替换上你的ID, Token, domain, sub_domain 就可以运行了。(ID,Token) 可以从 API 鉴权方式升级为 Token 获得。 脚本会在后台一直运行,初始化时会根据 sub_domain 查询是否已经创建,每隔30秒检查一遍IP,如果修改了就更新IP。

以 Archlinux 为例,按照如下步骤操作即可设置开机启动这个 DDNS 服务。

sudo wget -O /usr/local/bin/
sudo chmod +x /usr/local/bin/
sudo wget -O /etc/systemd/system/
sudo systemctl start dnspod-ddns
sudo systemctl enable dnspod-ddns


Description=DNSPod DDNS Service
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import requests
import time
import logging
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']
logger.error('!!!can not get record_id!!!')
return -1
params['record_id'] = record_id
current_ip = remote_ip
while True:
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:"IP remains %s" % public_ip)
except Exception as e:
def get_public_ip(self):
"""Get public ip via dnspod."""
sock = socket.create_connection(('', 6666), timeout=30)
ip = sock.recv(16)
return ip.decode('utf-8')
def get_record_list(self, params):
"""Get record list.
:return: dict of code, record_id and IP value
record_list_url = ''
r =, 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.
:return: record_id of new record
params['value'] = ip
record_create_url = ''
r =, 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.
params['value'] = ip
ddns_url = ''
r =, data=params)'status: %s, reason: %s' % (r.status_code, r.reason))
return r.json()['status']['code'] == '1'
def main():
# initialize params
# Use Token, check
ID = '23333' # replace with your ID
Token = '233333333333333333333333' # replace with your Token
params = dict(
login_token=("%s,%s" % (ID, Token)),
domain='', # replace with your domain
sub_domain='test', # replace with your sub_domain
dnspod = DNSPod(params)
if __name__ == "__main__":
Copy link

readme 有手误,
sudo wget -O /etc/systemd/system/
sudo wget -O /etc/systemd/system/dnspod-ddns.service

Copy link

rankun203 commented Aug 30, 2022

If your get_public_ip also failed, try to replace it with this:

    def get_public_ip(self):
        """Get public ip via dnspod."""
        res = requests.get("")
        matches ='(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', res.text)
        ip =
        return ip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment