準備
一個域名,一臺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
聲明
本文所述方法截止本文發出時是可行的。如有問題,歡迎提出。
我是可愛的分割線
2020-04-13 15:22:33
我知道爲什麼網上的文章都用兩個域名了,今天測試了下,確實可以。一個域名修改dns服務器,一個域名添加NS記錄,所以是兩個域名。之前測試的時候一直抽風,大寫的尷尬,但是其實只要一個域名就能搞定的事情emmm…