前言
之前一直想基于家中的宽带写一点对外提供服务的项目,比如私有网盘啊之类的,但是本地宽带服务商一直不给开公网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 的密钥。
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成功...')
可以看到代码里进行了两次请求,第一个请求是通过传递域名,拿到了zone_identifier和identifier,可以理解为是域名记录ID
修改域名解析,不是通过传递域名操作,而是ID,这样应该也是为了保证安全性
因为cloudflare的api是按照restful来的,所以直接判断状态码即可知道操作是否成功完成。
最后我们使用apscheduler搞个定时服务,1小时更新一次,自建的DDNS就算完工了,当然这样不具有实时性,可以修改代码实现实时动态解析
动态修改解析后,访问域名即可访问到我们的本机服务,图为本机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()
Python版权声明:如无特殊说明,文章均为本站原创,转载请注明出处
本文链接:https://www.yangyingqi.com/57.html