visit
Development and Testing: Easily create and manage custom domains for testing web applications.
Educational Purposes: Learn how DNS works and experiment with DNS configurations.
Local Network Management: Manage internal domains within a private network.
Create two HTML files (a.html
and b.html
) in a directory named html-files
. These files will be served when you access a.com
and b.com
Respectively.
<!-- a.com -->
<!DOCTYPE html>
<html>
<head>
<title>A Page</title>
</head>
<body>
<h1>Welcome to A.com</h1>
</body>
</html>
<!-- b.com -->
<!DOCTYPE html>
<html>
<head>
<title>B Page</title>
</head>
<body>
<h1>Welcome to B.com</h1>
</body>
</html>
Next, we’ll create a simple HTTP server using Python’s built-in. http.server
Module to serve the HTML files.
#http_server.py
import http.server
import socketserver
PORT = 8080
DIRECTORY = "html-files"
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/a.com':
self.path = '/a.html'
elif self.path == '/b.com':
self.path = '/b.html'
return http.server.SimpleHTTPRequestHandler.do_GET(self)
def translate_path(self, path):
return f"./{DIRECTORY}/{path}"
handler_object = MyHttpRequestHandler
my_server = socketserver.TCPServer(("0.0.0.0", PORT), handler_object)
print(f"Serving HTTP on port {PORT}")
my_server.serve_forever()
http.server
: Provides basic HTTP server functionality.
socketserver
: A framework for network servers.
PORT = 8080
: The server will listen on port 8080.
DIRECTORY = "html-files"
: The directory where HTML files are stored.
MyHttpRequestHandler
: Custom request handler class that overrides do_GET
to serve specific files for a.com
and b.com
.
do_GET(self)
: Checks the requested path and maps /a.com
to /a.html
and /b.com
to /b.html
. The http.server.SimpleHTTPRequestHandler
Serves these files.
translate_path(self, path)
: Translates the requested path to the correct file path within the html-files
directory.
socketserver.TCPServer(("0.0.0.0", PORT), handler_object)
: Binds the server to all available interfaces on port 8080.my_server.serve_forever()
: Starts the server to handle incoming requests indefinitely.
We’ll use the dnslib
Library to create a DNS server that resolves a.com
and b.com
to your local machine’s IP address.
from dnslib import DNSRecord, QTYPE, RR, A, DNSHeader
import socket
import socketserver
# Get the local IP address
hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)
# DNS server configuration
DOMAIN_TO_IP = {
'a.com.': local_ip,
'b.com.': local_ip,
}
class DNSHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
try:
request = DNSRecord.parse(data)
print(f"Received request for: {str(request.q.qname)}")
# Create a DNS response with the same ID and the appropriate flags
reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)
qname = str(request.q.qname)
qtype = QTYPE[request.q.qtype]
if qname in DOMAIN_TO_IP:
reply.add_answer(RR(qname, QTYPE.A, rdata=A(DOMAIN_TO_IP[qname])))
print(f"Resolved {qname} to {DOMAIN_TO_IP[qname]}")
else:
print(f"No record found for {qname}")
socket.sendto(reply.pack(), self.client_address)
except Exception as e:
print(f"Error handling request: {e}")
if __name__ == "__main__":
server = socketserver.UDPServer(("0.0.0.0", 53), DNSHandler)
print("DNS Server is running...")
server.serve_forever()
dnslib
: Provides DNS record creation and parsing.
socket
, socketserver
: Modules for network communication.
hostname = socket.gethostname()
: Retrieves the hostname of the local machine.
local_ip = socket.gethostbyname(hostname)
: Resolves the hostname to an IP address.
DOMAIN_TO_IP
: A dictionary mapping domain names to the local machine’s IP address.
DNSHandler
: Custom request handler class for handling DNS requests.
handle(self)
: Processes incoming DNS requests.
data = self.request[0].strip()
: Reads the incoming data.
request = DNSRecord.parse(data)
: Parses the DNS request.
print(f"Received request for: {str(request.q.qname)}")
: Logs the requested domain.
DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1), q=request.q)
: Creates a DNS response with the same ID and appropriate flags.
if qname in DOMAIN_TO_IP
: Checks if the requested domain is in the configuration.
reply.add_answer(RR(qname, QTYPE.A, rdata=A(DOMAIN_TO_IP[qname])))
: Adds an answer to the DNS response.
socket.sendto(reply.pack(), self.client_address)
: Sends the DNS response back to the client.
socketserver.UDPServer(("0.0.0.0", 53), DNSHandler)
: Binds the server to all available interfaces on port 53.server.serve_forever()
: Starts the server to handle incoming requests indefinitely.To access a.com
and b.com
from your mobile device, you need to configure your mobile device to use your local DNS server.
Go to Settings
> Network & Internet
> Wi-Fi
.
Tap on Advanced
> IP settings
And change it from DHCP
to Static
.
192.168.1.*
).192.168.1.*
).24
.192.168.1.*
).8.8.8.8
(optional).Go to Settings
> Wi-Fi
.
Tap on the i
Icon next to the connected network.
Configure DNS
.Manual
.192.168.1.*
)//a.com:8080
//b.com:8080
dig @127.0.0.1 b.com