Welcome to the official documentation of how I built my custom top-level domainΒ like .yash and used it to serve real content from Vercel and GitHub Pages using local DNS resolution at VPS and local network. This guide walks you through setting up your own alt-root DNS infrastructure and linking it with modern hosting.
This repository provides a complete guide to setting up your own alt-root DNS infrastructure with custom TLDs. Whether you want .dev, .home, .company, or any custom domain, this guide will help you build your own internet.
So How to Create your own custom top-level domains like .localnet, .yash, or .mycompany and serve real content locally or across the network with VPS?
Before you begin, ensure you have:
- π§ Linux OS (Ubuntu 20.04+, Arch, CentOS, etc.)
- π Internet access (for package installs and DNS routing)
- π§
sudoprivileges (to install and configure services) - π± (Optional) Other devices on your network (to test local DNS resolution)
- π οΈ Basic terminal knowledge (copy-paste commands, edit config files)
Only needed if you're hosting the setup on a remote server like AWS, Oracle Cloud, or DigitalOcean:
- βοΈ VPS or Cloud server with public IP
- π SSH access (via
.pemor password) - π (Optional) Custom domain (e.g.,
dns.yourdomain.com) - π (Optional) SSL certificates (for HTTPS/secure DNS)
- π‘οΈ Firewall/security group setup (allow ports: 22, 53, 80/443)
- π§βπ» (Optional) Hosting account (like Vercel, Netlify) for domain mapping
With this setup, you can:
- β
Create custom TLDs like
.localnet,.yash,.home,.company - β
Access local services via beautiful domains (
api.localnet,dashboard.company) - β Route traffic to Vercel, GitHub Pages, or local servers
- β Works across your entire network (mobile, desktop, IoT devices)
- β Professional development environment
# Development
http://api.dev β localhost:3000
http://frontend.dev β localhost:3001
http://docs.dev β GitHub Pages
# Company Network
http://intranet.company β Internal server
http://files.company β File server
http://chat.company β Slack alternative
# Home Lab
http://nas.home β Network storage
http://router.home β Router admin
http://pi.home β Raspberry PiHere's what a custom .yash TLD looks like in action:
Screenshot showing dev.yash loading successfully in browser
-
Install dnsmasq
# Ubuntu/Debian sudo apt update && sudo apt install dnsmasq # Arch Linux sudo pacman -S dnsmasq # CentOS/RHEL sudo yum install dnsmasq
-
Configure dnsmasq
Edit
/etc/dnsmasq.conf(create backup first:sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup):# Basic configuration domain-needed bogus-priv no-resolv server=8.8.8.8 server=1.1.1.1 # Your custom TLD (replace 'localnet' with your preferred TLD) local=/localnet/ address=/api.localnet/YOUR_SERVER_IP address=/web.localnet/YOUR_SERVER_IP address=/docs.localnet/YOUR_SERVER_IP # Network configuration (replace with your network interface and IP) listen-address=127.0.0.1,YOUR_SERVER_IP interface=eth0 # or wlan0, enp0s3, etc. # Optional: Cache settings cache-size=1000
π‘ Pro Tip: Find your network interface with
ip addr showorifconfigπ§ Replace YOUR_SERVER_IP with your actual IP, for example:
address=/api.localnet/192.168.1.100(if your server IP is 192.168.1.100)listen-address=127.0.0.1,192.168.1.100
-
Start the service
sudo systemctl enable dnsmasq sudo systemctl start dnsmasq sudo systemctl status dnsmasq # Verify it's running
β οΈ Important: After making config changes, always restart dnsmasq:sudo systemctl restart dnsmasq
# Method 1: Using ip command (Linux)
ip addr show | grep inet
# Method 2: Using hostname command
hostname -I
# Method 3: Using ifconfig (if available)
ifconfig | grep "inet "
# Your output will look like: 192.168.1.X, 10.0.0.X, or 172.16.0.Xπ‘ Note: Use your private IP (192.168.x.x, 10.x.x.x, 172.16-31.x.x) for local network setup, And your public IP for setting up external access via VPS.
-
Test your setup
# Test DNS resolution (replace 127.0.0.1 with your DNS server IP if remote) nslookup api.localnet 127.0.0.1 dig @127.0.0.1 web.localnet # Should return your configured IP (e.g., 192.168.1.100)
# Set DNS server (replace YOUR_SERVER_IP with your DNS server IP)
# Example: netsh interface ip set dns "Wi-Fi" static 192.168.1.100
netsh interface ip set dns "Wi-Fi" static YOUR_SERVER_IP# Edit /etc/resolv.conf (replace YOUR_SERVER_IP with your DNS server IP)
# Example: echo "nameserver 192.168.1.100" | sudo tee /etc/resolv.conf
echo "nameserver YOUR_SERVER_IP" | sudo tee /etc/resolv.conf- Go to Wi-Fi settings
- Modify network β Advanced options
- Set DNS to your server IP (e.g., 192.168.1.100)
The easiest way to make your custom TLD work on all devices automatically:
- Login to your router (usually
192.168.1.1or192.168.0.1) - Find DHCP/DNS settings (varies by router brand)
- Set Primary DNS to your dnsmasq server IP (e.g.,
192.168.1.100) - Set Secondary DNS to a public DNS (
8.8.8.8) - Save and reboot router
Now every device that connects to your WiFi will automatically use your custom DNS!
π‘ Router Examples:
- TP-Link: Advanced β Network β DHCP Server β Primary DNS
- Netgear: Dynamic DNS β DNS Server
- Linksys: Smart Wi-Fi Tools β Router Settings β DHCP
- ASUS: Adaptive QoS β DNS Server
# Serve static files
cd /var/www/localnet
python3 -m http.server 80
# Or use nginx
sudo apt install nginx
sudo systemctl start nginx
# Configure nginx virtual hosts
sudo tee /etc/nginx/sites-available/localnet << 'EOF'
server {
listen 80;
server_name *.localnet;
root /var/www/localnet;
index index.html;
}
EOF
sudo ln -s /etc/nginx/sites-available/localnet /etc/nginx/sites-enabled/
sudo systemctl reload nginxsudo mkdir -p /var/www/localnet
sudo tee /var/www/localnet/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to .localnet!</title>
<style>
body { font-family: Arial; text-align: center; margin-top: 100px; }
h1 { color: #2196F3; }
</style>
</head>
<body>
<h1>π Your Custom TLD is Working!</h1>
<p>You're accessing: <strong id="domain"></strong></p>
<script>document.getElementById('domain').textContent = window.location.hostname;</script>
</body>
</html>
EOFNow visit http://api.localnet or http://web.localnet in your browser!
# Add to your dnsmasq.conf
address=/app.localnet/76.76.21.21 # Vercel's IP
# Or use Vercel's CLI to add custom domain
vercel domains add app.localnet
# then add your coutom domain into vercel project
it will show config error but it will work# GitHub Pages IP ranges
address=/docs.localnet/185.199.108.153
address=/blog.localnet/185.199.109.153
# then add your coutom domain into github pages
it will show config error but it will work# Point to Netlify
address=/portfolio.localnet/75.2.60.5
# then add your coutom domain into Nwtlify project
it will show config error but it will work# Map to different local services
address=/grafana.localnet/192.168.1.200:3000
address=/jenkins.localnet/192.168.1.201:8080
address=/nextcloud.localnet/192.168.1.202Common Issues & Solutions
# Check if dnsmasq is running
sudo systemctl status dnsmasq
# Check configuration syntax
sudo dnsmasq --test
# Always restart after config changes
sudo systemctl restart dnsmasq
# Test DNS resolution
nslookup api.localnet 127.0.0.1π‘ Remember: Always run
sudo systemctl restart dnsmasqafter editing/etc/dnsmasq.conf
# Find your network interface
ip addr show
# Update dnsmasq.conf with correct interface
interface=wlan0 # or eth0, enp0s3, etc.# Ensure dnsmasq can bind to port 53
sudo netstat -tulpn | grep :53
# Kill conflicting services
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved- Ensure firewall allows port 53
- Check if router is overriding DNS settings
- Try using private DNS mode on Android
# For local development (self-signed)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/localnet.key \
-out /etc/ssl/certs/localnet.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=*.localnet"
# For public domains (Let's Encrypt)
sudo certbot certonly --standalone -d dns.yourdomain.comserver {
listen 443 ssl;
server_name *.localnet;
ssl_certificate /etc/ssl/certs/localnet.crt;
ssl_certificate_key /etc/ssl/private/localnet.key;
root /var/www/localnet;
index index.html;
}
server {
listen 80;
server_name *.localnet;
return 301 https://$server_name$request_uri;
}# In dnsmasq.conf (replace YOUR_SERVER_IP with your actual IP)
address=/.dev/YOUR_SERVER_IP
address=/.test/YOUR_SERVER_IP
address=/.local/YOUR_SERVER_IP# Forward specific domains to different servers
server=/company.com/192.168.1.10
server=/external.org/8.8.8.8# Round-robin between multiple servers (replace with your actual IPs)
address=/api.localnet/YOUR_SERVER_IP_1
address=/api.localnet/YOUR_SERVER_IP_2
address=/api.localnet/YOUR_SERVER_IP_3We welcome contributions! Here's how you can help:
- π΄ Fork this repository
- π Create a feature branch (
git checkout -b feature/amazing-feature) - π Commit your changes (
git commit -m 'Add amazing feature') - π€ Push to the branch (
git push origin feature/amazing-feature) - π Open a Pull Request
- Docker containerization
- Windows PowerShell scripts
- macOS setup automation
- Web-based management interface
- Monitoring and logging
- Additional DNS server integrations
This project is licensed under the MIT License - see the LICENSE file for details.
- Dockerized Setup - One-command deployment with Docker Compose
- Web Management Interface - GUI for managing domains and configurations
- DNS-over-HTTPS (DoH) - Secure DNS resolution over HTTPS
- DNS-over-TLS (DoT) - Encrypted DNS with stubby integration
- Windows PowerShell Scripts - Native Windows setup automation
- macOS Homebrew Formula - Easy installation for Mac users
- Global Alt-Root DNS - True internet-wide custom TLD (requires infrastructure)
- Pi-hole Integration - Combine ad-blocking with custom TLD
- Mobile App - Android/iOS app for easy DNS switching
- Load Balancing - Multiple DNS servers with failover
- Monitoring Dashboard - Real-time DNS query analytics
| Feature | Status | Notes |
|---|---|---|
| Global .localnet propagation | β Not possible | Requires others to manually add your DNS server |
| Let's Encrypt for local TLD | β Not supported | Let's Encrypt only works for publicly accessible domains |
| DNS-over-HTTPS | πΈ Planned | Currently only DNS-over-UDP implemented |
| Auto router configuration | πΈ Manual | Requires manual router DNS setup |
π‘ Want to contribute? Pick an item from the roadmap and submit a PR!
- dnsmasq - Lightweight DNS server
- CoreDNS - Cloud-native DNS server
- OpenWrt - Router firmware inspiration
- The awesome open-source community
- Pi-hole - Network-wide ad blocking
- Unbound - Recursive DNS resolver
- AdGuard Home - Network protection
β Star this repo if it helped you build your own internet! β
Made with β€οΈ by the community | Report Bug | Request Feature
