dnslog平臺搭建從0到1

準備

一個域名,一臺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刪除所有記錄

後記

吐槽一下搭建過程中遇到的坑

  1. 只要一個域名!!!!!!
  2. 修改dns解析時是在雲dns解析處直接添加一條NS記錄,而不是在域名管理那裏修改dns服務器
    在這裏插入圖片描述
  3. 放行53端口時,在添加安全規則處選擇協議類型爲自定義UDP,而不是自定義TCP,我還一度以爲代碼有問題emmmm

聲明

本文所述方法截止本文發出時是可行的。如有問題,歡迎提出。


我是可愛的分割線

2020-04-13 15:22:33
我知道爲什麼網上的文章都用兩個域名了,今天測試了下,確實可以。一個域名修改dns服務器,一個域名添加NS記錄,所以是兩個域名。之前測試的時候一直抽風,大寫的尷尬,但是其實只要一個域名就能搞定的事情emmm…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章