lwzm
4/7/2016 - 8:37 AM

update dns when ssh tunnel reconnecting 利用 supervisord 的 event, 可以在某进程重新启动时, 触发另一段逻辑的运行. 在这里, 当 ssh tunnel 意外断开连接接着启动成功后, 会认为公网 IP 可能有变, 需

update dns when ssh tunnel reconnecting

利用 supervisord 的 event, 可以在某进程重新启动时, 触发另一段逻辑的运行.

在这里, 当 ssh tunnel 意外断开连接接着启动成功后, 会认为公网 IP 可能有变, 需要重新注册 dns 的数据

[program:ssh_tunnel]
command=ssh -C -N -R 22224:localhost:22 ali.tyio.net
redirect_stderr=true
stdout_logfile=log/%(program_name)s.log
startretries=1000

[eventlistener:update_dns]
command=./dns.py gpu tyio.net your-token
events=PROCESS_STATE_RUNNING
stderr_logfile=log/%(program_name)s.log
#!/usr/bin/env python3

import datetime
import sys
import requests


def update(sub_domain, domain_name, token):
    session = requests.Session()
    session.headers["User-Agent"] = "Py/3.5 (lwzm@qq.com)"

    #my_ip = session.get("http://httpbin.org/ip").json()["origin"]
    my_ip = session.get("http://ip.cip.cc").text.strip()

    data = {
        "format": "json",
        "login_token": token,
    }

    resp = session.post("https://dnsapi.cn/Domain.List", data)
    domains = resp.json()


    for domain in domains["domains"]:
        if domain["name"] == domain_name:
            data["domain_id"] = domain["id"]
            break
    else:  # for ... else ...
        raise ValueError(domains)



    resp = session.post("https://dnsapi.cn/Record.List", data)
    records = resp.json()


    for record in records["records"]:
        if record["name"] == sub_domain:
            data["record_id"] = record["id"]
            break
    else:  # for ... else ...
        raise ValueError(records)


    data.update({
        "sub_domain": sub_domain,
        "record_type": "A",
        "record_line": "默认",
        "value": my_ip,
        "ttl": 600,
    })


    resp = session.post("https://dnsapi.cn/Record.Modify", data)

    return resp.json()


if __name__ == "__main__":
    # gpu tyio.net your-token
    update(*sys.argv[1:])
#!/usr/bin/env python3

import datetime
import sys

import dnspod

def log(*args):
    print(datetime.datetime.now(), *args, file=sys.stderr, flush=True)


def to_dict(s):
    return dict(x.split(':') for x in s.split())


def main():
    sub, name, token = sys.argv[1:]

    while True:
        print("READY")

        # read header line and print it to stderr
        line = input()
        log(line.strip())#, to_dict(line))

        # read event payload and print it to stderr
        headers = to_dict(line)
        data = sys.stdin.read(int(headers["len"]))
        log(data.strip())

        processname = to_dict(data)["processname"]
        # transition from READY to ACKNOWLEDGED
        try:
            if processname.startswith("ssh"):
                log(dnspod.update(sub, name, token))
            print("RESULT 2\nOK", end="")
        except Exception as e:
            log(e)
            print("RESULT 4\nFAIL", end="")


if __name__ == '__main__':
    main()