NAT: masquerade and port forwarding
File: src/topics/nat.j. Path: /ip/firewall/nat (NAT_PATH). Reference: cheatsheet.
CHAIN_SRCNATrewrites the source of outgoing traffic. WithACTION_MASQUERADEthe LAN appears as the router's WAN address; a private LAN needs it to reach the internet.CHAIN_DSTNATrewrites the destination of incoming traffic. WithACTION_DST_NATit is a port forward to an inside service.
addMasquerade is idempotent: an existing masquerade rule for the same out-interface is reused, so re-running a setup script never stacks duplicates. The port-forward verbs are not idempotent. They accept only tcp or udp, ports 1-65535 and an IP address as the target.
Examples
Internet edge with a DHCP WAN (dhcp.md):
jennifer
mt.setupWan($c, "ether1");
mt.addMasquerade($c, "ether1", "lan to internet");Publish an internal web server on port 8080:
jennifer
mt.forwardPortOn($c, "ether1", "tcp", 8080, "192.168.88.10", 80, "web server");Close the forward during maintenance without deleting it:
jennifer
mt.disableNatRuleByComment($c, "web server");
mt.enableNatRuleByComment($c, "web server");List the rules:
jennifer
def nats as list of mt.NatRule init mt.natRules($c);
for (def n in $nats) {
io.printf("%s/%s dst-port %s -> %s:%s %s\n",
$n.chain, $n.action, $n.dstPort, $n.toAddresses, $n.toPorts, $n.comment);
}Pitfalls
- The firewall
forwardchain must accept the redirected traffic. The RouterOS default config does (established/related and dstnat'ed connections are accepted); a hardened one needs an accept rule (firewall.md). - Use
forwardPortOnwith the WAN interface.forwardPortmatches any incoming interface, so LAN clients connecting to the router on that port are redirected too. - Reaching a forwarded service from inside the LAN through the public address needs hairpin NAT (an extra srcnat rule); add it with the generic
addonNAT_PATH. - Order matters in
dstnat: a catch-all above a forward shadows it. Reorder withmoveNatRule/moveNatRuleByComment. - Masquerade drops long-lived connections when the WAN address changes.
See also: ppp.md (masquerade the PPPoE interface on DSL uplinks), upnp.md.