python 动态dns
因为某些需要,需要访问家里的服务器,但家里联通网络的外网ip一直在换。所以需要动态dns。
1、获取主机外网的真实IP地址。
www.trackip.net这个网站可以返回IP,很方便。
import requests
url = r'http://www.trackip.net/ip'
r = requests.get(url)
txt = r.text
但是出现一个问题,就是联通很良心的支持了IP6,我访问后返回的是IP6的地址。肯定还有其他的方式,但我记得可以这样:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('www.trackip.net',80))
s.send(b'GET /ip HTTP/1.1\r\nHost: www.trackip.net\r\nConnection: close\r\n\r\n')
buffer = []
while True:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
data = b''.join(buffer)
s.close()
header,ip = data.split(b'\r\n\r\n',1)
return ip.decode('utf-8')
except:
return False
2、域名提供商一般都提供了API 我有一个域名是godaddy的,网上有一段代码抄过来
# coding=utf-8
import getip
import urllib.request
import json
def update_NS(ip):
#获得的自己的外网IP
ip_addr = ip
#定义http请求头
api_url = 'https://api.godaddy.com/v1/domains/yourdomainname/records'
head = {}
#定义服务器返回json数据给我们
head['Accept'] = 'application/json'
#定义我们发送的数据为json
head['Content-Type'] = 'application/json'
#定义身份认证信息
head['Authorization'] = 'sso-key yourKEY :yourSECRET_KEY'
#根据需要改下面的内容
records_a = {"data" : ip_addr,"name" : "yoursecondarydomain","ttl" : 600,"type" : 'A',}
#下面这两项好像和自己域名管理中的域名服务器有关
records_NS01 = {"data" : "ns05.domaincontrol.com","name" : "@","ttl" : 3600,"type" : "NS",}
records_NS02 = {
"data" : "ns06.domaincontrol.com","name" : "@","ttl" : 3600,"type" : "NS",}
put_data = [records_a,records_NS01,records_NS02]
try:
#定义请求,包含请求地址,请求头,请求方式,并把put_data从json转换为字符串格式,再转换成bytes
req = urllib.request.Request(api_url,headers = head,data = json.dumps(put_data).encode(),method = "PUT")
rsp = urllib.request.urlopen(req)
#根据官方文档我们只需要知道服务器返回码即可,200为成功,这里获取服务器的返回码
code = rsp.getcode()
#判断是否成功
if code == 200:
print('成功更改域名解析:'+ip_addr)
else:
print('更改失败!')
#如果有问题
except:
print('错误!')
if __name__ == '__main__':
update_NS(ip)
3、检测ip是否变化,如果改变了就更改解析记录
# coding=utf-8
import getip
import dnsip
def chgip():
newip = getip.get_inet4_ip()
if newip:
with open('oldip.log','r') as fo:
oldip = fo.read()
else:
return
if oldip == newip:
return
else:
with open('oldip.log','w') as fo1:
fo1.write(newip)
dnsip.update_NS(newip)
if __name__ == '__main__':
chgip()
4、然后设置crontab 10分钟运行一次
crontab -e
*/10 * * * * yourcommand
很多内容来自网络,不管怎样,功能实现了,iperf测试了一下,也有1m的带宽。