使用Python实现动态域名解析

2022年2月9日 00:16 阅读 4.91k 评论 0

前言

之前一直想基于家中的宽带写一点对外提供服务的项目,比如私有网盘啊之类的,但是本地宽带服务商一直不给开公网IP,找客服也只是模板式的回复,所以计划一直搁浅。

新发现

但是我最近发现分配的IPV6是可以公网访问的,而且没有封80端口,这可给我乐坏了。

我兴致勃勃地启动了几个web项目,均正常访问,这tm不比内网穿透香?然而,新问题来了,IPV6不是一成不变的,每隔一段时间就会变化,这无疑是给我泼了一盆冷水。

一开始我的想法是,使用server酱等推送工具不断的推送本机的IPV6地址给我,我通过最新的IPV6地址去访问,可行,但是太麻烦,懒癌晚期患者。。。

过了几天,我灵机一动,DDNS不就可以实现这个功能么,家中路由器以及设备不支持,我可以自己实现啊,想到这里,我直接从床上蹦了起来,手里的王者突然不香了,开干!

获取本机IP地址

要实现DDNS动态解析,第一步肯定是获取本机的IP,这个简单,直接ipconfig,然后从里面拿ip就完事,代码也很简单

def get_local_ip(): 
    ipv4 = None 
    ipv6 = None 
    for line in os.popen('ipconfig'): 
        if 'IPv4' in line: 
            ipv4 = line.split(':')[1].strip() 
        elif '临时 IPv6' in line: 
            ipv6 = ':'.join(line.split(':')[1:]).strip() 

    return ipv4, ipv6 

函数返回ipv4和ipv6,家中有ipv4公网的同学,直接用IPV4即可

动态解析

我的一个备案域名是放在cloudflare的,所以我这里使用cloudflare做示范。

第一步,当然是阅读cloudflare的API文档啦 点击前往

说实话,虽然本人六级过了,说起来还有那么一点基础,但是这一大片英语看起来依然是头疼,好在关键词很好找,直接定位到update DNS record,按照页面提示即可完成。

在一切开始之前,我们需要前往cloudflare个人资料页面,查看我们的Global API Key,这个很重要,是用于访问 Cloudflare API 的密钥。

api_key

def update_dns_record(record_type, target_domain, record): 
    headers = { 
        'X-Auth-Email': EMAIL, 
        'X-Auth-Key': API_KEY 
    } 
    zone_url = 'https://api.cloudflare.com/client/v4/zones' 
    ret = requests.get(zone_url, headers=headers) 
    zone_id = ret.json()['result'][0]['id'] 
    record_url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type={record_type}&name={target_domain}' 
    ret = requests.get(record_url, headers=headers).json() 
    data = { 
        "type": record_type, 
        "name": target_domain, 
        "content": record, 
        "ttl": 1, 
        "proxied": False 
    } 
    update_url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{ret["result"][0]["id"]}' 
    ret = requests.put(update_url, headers=headers, json=data) 
    if ret.status_code == 200: 
        print('修改ip成功...') 

result

可以看到代码里进行了两次请求,第一个请求是通过传递域名,拿到了zone_identifier和identifier,可以理解为是域名记录ID

修改域名解析,不是通过传递域名操作,而是ID,这样应该也是为了保证安全性

因为cloudflare的api是按照restful来的,所以直接判断状态码即可知道操作是否成功完成。

最后我们使用apscheduler搞个定时服务,1小时更新一次,自建的DDNS就算完工了,当然这样不具有实时性,可以修改代码实现实时动态解析

动态修改解析后,访问域名即可访问到我们的本机服务,图为本机IIS默认页面

IIS

完整代码如下:

import requests 
import os 
from apscheduler.schedulers.blocking import BlockingScheduler 

EMAIL = ''  # cloudflare的邮箱 
API_KEY = ''  # cloudflare的Global API Key 


def get_local_ip(): 
    ipv4 = None 
    ipv6 = None 
    for line in os.popen('ipconfig'): 
        if 'IPv4' in line: 
            ipv4 = line.split(':')[1].strip() 
        elif '临时 IPv6' in line: 
            ipv6 = ':'.join(line.split(':')[1:]).strip() 

    return ipv4, ipv6 


def update_dns_record(record_type, target_domain, record): 
    headers = { 
        'X-Auth-Email': EMAIL, 
        'X-Auth-Key': API_KEY 
    } 
    zone_url = 'https://api.cloudflare.com/client/v4/zones' 
    ret = requests.get(zone_url, headers=headers) 
    zone_id = ret.json()['result'][0]['id'] 
    record_url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?type={record_type}&name={target_domain}' 
    ret = requests.get(record_url, headers=headers).json() 
    data = { 
        "type": record_type, 
        "name": target_domain, 
        "content": record, 
        "ttl": 1, 
        "proxied": False 
    } 
    update_url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{ret["result"][0]["id"]}' 
    ret = requests.put(update_url, headers=headers, json=data) 
    if ret.status_code == 200: 
        print('修改ip成功...') 


def main(): 
    print('开始运行...') 
    domain = ''  # 待解析的域名 
    record_type = 'AAAA'  # AAAA为ipv6,若要解析ipv4请使用A记录 
    ipv4, ipv6 = get_local_ip() 
    print('获取到的IP为:', ipv4, ipv6) 
    update_dns_record(record_type, domain, ipv6) 


if __name__ == '__main__': 
    main()  # 先调用一次,然后启动定时任务 
    sched = BlockingScheduler(timezone='MST') 
    sched.add_job(main, 'interval', id='update_dns_record_job', hours=1)  # 一小时更新一次 
    sched.start() 
最后修改于2022年3月4日 09:46
©允许规范转载

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://www.yangyingqi.com/57.html

Python
微信
支付宝
登录后即可进行评论/回复