我找到了如何在YouTube上创建自己的dns服务器的指南。但是我需要您的帮助来创建IP地址黑名单,因此,如果有人想访问被禁的IP地址,他们将重定向到特定的IP地址,例如localhost。
在代码下方,并在指南视频上链接。
import socket, glob, json
port = 53
ip = '127.0.0.1'
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((ip, port))
def load_zones():
jsonzone = {}
zonefiles = glob.glob('zones/*.zone')
for zone in zonefiles:
with open(zone) as zonedata:
data = json.load(zonedata)
zonename = data["$origin"]
jsonzone[zonename] = data
return jsonzone
zonedata = load_zones()
def getflags(flags):
byte1 = bytes(flags[:1])
byte2 = bytes(flags[1:2])
rflags = ''
QR = '1'
OPCODE = ''
for bit in range(1,5):
OPCODE += str(ord(byte1)&(1<<bit))
AA = '1'
TC = '0'
RD = '0'
# Byte 2
RA = '0'
Z = '000'
RCODE = '0000'
return int(QR+OPCODE+AA+TC+RD, 2).to_bytes(1, byteorder='big')+int(RA+Z+RCODE, 2).to_bytes(1, byteorder='big')
def getquestiondomain(data):
state = 0
expectedlength = 0
domainstring = ''
domainparts = []
x = 0
y = 0
for byte in data:
if state == 1:
if byte != 0:
domainstring += chr(byte)
x += 1
if x == expectedlength:
domainparts.append(domainstring)
domainstring = ''
state = 0
x = 0
if byte == 0:
domainparts.append(domainstring)
break
else:
state = 1
expectedlength = byte
y += 1
questiontype = data[y:y+2]
return (domainparts, questiontype)
def getzone(domain):
global zonedata
zone_name = '.'.join(domain)
return zonedata[zone_name]
def getrecs(data):
domain, questiontype = getquestiondomain(data)
qt = ''
if questiontype == b'\x00\x01':
qt = 'a'
zone = getzone(domain)
return (zone[qt], qt, domain)
def buildquestion(domainname, rectype):
qbytes = b''
for part in domainname:
length = len(part)
qbytes += bytes([length])
for char in part:
qbytes += ord(char).to_bytes(1, byteorder='big')
if rectype == 'a':
qbytes += (1).to_bytes(2, byteorder='big')
qbytes += (1).to_bytes(2, byteorder='big')
return qbytes
def rectobytes(domainname, rectype, recttl, recval):
rbytes = b'\xc0\x0c'
if rectype == 'a':
rbytes = rbytes + bytes([0]) + bytes([1])
rbytes = rbytes + bytes([0]) + bytes([1])
rbytes += int(recttl).to_bytes(4, byteorder='big')
if rectype == 'a':
rbytes = rbytes + bytes([0]) + bytes([4])
for part in recval.split('.'):
rbytes += bytes([int(part)])
return rbytes
def buildresponse(data):
# Transaction ID
TransactionID = data[:2]
# Get the flags
Flags = getflags(data[2:4])
# Question Count
QDCOUNT = b'\x00\x01'
# Answer Count
ANCOUNT = len(getrecs(data[12:])[0]).to_bytes(2, byteorder='big')
# Nameserver Count
NSCOUNT = (0).to_bytes(2, byteorder='big')
# Additonal Count
ARCOUNT = (0).to_bytes(2, byteorder='big')
dnsheader = TransactionID+Flags+QDCOUNT+ANCOUNT+NSCOUNT+ARCOUNT
# Create DNS body
dnsbody = b''
# Get answer for query
records, rectype, domainname = getrecs(data[12:])
dnsquestion = buildquestion(domainname, rectype)
for record in records:
dnsbody += rectobytes(domainname, rectype, record["ttl"], record["value"])
return dnsheader + dnsquestion + dnsbody
while 1:
data, addr = sock.recvfrom(512)
r = buildresponse(data)
sock.sendto(r, addr)
{
"$origin": "howcode.org.",
"$ttl": 3600,
"soa": {
"mname": "ns1.howcode.org.",
"rname": "admin.howcode.org.",
"serial": "{time}",
"refresh": 3600,
"retry": 600,
"expire": 604800,
"minimum": 86400
},
"ns": [
{ "host": "ns1.howcode.org." },
{ "host": "ns2.howcode.org." }
],
"a": [
{ "name": "@", "ttl": 400, "value": "255.255.255.255" },
{ "name": "@", "ttl": 400, "value": "127.0.0.1" },
{ "name": "@", "ttl": 400, "value": "127.0.0.1" },
{ "name": "@", "ttl": 400, "value": "127.0.0.1" },
{ "name": "@", "ttl": 400, "value": "10.10.10.10" }
]
}
https://www.youtube.com/watch?v=wuo_nWN4YJU&list=PLBOh8f9FoHHhvO5e5HF_6mYvtZegobYX2&index=9