Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Improved CGNAT script

...

  • input - used to process packets entering the router through one of the interfaces with the destination IP address which is one of the router's addresses. Packets passing through the router are not processed against the rules of the input chain.
  • output - used to process packets that originated from the router and leave it through one of the interfaces. Packets passing through the router are not processed against the rules of the output chain.

Destination NAT

Image Modified

Network address translation works by modifying network address information in the packets IP header. Let`s take a look at the common setup where a network administrator wants to access an office server from the internet.

...

Code Block
languageros
/ip firewall nat add chain=srcnat src-address=10.0.0.0/24 action=masquerademasquarade out-interface=WAN

Every time when interface disconnects and/or its IP address changes, the router will clear all masqueraded connection tracking entries related to the interface, this way improving system recovery time after public IP change. If srcnat is used instead of masquerade, connection tracking entries remain and connections can simply resume after a link failure.

...

Tip

Though Source NAT and masquerading perform the same fundamental function: mapping one address space into another one, the details differ slightly. Most noticeably, masquerading chooses the source IP address for the outbound packet from the IP bound to the interface through which the packet will exit.

CGNAT (NAT444)

Image Modified

To combat IPv4 address exhaustion, a new RFC 6598 was deployed. The idea is to use shared 100.64.0.0/10 address space inside the carrier's network and perform NAT on the carrier's edge router to a single public IP or public IP range.

...

Inside IPOutside IP/Port range
100.64.1.12.2.2.2:2000-2099
100.64.1.22.2.2.2:2100-2199
100.64.1.32.2.2.2:2200-2299
100.64.1.42.2.2.2:2300-2399
100.64.1.52.2.2.2:2400-2499
100.64.1.62.2.2.2:2500-2599

Instead of writing NAT mappings rules by hand, we could write a function that adds such rules automaticallyit is suggested to use a script instead. Below is an example that could be adapted to any requirements for your setup.

Code Block
languageros
:global sqrt do={
######## Adjustable values #########
:forlocal i from=0 to=$1 do={
    :if (i * i > $1) do={ :return ($i - 1) }
  }
}

:global addNatRules do={
  StartingAddress 100.64.0.1
:local ClientCount 5
:local AddressesPerClient 2
:local PublicAddress 2.2.2.2
:local StartingPort 5000
:local PortsPerAddress 200
####################################

# All client chain jump
/ip firewall nat add chain=srcnat action=jump jump-target=xxxclients \
    src-address="$($srcStart)$StartingAddress-$($srcStart$StartingAddress + $count($ClientCount * $AddressesPerClient) - 1)"

:local currentPort :local x [$sqrt $count]
  :local y $x
  $StartingPort

:for c from=1 to=$ClientCount do={
    # Specific client chain jumps
    :if ($x$AddressesPerClient * $x = $count> 1) do={
 :set y ($x + 1) }
  :for i from=0 to=$x do={
    /ip firewall nat add chain=xxxclients action=jump jump-target="xxx-$($i)client-$c" \
      src-address="$($srcStart$StartingAddress + ($x$AddressesPerClient * $i($c - 1)))-$($srcStart$StartingAddress + ($x$AddressesPerClient * ($i + 1)$c - 1))"
  }

  :for i from=0 to=($count - 1) do=} else={
    :local prange "$($portStart + ($i * $portsPerAddr))-$($portStart + (($i + 1) * $portsPerAddr) - 1)" /ip firewall nat add chain=clients action=jump jump-target="client-$c" \
      src-address="$($StartingAddress + ($AddressesPerClient * ($c - 1)))"
    }
  
    # Translation rules
    :for a from=1 to=$AddressesPerClient do={
      /ip firewall nat add chain="xxx-$($i / $x)client-$c" action=src-nat protocol=tcp src-address=($srcStart\
      src-address="$($StartingAddress + $i(($c -1) \
* $AddressesPerClient) + $a - 1)" to-address=$toAddr$PublicAddress to-ports=$prange"$currentPort-$($currentPort+$PortsPerAddress)"
      /ip firewall nat add chain="xxx-$($i / $x)client-$c" action=src-nat protocol=udp \
      src-address="$($srcStart$StartingAddress + $i) \
    (($c -1) * $AddressesPerClient) + $a - 1)" to-address=$toAddr$PublicAddress to-ports=$prange
  }
}

After pasting the above script in the terminal function "addNatRules" is available. If we take our example, we need to map 6 shared network addresses to be mapped to 2.2.2.2 and each address uses a range of 100 ports starting from 2000. So we run our function:

Code Block
languageros
$addNatRules count=6 srcStart=100.64.1.1 toAddr=2.2.2.2 portStart=2000 portsPerAddr=100
"$currentPort-$($currentPort+$PortsPerAddress)"
      :set currentPort ($currentPort + $PortsPerAddress)
    }
}
}

The six local values can be adjusted and the script can be either simply pasted in the terminal or it can be stored in the system script section, in case the configuration needs to be regenerated later.

After execution you should Now you should be able to get a set of rules:

Code Block
languageros
[admin@rack1_b18_450] /admin@MikroTik] > ip firewall nat>nat print 
Flags: X - disabled, I - invalid,; D - dynamic 
 0    chain=srcnat action=jump jump-target=xxxclients 
      src-address=100.64.10.1-100.64.1.6 log=no log-prefix=""0.10 

 1    chain=xxxclients action=jump jump-target=xxx-0 src-address=100.64.1.1-100.64.1.2 log=no log-prefix="" 

 2client-1 
     chain=xxx action=jump jump-target=xxx-1 src-address=100.64.0.1.3-100.64.1.4 log=no log-prefix=""0.2 

 32    chain=xxxclient-1 action=jump jump-target=xxx-2src-nat to-addresses=2.2.2.2 to-ports=5000-5200 
      protocol=tcp src-address=100.64.1.5-100.640.1.6 log=no log-prefix="" 

 43    chain=xxxclient-01 action=src-nat to-addresses=2.2.2.2 to-ports=2000-20995000-5200 
      protocol=tcpudp src-address=100.64.10.1 log=no log-prefix="" 

 54    chain=xxxclient-01 action=src-nat to-addresses=2.2.2.2 to-ports=2000-20995200-5400 
      protocol=udptcp src-address=100.64.10.1 log=no log-prefix="" 2 

 65    chain=xxxclient-01 action=src-nat to-addresses=2.2.2.2 to-ports=2100-21995200-5400 
      protocol=tcpudp src-address=100.64.10.2 log=no log-prefix="" 

 76    chain=xxx-0clients action=src-natjump tojump-addressestarget=2.2.2.2 to-ports=2100-2199 protocol=udpclient-2 
      src-address=100.64.0.3-100.64.1.2 log=no log-prefix="" 0.4 

 87    chain=xxxclient-12 action=src-nat to-addresses=2.2.2.2 to-ports=2200-22995400-5600 
      protocol=tcp src-address=100.64.10.3 log=no log-prefix="" 

 98    chain=xxxclient-12 action=src-nat to-addresses=2.2.2.2 to-ports=2200-22995400-5600 
      protocol=udp src-address=100.64.10.3 log=no log-prefix="" 

10 9    chain=xxxclient-12 action=src-nat to-addresses=2.2.2.2 to-ports=2300-23995600-5800 
      protocol=tcp src-address=100.64.1.4 log=no log-prefix=""0.4 

1110    chain=xxxclient-12 action=src-nat to-addresses=2.2.2.2 to-ports=2300-23995600-5800 
      protocol=udp src-address=100.64.10.4 log=no log-prefix="" 

11    chain=clients action=jump jump-target=client-3 
      src-address=100.64.0.5-100.64.0.6 

12    chain=xxxclient-23 action=src-nat to-addresses=2.2.2.2 to-ports=2400-24995800-6000 
      protocol=tcp src-address=100.64.10.5 log=no log-prefix="" 

13    chain=xxxclient-23 action=src-nat to-addresses=2.2.2.2 to-ports=2400-24995800-6000 
      protocol=udp src-address=100.64.10.5 log=no log-prefix="" 

14    chain=xxxclient-23 action=src-nat to-addresses=2.2.2.2 to-ports=2500-25996000-6200 
      protocol=tcp src-address=100.64.10.6 log=no log-prefix="" 

15    chain=xxxclient-23 action=src-nat to-addresses=2.2.2.2 to-ports=2500-25996000-6200 
      protocol=udp src-address=100.64.10.6 log=no log-prefix=""

[...]


Hairpin NAT

Hairpin network address translation (NAT Loopback) is where the device on the LAN is able to access another machine on the LAN via the public IP address of the gateway router. 


Image Modified


In the above example the gateway router has the following dst-nat configuration rule:

...

  1. the client sends a packet with a source IP address of 192.168.88.1 to a destination IP address of 172.16.16.1 on port 443 to request some web resources;
  2. the router destination NAT`s the packet to 10.0.0.3 and replaces the destination IP address in the packet accordingly. The source IP address stays the same: 192.168.88.1;
  3. the server replies to the client's request and the reply packet have a source IP address of 10.0.0.3 and a destination IP address of 192.168.88.1.
  4. the router determines that the packet is part of a previous connection and undoes the destination NAT, and puts the original destination IP address into the source IP address field. The destination IP address is 192.168.88.1, and the source IP address is 172.16.16.1;
  5. The client receives the reply packet it expects, and the connection is established;


Image Modified

But, there will be a problem, when a client on the same network as the web server requests a connection to the web server's public IP address: 

...

  1. the client sends a packet with a source IP address of 10.0.0.2 to a destination IP address of 172.16.16.1 on port 443 to request some web resources;
  2. the router destination NATs the packet to 10.0.0.3 and replaces the destination IP address in the packet accordingly. It also source NATs the packet and replaces the source IP address in the packet with the IP address on its LAN interface. The destination IP address is 10.0.0.3, and the source IP address is 10.0.0.1;
  3. the web server replies to the request and sends the reply with a source IP address of 10.0.0.3 back to the router's LAN interface IP address of 10.0.0.1;
  4. the router determines that the packet is part of a previous connection and undoes both the source and destination NAT, and puts and puts the original destination IP address of 17210.160.160.1 3 into the source IP address field, and the original source IP address of 10172.016.016.2 1 into the destination IP address field.

Endpoint-Independent NAT

Endpoint-independent NAT creates mapping in the source NAT and uses the same mapping for all subsequent packets with the same source IP and port. This mapping is created with the following rule:

...