05-03: Exercises¶
Question¶
A company's internal web server sits at private address 192.168.1.50:8080. Their router/firewall's public interface is 203.0.113.10. They want anyone on the internet to be able to reach the internal web server by visiting https://203.0.113.10 on the standard port 443.
- Write the
iptablesNAT rule that forwards incoming traffic on the public IP's port 443 to the internal server's port 8080. - Write the companion
FORWARDrule needed to actually let that traffic reach the internal host. - Explain what's needed for the return traffic to get back out correctly.
Solution¶
Step 1: The DNAT (Destination NAT) rule¶
Port forwarding is implemented with Destination NAT (DNAT), applied in the nat table's PREROUTING chain (so the rewrite happens before the routing decision):
iptables -t nat -A PREROUTING -p tcp -d 203.0.113.10 --dport 443 -j DNAT --to-destination 192.168.1.50:8080
-t natselects the NAT table (as opposed to the defaultfiltertable).-A PREROUTING— DNAT must happen in PREROUTING, before the kernel decides how to route the packet, so it can be redirected to an internal host.-d 203.0.113.10 --dport 443matches traffic arriving for the public IP on port 443.-j DNAT --to-destination 192.168.1.50:8080rewrites the destination IP and port to the internal server.
Step 2: The FORWARD rule¶
DNAT only rewrites the packet's destination — it doesn't automatically grant permission to forward it. Since this traffic is now heading to a different host than the firewall itself, it passes through the FORWARD chain, which needs its own explicit allow rule (see 05-07: ACLs, DMZ & Segmentation for why forwarded traffic between zones is treated separately from traffic destined for the firewall itself):
iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 8080 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
👉 Without this rule, the DNAT rewrite happens, but the packet is dropped when it hits a default-DROP FORWARD policy.
Step 3: The return path (SNAT/MASQUERADE)¶
The internal server's reply is addressed back to whatever the original client's IP was — but that reply needs to travel back out through the same public interface, and (just as importantly) the client is expecting a reply from 203.0.113.10:443, not from 192.168.1.50. The router needs to translate the source address back on the way out. On the common case where the public IP is dynamically assigned or the exact address isn't hardcoded elsewhere in the firewall config, MASQUERADE handles this automatically for the outbound interface:
-t nat -A POSTROUTINGapplies after routing, right before the packet leaves the interface.-o eth0— the outbound (public-facing) interface.MASQUERADErewrites the source address to match the outbound interface's address automatically — the connection-tracking system (conntrack) remembers this translation so replies naturally get un-translated on the way back to the internal server, and the original DNAT/SNAT mapping is applied symmetrically without needing a separate manual reverse rule.
Final Answer¶
# 1. DNAT: forward public :443 to the internal server's :8080
iptables -t nat -A PREROUTING -p tcp -d 203.0.113.10 --dport 443 -j DNAT --to-destination 192.168.1.50:8080
# 2. Allow the forwarded traffic through the FORWARD chain
iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 8080 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
# 3. Translate the source address on the way back out (return path)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
All three pieces are required together: DNAT alone gets the packet redirected but not forwarded; the FORWARD rule alone has nothing to match without DNAT; and without the POSTROUTING rule, the internal server's replies would try to go directly back to the client with a private source address that the internet can't route to.