惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
O
OpenAI News
V
V2EX
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - Franky
Security Latest
Security Latest
S
SegmentFault 最新的问题
Project Zero
Project Zero
Spread Privacy
Spread Privacy
K
Kaspersky official blog
J
Java Code Geeks
V
Vulnerabilities – Threatpost
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
Scott Helme
Scott Helme
WordPress大学
WordPress大学
量子位
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Simon Willison's Weblog
Simon Willison's Weblog
S
Secure Thoughts
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
Visual Studio Blog
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
腾讯CDC
Cyberwarzone
Cyberwarzone
IT之家
IT之家
GbyAI
GbyAI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
D
Docker

K.I.S.S

身在 Kimi 的 800 天 写在 Kimi K2 发布之后:再也不仅仅是 ChatBot macOS 按域名切换 DNS 解析 | K.I.S.S 为什么说 GPT 是无损压缩 | K.I.S.S 握着你的手训一个类GPT语言模型 (二) | K.I.S.S 握着你的手训一个类GPT语言模型 (一) | K.I.S.S Rosetta in Linux Virtual Machine on Apple Silicon Fit an Overfit with MegEngine 把 CUPS 扔进 docker 里 ASUS Chromebook Flip | K.I.S.S GPG 与 SSH Agent 转发 使用 dnsmasq 和 ipset 的策略路由 YubiKey 4 简介与配置 | K.I.S.S 定制GH60机械键盘 | K.I.S.S Debian 网络安装内核参数 | K.I.S.S 我的 Vim 配置 | K.I.S.S Libinput 与 Udev | K.I.S.S 给妹子看的 Arch Linux 桌面日常安装 | K.I.S.S 修复GTK3 CSD外观 | K.I.S.S 握着你的手教你画哀女王 | K.I.S.S R.I.P Google Reader | K.I.S.S Richard Stallman仍然是对的 | K.I.S.S Scala 自定义控制结构 | K.I.S.S 入手Wacom Bamboo CTL470 | K.I.S.S 转个型? | K.I.S.S Wish List | K.I.S.S pulseaudio音量问题 | K.I.S.S 入手yubikey,一点小心得 | K.I.S.S 迁移到Octopress | K.I.S.S Linux 用作 IPv6 网关 | K.I.S.S Conky从豆瓣获取MPD专辑封面 | K.I.S.S 我和Linus大学时那些事儿 | K.I.S.S Micro$oft依然是那副老德行 | K.I.S.S 用PulseAudio TCP Forwarding实现网络传声 | K.I.S.S 利用tmpfs加速gnome-shell overview模式Applications索引 | K.I.S.S 新的短网址 | K.I.S.S 紧张的一个月 | K.I.S.S 5月11日活动有感 | K.I.S.S 西电开源社区2011年Tee 最终版 | K.I.S.S 多头多尾的Linux | K.I.S.S Linux的中文名称怎么翻译呢? | K.I.S.S iPhone使用OpenVPN | K.I.S.S 我的人人网敏感词 | K.I.S.S 纪念钱立生老师 | K.I.S.S twitter键盘控:Twittperator | K.I.S.S 天生的暴力倾向? | K.I.S.S The Open Source Spirit | K.I.S.S Libreoffice | K.I.S.S Hello world! | K.I.S.S Python 调用gnuplot的例子 | K.I.S.S The Beginning | K.I.S.S About Me | K.I.S.S
自动更新DNSPod记录 | K.I.S.S
2012-02-23 · via K.I.S.S

今天将社区和个人的转移到了dnspod,原因是dnspod 提供免费的智能解析(电信、教育网什么的可以制定不同的IP地址),并且有丰富的API,可以用脚本更新记录,于是我就fork了dnspod官方的python脚本,写了个动态更新DNS记录的脚本。

比花生壳强大多啦!!!!

#!/usr/bin/env python2
# -*- coding:utf8 -*-

import httplib, urllib
import socket
import argparse
import time
import fcntl
import struct
from xml.etree import ElementTree
from getpass import getpass

DEBUG = False
params = dict(
    login_email="", # replace with your email
    login_password="", # replace with your password
    format="json",
    domain_id=None, # replace with your domain_od, can get it by API Domain.List
    record_id=None, # replace with your record_id, can get it by API Record.List
    record_type='A', # replace with your record_id, can get it by API Record.List
    sub_domain="", # replace with your sub_domain
    record_line="默认",
)

def ddns(ip):
    params.update(dict(value=ip))
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
    conn = httplib.HTTPSConnection("dnsapi.cn")
    conn.request("POST", "/Record.Modify", urllib.urlencode(params), headers)
    
    response = conn.getresponse()
    if DEBUG: print response.status, response.reason
    data = response.read()
    if DEBUG: print data
    conn.close()
    return response.status == 200

def get_domain_id(domain_name):
    keys = ["login_email", "login_password"]
    _param = { k:v for k,v in params.iteritems() if k in keys }

    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
    conn = httplib.HTTPSConnection("dnsapi.cn")
    conn.request("POST", "/Domain.list", urllib.urlencode(_param), headers)
    response = conn.getresponse()
    id = None
    etree = ElementTree.parse(response)
    for domain in  etree.findall("domains/item"):
        if domain.find("name").text == domain_name:
            id = domain.find("id").text          
    conn.close()
    if id:
        return id
    else:
        raise Exception("Record '"+domain_name+"' not found!")

def get_record_id():
    keys = ["login_email", "login_password", "domain_id"]
    _param = { k:v for k,v in params.iteritems() if k in keys }
    subdomain = params["sub_domain"]
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
    conn = httplib.HTTPSConnection("dnsapi.cn")
    conn.request("POST", "/Record.List", urllib.urlencode(_param), headers)
    response = conn.getresponse()
    etree = ElementTree.parse(response)
    id = None
    for record in  etree.findall("records/item"):
        if record.find("name").text == subdomain:
            if DEBUG: print "Found", record.find("name").text
            if id:
                raise Exception("Multipule records of '"+subdomain+"' found. Please specify record id! ")
            id = record.find("id").text
    conn.close()
    if id:
        return id
    else:
        raise Exception("Record '"+subdomain+"' not found!")

def get_current_ip():
    """get current ip of """
    keys = ["login_email", "login_password", "domain_id"]
    record_id = params['record_id']
    _param = { k:v for k,v in params.iteritems() if k in keys }
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
    conn = httplib.HTTPSConnection("dnsapi.cn")
    conn.request("POST", "/Record.List", urllib.urlencode(_param), headers)
    response = conn.getresponse()
    etree = ElementTree.parse(response)
    cur_ip = None
    for record in  etree.findall("records/item"):
        if record.find("id").text == record_id:
            cur_ip = record.find("value").text
    conn.close()
    return cur_ip

def get_public_ip():
    """ get ip address from dnspod """
    if DEBUG: print "getting ip address from dnspod..."
    sock = socket.create_connection(('ns1.dnspod.net', 6666))
    ip = sock.recv(16)
    sock.close()
    return ip

def get_if_ip(ifname):
    """Get ip address by interface, Linux ONLY"""
    if DEBUG: print "getting ip address of", ifname
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
            )[20:24])

def parse_arg():
    parser = argparse.ArgumentParser(description="Update dns record on dnspod dynamically.")
    parser.add_argument( '-I', '--interval', help="Set test interval, default is 300 seconds." )
    parser.add_argument( '-i', '--interface', help="Set interface." )
    parser.add_argument( '-u','--username', help="Set login email." )
    parser.add_argument( '-p','--password', help="Set login password." )
    parser.add_argument( '-d','--domain', help="Set domain name." )
    parser.add_argument( '-s','-r','--subdomain', help="Set subdomain/record name." )
    parser.add_argument( '--domain-id', help="Set domain id." )
    parser.add_argument( '--record-id', help="Set record id." )
    parser.add_argument( '--debug',action="store_true", help="Show debug outputs." )
    return parser.parse_args()

if __name__ == '__main__':
    
    args = parse_arg()
    
    # confiure
    DEBUG = args.debug or False
    interval = args.interval or 300

    #Set domain name
    domain = args.domain or raw_input("Domain name: ")
    params['sub_domain'] = params['sub_domain'] \
            or args.subdomain or raw_input("Subomain: ") or "@"
    
    #Login info
    params['login_email'] = params['login_email'] \
            or args.username or raw_input("E-mail: ")
    params['login_password'] = params['login_password'] \
            or args.password or getpass()
    
    #domain and record id
    params['domain_id'] = params['domain_id'] \
            or args.domain_id or get_domain_id(domain)
    params['record_id'] = params['record_id']  \
            or args.record_id or get_record_id()
    
    print params
    if args.interface:
        getip = lambda : get_if_ip(args.interface)
    else:
        getip = lambda : get_public_ip()

    if DEBUG:
        print "domain_name: ", params['sub_domain']+'.'+domain
        print "domain id:", params['domain_id']
        print "record id:", params['record_id']
        print "interval: ", interval
    
    current_ip = get_current_ip()
    while True:
        try:
            ip = getip()
            if DEBUG: print "ip:", ip
            if DEBUG: print "record ip:", current_ip
            if current_ip != ip:
                if ddns(ip):
                    current_ip = ip
        except Exception, e:
            print e
            pass
        time.sleep(interval)

以后可能会常更新,新的代码会放在 github 上。

另有一份增强版,可以读却配置文件,支持更新多个域名,当然代码行数也多了… 放在 这里

要求是python2.7,python2.7以下版本(如在centos上)需要单独安装argparse模块

参数说明: ./dnspod.py -h

  -I INTERVAL, --interval INTERVAL
                        心跳时间,默认为5分钟
  -i INTERFACE, --interface INTERFACE
                        指定网络接口,不指定则会请求公共IP
  -u USERNAME, --username USERNAME
                        登陆的email,不指定则交互输入
  -p PASSWORD, --password PASSWORD
                        密码,不指定则交互输入
  -d DOMAIN, --domain DOMAIN
                        主域名,不指定则交互输入
  -s SUBDOMAIN, -r SUBDOMAIN, --subdomain SUBDOMAIN
                        子域,不指定则交互输入
  --domain-id DOMAIN_ID
                        主域ID,可选
  --record-id RECORD_ID
                        子域ID,由于一个子域可以有多条记录,这种情况必须指定,否则可选
  --debug               显示debug信息

例如: ./dnspod.py –debug -d bigeagle.me -s home -u xxx@gmail.com

则会更新home.bigeagle.me的记录