Intro

NAT Loopback/hairpin/reflection allows internal clients to access internal resources using an external IP/hostname. This is useful when you run a server inside of a local network, and would like to access it using your domain name/external IP. NAT reflection is fairly simple to accomplish, but becomes a manual process if you are on a dynamic IP. This tutorial will walk you through creating a NAT hairpin, and will provide a script to update all applicable rules when DHCP refreshes.

Note: If you are on ERL version 1.3.0 or greater, a command has been added that drastically simplifies this process. Read this tutorial for more details.

NAT Hairpin

  • Login to EdgeRouter Lite via SSH
  • Enter configure mode
    configure
  • Create NAT rule; the below will forward inbound port 443 to local IP 192.168.69.100 on port 443
    edit service nat rule 1 
    set description HTTPS
    set inside-address address 192.168.69.100
    set inside-address port 443
    set log disable
    set protocol tcp_udp
    set type destination
  • Now set the destination settings of this NAT rule. Note that we are using the eth+ wildcard in order for this rule to be active on all interfaces. Do not worry about modifying the destination address, as this will be dynamically identified with a script later.
    set inbound-interface eth+
    set destination address 0.0.0.0
    set destination port 443
    top
  • Now we need to setup NAT Masquerading for LAN to loop back to LAN
    edit service nat rule 5001
    set description Hairpin_MASQ
    set destination address 192.168.69.0/24
    set source address 192.168.69.0/24
    set log disable
    set outbound-interface eth0
    set protocol tcp_udp
    set type masquerade
    top
  • Finally, we create a firewall rule to allow the inbound traffic
    edit firewall name WAN_IN rule 443
    set description HTTPS
    set action accept
    set destination port 443
    set log disable
    set protocol tcp_udp
    top
  • Commit and save
    commit
    save

Dynamic IP Script

This script will loop through all of your NAT rules looking for rules on the wildcard eth+ interface (it is working under the assumption that all wildcard interfaces are NAT hairpins).

  • Escalate to root and open a new file for the script
    sudo su
    vi /config/scripts/dynnat
  • Paste the following into the new file and save it
    #!/bin/vbash
    IP=`curl -s icanhazip.com`
    source /opt/vyatta/etc/functions/script-template
    configure
    
    for RULE_NUM in `show service nat | grep rule | tr -d '{' | sed 's/rule\|\s//g'`;
    do
        RES=\"`show service nat rule $RULE_NUM`\"
        echo $RES
        if echo $RES | grep -q '+';
            then
                set service nat rule $RULE_NUM destination address $IP
        fi
    done
    commit
    save
  • Add execution bit and create a hard link in dhclient exit hooks directory. These two commands will need to be rerun if you flash the ERL firmware.
    chmod +x /config/scripts/dynnat
    ln /config/scripts/dynnat /etc/dhcp3/dhclient-exit-hooks.d/dynnat
  • Run the script in order to update current IP
    /config/scripts/dynnat /etc/dhcp3/dhclient-exit-hooks.d/dynnat

Credits

http://community.ubnt.com/t5/EdgeMAX/HowTo-Hairpin-NAT-for-Dynamic-IP/m-p/471285/highlight/false#M9220

1