准备
一个域名,一台vps
本文中均为阿里云购买的域名和云服务器ECS
域名: saltor.icu
vps ip: 100.100.100.100
开始
添加dns解析
在云解析DNS处添加一条A记录和一条NS记录,如图所示
放行53端口
在云服务器ECS安全组规则里添加放行53端口的规则,协议是udp
dnslog代码
dnslog.py
运行在python2下,无需安装依赖包
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import SocketServer
import struct
import socket as socketlib
# DNS Query
class SinDNSQuery:
def __init__(self, data):
i = 1
self.name = ''
while True:
d = ord(data[i])
if d == 0:
break;
if d < 32:
self.name = self.name + '.'
else:
self.name = self.name + chr(d)
i = i + 1
self.querybytes = data[0:i + 1]
(self.type, self.classify) = struct.unpack('>HH', data[i + 1:i + 5])
self.len = i + 5
def getbytes(self):
return self.querybytes + struct.pack('>HH', self.type, self.classify)
# DNS Answer RRS
class SinDNSAnswer:
def __init__(self, ip):
self.name = 49164
self.type = 1
self.classify = 1
self.timetolive = 190
self.datalength = 4
self.ip = ip
def getbytes(self):
res = struct.pack('>HHHLH', self.name, self.type, self.classify, self.timetolive, self.datalength)
s = self.ip.split('.')
res = res + struct.pack('BBBB', int(s[0]), int(s[1]), int(s[2]), int(s[3]))
return res
# DNS frame
class SinDNSFrame:
def __init__(self, data):
(self.id, self.flags, self.quests, self.answers, self.author, self.addition) = struct.unpack('>HHHHHH', data[0:12])
self.query = SinDNSQuery(data[12:])
def getname(self):
return self.query.name
def setip(self, ip):
self.answer = SinDNSAnswer(ip)
self.answers = 1
self.flags = 33152
def getbytes(self):
res = struct.pack('>HHHHHH', self.id, self.flags, self.quests, self.answers, self.author, self.addition)
res = res + self.query.getbytes()
if self.answers != 0:
res = res + self.answer.getbytes()
return res
# A UDPHandler to handle DNS query
class SinDNSUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
dns = SinDNSFrame(data)
socket = self.request[1]
namemap = SinDNSServer.namemap
if(dns.query.type==1):
# If this is query a A record, then response it
name = dns.getname();
toip = namemap['*']
dns.setip(toip)
print '%s: %s-->%s'%(self.client_address[0], name, toip)
socket.sendto(dns.getbytes(), self.client_address)
else:
# If this is not query a A record, ignore it
socket.sendto(data, self.client_address)
# DNS Server
class SinDNSServer:
def __init__(self, port=53):
SinDNSServer.namemap = {}
self.port = port
def addname(self, name, ip):
SinDNSServer.namemap[name] = ip
def start(self):
HOST, PORT = "0.0.0.0", self.port
server = SocketServer.UDPServer((HOST, PORT), SinDNSUDPHandler)
server.serve_forever()
if __name__ == "__main__":
sev = SinDNSServer()
sev.addname('*', '127.0.0.1') # default address
sev.start() # start DNS server
在vps上直接运行dnslog.py,一个简易的dnslog平台就搭起来了
看下效果
WEB界面
使用tornado框架写一个web界面,为什么用tornado,代码量少啊emmmm
项目已上传至github: https://github.com/sa1tor/dnslog
pip安装tornado之后直接运行server.py即可
pip install tornado
python server.py
默认在8000端口,浏览器访问http://ip:8000/ 即可看到web界面
我指定了6002端口,python server.py --port=6002
界面比较简单,就3个按钮,getsubdomain获取随机子域名,refresh刷新页面,delete all删除所有记录
后记
吐槽一下搭建过程中遇到的坑
- 只要一个域名!!!!!!
- 修改dns解析时是在云dns解析处直接添加一条NS记录,而不是在域名管理那里修改dns服务器
- 放行53端口时,在添加安全规则处选择协议类型为自定义UDP,而不是自定义TCP,我还一度以为代码有问题emmmm
声明
本文所述方法截止本文发出时是可行的。如有问题,欢迎提出。