A minimal implementation of a Shecan-like service. It combines a lightweight DNS server written in Python with an Nginx based transparent proxy. Whitelisted domains resolve to your public IP while all other lookups are resolved normally.
| File | Description |
|---|---|
dns.py |
DNS server using dnslib. It serves a fixed IP for domains listed in the whitelist and falls back to real DNS resolution for others. |
domains |
Default whitelist. Borrowed from fod. |
nginx.conf |
Nginx configuration that redirects HTTP to HTTPS and forwards TCP traffic on port 443 based on SNI. |
entrypoint.sh |
Start script that launches Nginx and the DNS server. |
Dockerfile |
Build instructions for the container image. |
- Docker/Podman (recommended)
- Python 3 with
dnslibif running the DNS server outside of a container
-
Ensure ports 53/udp, 80, and 443 are free. Disable
systemd-resolvedif necessary. -
Build the image (optional if using the published one):
docker build -t smart-dns . -
Run the container, replacing
YOUR_PUBLIC_IPwith the address you want whitelisted domains to resolve to:docker run -d --net=host -p 53:53/udp -p 80:80 -p 443:443 \ -e PUB_IP=YOUR_PUBLIC_IP --name smart-dns smart-dns:latest
PUB_IP: IP address returned for whitelisted domains.DNS_ALLOW_ALL=YES: Ignore the whitelist and respond withPUB_IPfor every domain.
python3 dns.py --ip ENV --whitelist domains --port 53Use --ip ENV to read the IP from the PUB_IP environment variable, or supply the IP directly. Set --whitelist ALL (or DNS_ALLOW_ALL=YES) to allow every domain.
Verify functionality with dig:
dig @127.0.0.1 -p 53 fodev.org +short # returns PUB_IP for whitelisted domain
dig @127.0.0.1 -p 53 google.com +short # returns real IP for others- Port 53 handles DNS queries.
- Ports 80 and 443 receive HTTP/HTTPS traffic for the transparent proxy.
--net=hostavoids NAT so Nginx can see the original client IP and process SNI correctly.
This project is for educational use. Review the code and configuration before exposing it to untrusted networks.