Skip to content

Lab 06-05 · Destination NAT: port forwarding

MTCNA

Module 6 · Firewall of the MikroTik MTCNA course, official slides p261–267 (what NAT is, source and destination NAT, the srcnat and dstnat chains, and the Dst NAT example).

Ever hosted a Minecraft server for your friends, or tried to? Sooner or later somebody says "you need to open a port on your router". What they mean is this lab. Your friends can only see one address from the Internet: your router's. Your server is hidden behind it, on a private address nobody outside can reach. Someone has to take the visitor who knocks at the router's front door and walk them to the right room.

That someone is the bouncer again. Today he is not refusing anybody: he is escorting. You will run a tiny website on your laptop, then make it reachable from "the Internet" through the router's address.

What you will learn

  • Explain what NAT (Network Address Translation) is and why home networks need it.
  • Tell source NAT (change who sends) from destination NAT (change where it goes).
  • Write a dst-nat rule in the dstnat chain that forwards a port to a server on the LAN.
  • Prove it from outside, and prove that the server still sees the real visitor.
  • Understand why a NAT rule's counter grows by one packet per connection, not per packet.

What is NAT?

NAT (Network Address Translation) changes the source or destination address (and port) of packets as they cross the router.

Your LAN uses private addresses such as 192.168.88.x. They are reserved for internal networks (RFC 1918: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) and the Internet does not route them: millions of homes use 192.168.88.200 at the same time. To talk to the outside world, the router translates. Slides 261–262 name the two kinds:

Kind What changes Typical use Club version
src-nat (source NAT) the source address: who the packet seems to come from let a private LAN reach the Internet using the router's address everyone leaving wears the club's T-shirt
dst-nat (destination NAT) the destination address: where the packet goes let the Internet reach a server inside the LAN the bouncer walks a visitor from the front door to a room inside

Like filter rules, NAT rules live in chains and work on if-then, read top to bottom, first match wins (slide 265). NAT has two chains: srcnat for source NAT and dstnat for destination NAT.

Destination NAT, step by step

The visitor only knows the club's street address: the router's public address (on its WAN port). The dst-nat rule says: "if a packet arrives at the WAN port for tcp/80, change its destination to 192.168.88.200:80".

sequenceDiagram
    participant V as internet<br>198.51.100.10
    participant R as r1<br>WAN 10.0.0.x
    participant S as pc1 web server<br>192.168.88.200
    V->>R: to 10.0.0.x:80
    Note over R: dstnat rule: destination becomes 192.168.88.200:80
    R->>S: to 192.168.88.200:80 (from 198.51.100.10)
    S->>R: reply to 198.51.100.10
    Note over R: remembers the translation, puts 10.0.0.x back as the source
    R->>V: reply from 10.0.0.x:80

Two details worth noticing:

  • Only the destination changes. The server sees the real visitor's address (198.51.100.10) in its logs.
  • The router remembers each translated conversation (this memory is connection tracking, lab 06-08), so the reply automatically gets the router's address back. That is why the NAT rule itself only sees the first packet of each connection: the rest follow the remembered translation.

Public address in this lab

In a real home, the WAN port has a public address given by your ISP. Here r1's WAN gets 10.0.0.x from class-ap (the "ISP" of the classroom), and the node internet can reach that network directly. The idea is identical.

The scenario

On a real hAP the Internet port is ether1; in the virtual lab ether1 is reserved for the lab itself, so the Internet port is ether2 and the LAN ports start at ether3.

flowchart LR
    PC1["<b>pc1</b> (laptop + web server :80)<br>192.168.88.200<br>'Hello from pc1...'"] -- "LAN" --- R1["<b>r1</b> (the club)<br>bridge1: 192.168.88.1/24<br>ether2 = WAN: 10.0.0.x"]
    R1 -- "class network<br>10.0.0.0/24" --- AP["<b>class-ap</b> (the ISP)<br>10.0.0.1 · 198.51.100.1"]
    AP --- NET["<b>internet</b> (the visitor)<br>198.51.100.10"]
Node Role Address
pc1 your laptop, running a web server on port 80 192.168.88.200 (DHCP)
r1 your router LAN 192.168.88.1/24 · WAN ether2 10.0.0.x (DHCP from class-ap)
class-ap the trainer's router, the "ISP" 10.0.0.1 and 198.51.100.1
internet a visitor on the Internet (Linux, with curl) 198.51.100.10

Start the lab

Download the lab files and unzip them: 06-05-dst-nat-port-forwarding.zip. Open a terminal inside the 06-05-dst-nat-port-forwarding folder.

From the lab folder guions/tema-3/lab/mtcna/06-05-dst-nat-port-forwarding/:

sudo containerlab deploy -t topology.clab.yml

After about two minutes, open three terminals:

ssh admin@clab-mtcna-06-05-r1                       # the router (password: admin)
docker exec -it clab-mtcna-06-05-pc1 bash           # your laptop + web server
docker exec -it clab-mtcna-06-05-internet bash      # the visitor on the Internet

Step 1 · Find the club's street address

The visitor needs the router's WAN address.

IP → Addresses

/ip address print where interface=ether2

Expected: one dynamic (D) address such as 10.0.0.200/24. Write it down; below it is called WAN.

On pc1, check your website works locally:

curl -s http://192.168.88.200        # Hello from pc1, the web server inside the LAN

Check yourself

Which address will a visitor on the Internet use to reach your website: 192.168.88.200, 192.168.88.1 or the WAN address? Why?

Done when: you know the WAN address and pc1's website answers.

Step 2 · Knock from outside before forwarding

On internet (replace 10.0.0.200 by your WAN address):

curl -s http://10.0.0.200 | grep -o '<title>.*</title>'      # <title>RouterOS</title>

The visitor reached... the router's own login page, WebFig. Without instructions, a knock at the front door on port 80 goes into the staff office (input), not to your laptop.

Check yourself

Why can't the visitor simply type http://192.168.88.200? Use the words "private address" in your answer.

Done when: you see that the WAN address on port 80 shows WebFig.

Step 3 · Forward port 80 to the laptop

Slide 267: a dst-nat rule in the dstnat chain.

IP → Firewall → NAT → + · General: Chain dstnat, Protocol 6 (tcp), Dst. Port 80, In. Interface ether2 · Action: dst-nat, To Addresses 192.168.88.200, To Ports 80 · Comment port forwarding: web server on pc1

/ip firewall nat add chain=dstnat in-interface=ether2 protocol=tcp dst-port=80 action=dst-nat to-addresses=192.168.88.200 to-ports=80 comment="port forwarding: web server on pc1"
/ip firewall nat print

Why in-interface=ether2? So that only knocks arriving from the Internet side are escorted. Without it, your own laptop opening any web page on port 80 would also be sent back to itself.

Check yourself

Why does this rule go in dstnat and not in the filter's forward chain?

Done when: the NAT list shows the masquerade rule and your new dst-nat rule.

Step 4 · Knock again

On internet:

curl -s http://10.0.0.200            # Hello from pc1, the web server inside the LAN

On pc1, read the web server's diary:

cat /var/log/http.log                # 198.51.100.10 - - [...] "GET / HTTP/1.1" 200 -

The server saw the real visitor, 198.51.100.10: dst-nat only changed the destination. Now the counters:

IP → Firewall → NAT (Packets column)

/ip firewall nat print stats

The dst-nat rule shows 1 packet per curl, although each web visit is several packets. Only the first packet of a connection goes through the NAT rules; the rest follow the remembered translation.

Check yourself

You want visitors to type http://WAN:8080 instead, while pc1's server stays on port 80. Which two fields of the rule do you change, and to what?

Done when: the visitor sees pc1's page and pc1's log shows 198.51.100.10.

Step 5 · Make sure the LAN still works

On pc1:

curl -s http://www.mikrotik.com      # Welcome to the Internet

Then run the checker from the lab folder on your PC:

CLAB_EXEC="sudo docker exec" ./check.sh

It must end with RESULT: lab 06-05 solved.

Check yourself

The masquerade rule and your dst-nat rule live in the same NAT table. Which one handles pc1's visits to the Internet, and which one the visitor's knock?

Done when: check.sh passes.

If something goes wrong

Symptom Likely cause Fix
The visitor still sees WebFig rule disabled, wrong chain (srcnat), or wrong in-interface /ip firewall nat print detail
The visitor gets nothing (timeout) wrong To Addresses (typo), or pc1's server is not running curl http://192.168.88.200 on pc1
pc1 opening http://WAN from inside does not work that is hairpin NAT, a different case not covered by this rule test from internet, as the lab does
pc1 cannot browse the Internet any more the rule has no in-interface=ether2, so pc1's own web traffic is sent back to itself add in-interface=ether2
The counter grows by 1 per visit, not more that is normal: NAT only sees the first packet of a connection nothing to fix

Clean up

sudo containerlab destroy -t topology.clab.yml --cleanup

Key takeaways

  • NAT rewrites the source (src-nat) or destination (dst-nat) address of packets crossing the router.
  • Private addresses (RFC 1918) are not routed on the Internet, so a LAN server needs dst-nat to be reachable.
  • A port forwarding rule: chain dstnat, in-interface = WAN, protocol + dst-port, action dst-nat with to-addresses / to-ports.
  • dst-nat changes only the destination: the server sees the real visitor's address.
  • NAT rules only see the first packet of each connection; connection tracking handles the rest.

Quick check

1. What does destination NAT change in a packet?
  • The source address
  • The destination address (and optionally the port)
  • The MAC address
  • The protocol

dst-nat rewrites where the packet goes. src-nat rewrites who it seems to come from.

2. In which NAT chain do you put a port-forwarding rule?
  • srcnat
  • dstnat
  • forward
  • input

Destination NAT lives in the dstnat chain. srcnat is for source NAT; forward and input are filter chains.

3. Why can't somebody on the Internet open http://192.168.88.200 directly?
  • Because port 80 is always closed on laptops
  • Because the router blocks all traffic from the Internet by default
  • Because 192.168.88.0/24 is a private range that the Internet does not route
  • Because the address belongs to the router

Private addresses (RFC 1918) are reused in millions of homes, so the Internet cannot know which one you mean. The visitor must use the router's public address, and dst-nat does the rest.

4. After port forwarding, whose address does pc1's web server see as the visitor?
  • The router's LAN address 192.168.88.1
  • The router's WAN address
  • The real visitor's address 198.51.100.10
  • Its own address 192.168.88.200

dst-nat only changes the destination. The source is untouched, so the server logs the real visitor.

5. A visitor loads the forwarded page and the transfer takes 8 packets. How much does the dst-nat rule's counter grow?
  • By 1 packet
  • By 4 packets
  • By 8 packets
  • By 16 packets

NAT rules see only the first packet of a connection. The router remembers the translation (connection tracking) and applies it to the rest without reading the rules again.

6. Your friend wants to host a game server on 192.168.88.50, port 25565/tcp, reachable at your router's public address. Which two settings belong in the rule?
  • chain=dstnat in-interface=ether2 protocol=tcp dst-port=25565
  • chain=srcnat out-interface=ether2 action=masquerade
  • action=dst-nat to-addresses=192.168.88.50 to-ports=25565
  • chain=input protocol=tcp dst-port=25565 action=accept

A port forward matches the knock at the WAN (dstnat, in-interface, protocol, dst-port) and escorts it inside (dst-nat with to-addresses and to-ports).

The bouncer can now escort visitors from the front door to a room. In 06-06 · Redirect he does the opposite trick: whatever room your laptop asks for, he walks it to the club's own reception.