How to Resolve a Domain to CNAME Locally Using dnsmasq: AWS ELB Example


20 views

When working with cloud infrastructure like AWS Elastic Load Balancers (ELB), you often need to map custom domains to their dynamically assigned DNS names. The traditional /etc/hosts approach falls short because:

  • It only supports A records (IP addresses)
  • ELB hostnames frequently change during scaling events
  • No support for DNS-level features like TTL management
# /etc/hosts example (won't work for CNAME)
# 54.252.123.45 somedomain.com  # This would break when ELB IPs change

dnsmasq provides a lightweight DNS forwarder with local override capabilities perfect for development environments:

  • Supports all DNS record types including CNAME
  • Can be configured per-machine without affecting others
  • Integrates with your existing DNS resolution chain
  • Supports wildcards and regex patterns if needed
  • Here's how to set it up on a Linux/macOS development machine:

    1. Install dnsmasq

    # Ubuntu/Debian
    sudo apt-get install dnsmasq
    
    # macOS (using Homebrew)
    brew install dnsmasq
    

    2. Configure Local CNAME Resolution

    Edit /etc/dnsmasq.conf (create if doesn't exist):

    # Enable dnsmasq to bind to port 53
    bind-interfaces
    
    # Set your main DNS server (e.g., Google DNS)
    server=8.8.8.8
    
    # Add your CNAME mapping
    cname=somedomain.com,some-balancer-1213231237.ap-southeast-2.elb.amazonaws.com
    

    3. Configure Your System to Use Local dnsmasq

    Edit /etc/resolv.conf:

    nameserver 127.0.0.1
    options edns0
    

    Verify the setup using dig or nslookup:

    dig somedomain.com
    
    ;; ANSWER SECTION:
    somedomain.com.      0       IN      CNAME   some-balancer-1213231237.ap-southeast-2.elb.amazonaws.com.
    

    For more complex scenarios, consider these patterns:

    Wildcard Subdomains

    cname=*.dev.somedomain.com,internal-alb-123456789.ap-southeast-2.elb.amazonaws.com
    

    Multiple Environments

    # Development
    cname=api.somedomain.com,dev-alb-123.elb.amazonaws.com
    
    # Staging
    cname=api.stage.somedomain.com,stage-alb-456.elb.amazonaws.com
    
    • Check logs: tail -f /var/log/dnsmasq.log
    • Reload config: sudo pkill -HUP dnsmasq
    • Test locally: dig @127.0.0.1 somedomain.com

    When working with AWS infrastructure, we often need to test domain resolutions before updating production DNS records. While /etc/hosts works for simple A record overrides, it falls short when we need to:

    • Map to CNAME records (like AWS load balancer endpoints)
    • Maintain complex local DNS rules
    • Test multiple subdomains efficiently

    dnsmasq provides a lightweight DNS forwarder with these advantages:

    • Local CNAME resolution support
    • Flexible configuration without restarting the network stack
    • Ability to override specific domains while forwarding others
    • Lightweight and easy to configure

    For most Linux distributions:

    # Ubuntu/Debian
    sudo apt install dnsmasq
    
    # RHEL/CentOS
    sudo yum install dnsmasq
    
    # macOS (via Homebrew)
    brew install dnsmasq
    

    Edit /etc/dnsmasq.conf (create if doesn't exist):

    # Listen only on localhost
    listen-address=127.0.0.1
    
    # Disable DNS cache (optional for development)
    no-negcache
    cache-size=0
    
    # Our CNAME mapping
    cname=somedomain.com,some-balancer-1213231237.ap-southeast-2.elb.amazonaws.com
    
    # Alternative syntax if you need multiple domains
    cname=*.test.somedomain.com,internal-alb-123456789.ap-southeast-2.elb.amazonaws.com
    

    Start dnsmasq in debug mode to verify:

    sudo dnsmasq --no-daemon --log-queries
    

    In another terminal, test resolution:

    dig @127.0.0.1 somedomain.com
    
    # Should show:
    ;; ANSWER SECTION:
    somedomain.com.      0       IN      CNAME   some-balancer-1213231237.ap-southeast-2.elb.amazonaws.com.
    

    For complex setups with multiple environments:

    # Development environment mapping
    cname=dev.somedomain.com,dev-alb-987654321.ap-southeast-2.elb.amazonaws.com
    
    # Staging environment mapping
    cname=staging.somedomain.com,stage-alb-123987456.ap-southeast-2.elb.amazonaws.com
    
    # Wildcard subdomains
    cname=*.feature.somedomain.com,feature-test-123456789.ap-southeast-2.elb.amazonaws.com
    

    For system-wide use (Linux):

    # Configure DNS resolution
    sudo mkdir -p /etc/systemd/resolved.conf.d
    echo -e "[Resolve]\nDNS=127.0.0.1" | sudo tee /etc/systemd/resolved.conf.d/dnsmasq.conf
    sudo systemctl restart systemd-resolved
    
    # Enable dnsmasq service
    sudo systemctl enable --now dnsmasq
    

    For macOS (after Homebrew installation):

    # Start dnsmasq service
    sudo brew services start dnsmasq
    
    # Configure DNS resolution
    sudo mkdir -p /etc/resolver
    echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/somedomain.com