Skip to content

Commit

Permalink
add Dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Cuartin authored and Miguel Cuartin committed Feb 16, 2021
1 parent f8b542b commit 065c0b8
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 48 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
venv
venv
*.log
socket
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM python:3.8
WORKDIR /code
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src/ .
EXPOSE 53/tcp
EXPOSE 53/udp
CMD [ "python", "./dnproxy.py" ]
47 changes: 0 additions & 47 deletions dnproxy.py

This file was deleted.

Empty file removed dnproxy.yml
Empty file.
7 changes: 7 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ chardet==4.0.0
cryptography==3.4.5
dnspython==2.1.0
idna==2.10
lxml==4.6.2
pycparser==2.20
pyfiglet==0.8.post1
pytils==0.3
PyYAML==5.4.1
requests==2.25.1
requests-toolbelt==0.9.1
selectors==0.0.14
six==1.15.0
urllib3==1.26.3
user-agent==0.1.9
weblib==0.1.30
111 changes: 111 additions & 0 deletions src/dnproxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python3

import sys
import socket
import selectors
import types
import yaml
import logging
from dns import message, query
from pyfiglet import Figlet
import binascii
import time

# General config
f = Figlet(font='slant')

# Load Config
with open("dnproxy.yml", "r") as configfile:
cfg = yaml.load(configfile, Loader=yaml.FullLoader)

# create logger
logger = logging.getLogger('dnproxy')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - [%(levelname)s] - %(message)s ") # I am printing thread id here
ch.setFormatter(formatter)
logger.addHandler(ch)

# Init
logger.info(f.renderText('dnproxy'))

HOST = cfg['dnproxy']['host']
PORT = cfg['dnproxy']['port']
UPSTREAM_IP = cfg['upstream']['ip']
TLS_HOSTNAME = cfg['upstream']['hostname']

sel = selectors.DefaultSelector()

def receive_message(sock):
(wire, host) = sock.recvfrom(1024)
q = message.from_wire(wire)
logger.info(f'UDP Socket - Query ID: {q.id}, Question:{q.question}')
r = query.tls(q, UPSTREAM_IP, server_hostname=TLS_HOSTNAME)
logger.info(f'UDP Socket - Query ID: {q.id}, Answer: {r.answer}')
wire = r.to_wire()
sock.sendto(wire, host)

def accept_wrapper(sock):
conn, addr = sock.accept() # Should be ready to read
logger.debug(f"TCP Socket - Accepted connection from {addr[0]}:{addr[1]}")
conn.setblocking(False)
data = types.SimpleNamespace(addr=addr, inb=b"", outb=b"")
events = selectors.EVENT_READ | selectors.EVENT_WRITE
sel.register(conn, events, data=data)

def service_connection(key, mask):
sock = key.fileobj
data = key.data
if mask & selectors.EVENT_READ:
recv_data = sock.recv(1024)
if recv_data:
data.outb += recv_data
else:
logger.debug(f"TCP Socket - Closing connection to {data.addr[0]}:{data.addr[1]}")
sel.unregister(sock)
sock.close()
if mask & selectors.EVENT_WRITE:
if data.outb:
q = message.from_wire(data.outb[2:])
logger.info(f'TCP Socket - Question from {data.addr[0]}:{data.addr[1]}, Query ID: {q.id}, Question:{q.question}')
r = query.tls(q, UPSTREAM_IP, server_hostname=TLS_HOSTNAME)
logger.info(f'TCP Socket - Response to {data.addr[0]}:{data.addr[1]}, Query ID: {q.id}, Answer: {r.answer}')
wire = r.to_wire()
length = binascii.unhexlify("%04x" % len(wire))
if r:
sent = sock.send(length+wire)
data.outb = data.outb[sent:]


if __name__=="__main__":

# Sockets Creations

tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tsock.bind((HOST, PORT))
tsock.listen()
logger.info(f"TCP Socket - Listening on {HOST}:{PORT}")
tsock.setblocking(False)
sel.register(tsock, selectors.EVENT_READ, data=None)

usock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
usock.bind((HOST, PORT))
logger.info(f"UDP Socket - Listening on {HOST}:{PORT}")
sel.register(usock, selectors.EVENT_READ, data=None)

try:
while True:
events = sel.select(timeout=None)
for key, mask in events:
if key.data is None:
if key.fileobj.type == socket.SOCK_STREAM:
accept_wrapper(key.fileobj)
elif key.fileobj.type == socket.SOCK_DGRAM:
receive_message(key.fileobj)
else:
service_connection(key, mask)
except KeyboardInterrupt:
logger.info("Caught keyboard interrupt, exiting")
finally:
sel.close()
6 changes: 6 additions & 0 deletions src/dnproxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dnproxy:
host: "0.0.0.0"
port: 53
upstream:
ip: "1.1.1.1"
hostname: "cloudflare-dns.com"

0 comments on commit 065c0b8

Please sign in to comment.