Configuring Wildcard DNS for Local Development with dnsmasq: Resolving *.mydomain.com to Internal Server IP


2 views

In my local NAT environment, I have multiple machines including:

  • Router (running dnsmasq, NAT, forwarding)
  • Server (hosting multiple web services via vhosts)
  • Client machines

The main challenge arises when all external requests for *.mydomain.com resolve to the router's public IP, making it difficult to:

  1. Track individual client requests in server logs
  2. Maintain proper vhost resolution internally
  3. Debug scripts with accurate client identification

To make all subdomains of mydomain.com resolve to the internal server IP (e.g., 192.168.1.100), add this to /etc/dnsmasq.conf:

# Wildcard DNS for local development
address=/mydomain.com/192.168.1.100
# If you need specific subdomains to point elsewhere
address=/special.mydomain.com/192.168.1.101
# Force all queries for this domain to be handled locally
server=/mydomain.com/

For Apache/Nginx virtual hosts on your server machine, ensure each vhost has:

# Apache example
<VirtualHost *:80>
    ServerName site1.mydomain.com
    ServerAlias *.site1.mydomain.com
    DocumentRoot /var/www/site1
</VirtualHost>

# Nginx example
server {
    server_name ~^(?<subdomain>.+)\.mydomain\.com$;
    root /var/www/$subdomain;
    ...
}

After restarting dnsmasq (sudo systemctl restart dnsmasq), verify with:

# Test DNS resolution
dig anytest.mydomain.com @localhost

# Expected output should show:
;; ANSWER SECTION:
anytest.mydomain.com. 0 IN A 192.168.1.100

If you need external DNS for some subdomains but local resolution for others:

# In dnsmasq.conf
server=/mydomain.com/8.8.8.8
address=/dev.mydomain.com/192.168.1.100
address=/staging.mydomain.com/192.168.1.100


When running services behind NAT with dnsmasq as your local DNS resolver, you often need proper hostname resolution for development or internal services. The standard setup where all subdomains point to your public IP (router) creates logging complications and breaks local network visibility.

Consider this common scenario:

Public DNS:
*.mydomain.com. 300 IN A 203.0.113.45 (router IP)

Local Network:
router - 192.168.1.1
server - 192.168.1.2
client1 - 192.168.1.100

Without proper local resolution, all HTTP requests for dev.site1.mydomain.com get routed through your public IP and port forwarded back in - creating unnecessary latency and masking the true client IP in your logs.

Edit your dnsmasq.conf (typically /etc/dnsmasq.conf):

# Enable wildcard resolution for local domain
address=/.mydomain.com/192.168.1.2

# Alternative syntax for specific subdomain patterns
address=/server.mydomain.com/192.168.1.2

# If you need both internal and external resolution
server=/mydomain.com/8.8.8.8

Pair this with proper virtual host configuration:

# Apache example

    ServerName dev.mydomain.com
    ServerAlias *.mydomain.com
    DocumentRoot /var/www/dev


# Nginx example
server {
    listen 80;
    server_name ~^(?.+)\.mydomain\.com$;
    root /var/www/$subdomain;
}

Verify with these commands:

# Flush DNS cache
sudo systemctl restart dnsmasq

# Test resolution
dig +short test.mydomain.com @192.168.1.1
# Should return 192.168.1.2

ping -c 1 random.mydomain.com
# Should resolve to your server IP

To maintain proper client identification in your logs, configure HTTP forwarding:

# Nginx real IP module
set_real_ip_from 192.168.1.0/24;
real_ip_header X-Forwarded-For;

For Apache:

RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 192.168.1.1