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


2 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