DDNS No-IP自动更新IPv6地址的的Python脚本

DDNS No-IP自动更新IPv6地址的的Python脚本

目前No-IP的更新工具暂不支持更新ipv6,而我的公网ip来自手机热点,所以公网ip并非是固定的,有需要更新ip的需求。因此写了个脚本。参考官网的协议完成

官网协议地址:https://www.noip.com/integrate/request

源码供参考,如果有帮到您的话可以给一个赞吗:

import socket
import base64
import os
import re
import time

class netParam:
    def __init__(self):
        self.host = "dynupdate.no-ip.com"
        self.usrname = "[email protected]"
        self.passwd = "xxxxxxxxxxxxxxxx"
        self.domain = "xxxxxxxxxxx.ddns.net"
        self.timeval = 5 * 60
        self.server_port = 80

def getIPv6Address():
    output = os.popen("ipconfig /all").read()
    # print(output)
    result = re.findall(r"(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})", output, re.I)
    return result[0][0]

def getip(domain):
    address = socket.getaddrinfo(domain, 'http')
    return address[0][4][0]

if __name__ == "__main__":

    param = netParam()
    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 不经过WAIT_TIME,直接关闭
    tcp_sock.setblocking(False)                                     # 设置非阻塞编程
    tcp_sock.settimeout(1)
    link_statu = False
    send_data_len = 0
    old_ipv6addr = ""
    fisrt_flag = True

	# 按协议,对usrname:passwd进行base64编码
    raw_key = param.usrname + ":" + param.passwd
    print("raw key: " + raw_key)

    encode_key = base64.b64encode(raw_key.encode("utf-8"))
    encode_key = str(encode_key)[2:len(str(encode_key)) - 1]
    print("encode key: " + encode_key)

	#构造请求头部的内容,由于本机ip可能变化,因此这里没有直接把GET方法写进去,而是放在循环体中做
    requestParam = ""
    #requestParam += "GET /nic/update?hostname=" + param.domain + ""
    requestParam += "Host: dynupdate.no-ip.com\r\n"
    requestParam += "Authorization: Basic " + encode_key + "\r\n"
    requestParam += "User-Agent: None\r\n\r\n"
    print("request:\n" + requestParam)

    while(True):
    	# 每次运行等待timeval(此处是5分钟)的间隔,避免频繁更新
        if (True != fisrt_flag):
            time.sleep(param.timeval)

        fisrt_flag = False

		# 获取ipv6地址,若地址没有发生改变,则不上报更新
        ipv6addr = getIPv6Address()
        if ('2' != ipv6addr[0] or '4' != ipv6addr[1] or '0' != ipv6addr[2]):
            print("ipv6 addr invalid!")
            continue

        if (0 != len(ipv6addr)):
            print("ipv6 addr: " + ipv6addr)
            if (ipv6addr == old_ipv6addr):
                print("ip not change, continue")
                continue

		# 构造请求的头部GET方法内容
        requestHead = "GET "
        requestHead += "/nic/update?hostname=" + param.domain + "&myip=" + ipv6addr + " HTTP/1.1\r\n"

		# 建立tcp连接
        if (False == link_statu):
            server_ip = getip(param.host)
            print("server ip is :" + server_ip)

            try:
                tcp_sock.connect((server_ip, param.server_port))
                print("connect server success")
                link_statu = True
            except Exception as err:
                print("connect server failed, exception:", err)
                continue

		# 发送数据
        send_data = requestHead + requestParam
        send_data_len = 0

        while send_data_len < len(send_data):
            time.sleep(0.1)
            try:
                send_data_len += tcp_sock.send(send_data[send_data_len:].encode())
                print("send " + str(send_data_len) + " data")
            except Exception as err:
                print("send data error, exception: ", err)
                print("close tcp socket")
                tcp_sock.close()
                link_statu = False
                break

        if (send_data_len != len(send_data)):
            continue

        print("send data:" + send_data)
    
    	# 检查结果,更新成功则把当前ip记录为旧ip
        if (True == link_statu):
            try:
                recv_data = tcp_sock.recv(2048)
                print("server reply:\n" + str(recv_data))
            except Exception as err:
                print("recv data error, exception: ", err)
                tcp_sock.close()
                link_statu = False

        if (-1 != str(recv_data).find("HTTP/1.1 200 OK")):
            old_ipv6addr = ipv6addr
            print("update ip success")

    print("end")

你可能感兴趣的:(网络,python,开发语言,ip)