Port forwarding redirects network traffic from external ports to internal services. This allows applications running behind firewalls to receive incoming connections from external networks.
Important Note: Most modern Linux distributions now use nftables as the default firewall framework. While iptables remains fully supported and widely used in production environments, nftables offers improved syntax and performance. This guide focuses on iptables for legacy system administration and environments where nftables are not available.
iptables vs nftables quick comparison
| Decision factor | iptables interface | nftables interface |
|---|---|---|
| System support | Confirm the distribution backend and compatibility layer | Confirm the distribution package, service, and active ruleset |
| Existing rules | Common in older runbooks and tooling | Can express rules in native nftables sets, maps, chains, and tables |
| Performance | Benchmark only if rule-processing cost is material to the workload | Benchmark the same traffic and ruleset |
| Migration | Inventory generated rules, Docker/firewall tooling, persistence, and rollback | Validate translated behavior and boot persistence before cutover |
| Selection | Maintain when required by the supported platform or tooling | Prefer when it is the supported native interface for the target platform |
Quick start
Forward port 80 to internal server 192.168.1.10:8080:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:8080
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 8080 -j ACCEPT
iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
netfilter-persistent save
Replace ens33 with your network interface name. See the full guide below.
Prerequisites
Requirements:
- Root or sudo access to your Linux server
- Properly configured network interfaces (verify:
ip addr show) - Basic networking knowledge (IP addresses, ports, protocols)
-
iptablesinstalled (verify:iptables --version)
All iptables commands require root privileges to modify firewall rules.
How iptables works
iptables configures Linux packet filtering through tables and chains. Each table serves a specific purpose, with chains processing packets sequentially.
Basic command syntax:
iptables -t [table] -A [chain] [match_criteria] -j [target]
The nat table handles Network Address Translation operations. For port forwarding, we use three chains in the nat table.
The PREROUTING chain processes incoming packets before routing decisions are made. When a packet arrives, PREROUTING rules execute first, allowing you to change the destination address before the kernel routes the packet.
The POSTROUTING chain handles packets after routing decisions, just before they leave the system. POSTROUTING ensures response packets can find their way back to the original sender.
The FORWARD chain in the filter table controls which packets can traverse your system. Every packet passing through your system must be explicitly allowed in the FORWARD chain, unless you set a permissive default policy.
The default FORWARD policy is typically DROP for security. Check your policy with:
iptables -L FORWARD -v -n | grep policy
Installing iptables
On Debian-based systems, install iptables with the following command:
apt update && apt install iptables
Verify the installation by viewing current rules:
iptables -L -v -n
Check your network interface names as you will need them later:
ip link show
Modern systems typically use interface names like ens33, ens5, or eth0.
Enabling IP forwarding
Enable IP forwarding (disabled by default):
Check the current forwarding status:
sysctl net.ipv4.ip_forward
A value of 0 means disabled. A value of 1 means enabled.
Enable forwarding temporarily for immediate testing:
sysctl -w net.ipv4.ip_forward=1
To make forwarding permanent across reboots, edit the sysctl configuration file:
nano /etc/sysctl.conf
Add or modify this line:
net.ipv4.ip_forward = 1
Apply the changes immediately:
sysctl -p
Complete port forwarding configuration
Port forwarding requires three components working together: destination address translation, firewall forwarding rules, and source address masquerading. Configure each component in sequence.
Example: Forward external port 80 to internal server 192.168.1.2:8080.
Step 1: configure the PREROUTING rule
Redirect incoming traffic:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:8080
Step 2: add a FORWARD rule
Allow the redirected traffic through your firewall:
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 8080 -j ACCEPT
Step 3: configure MASQUERADE
Configure masquerading for proper return traffic handling.
Replace ens33 with your actual outgoing interface name:
iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
Step 4: verify your configuration
iptables -t nat -L -v -n
iptables -L FORWARD -v -n
The packet counters should increment when traffic passes through these rules.
Common port forwarding scenarios
HTTP and HTTPS traffic
Forward standard web traffic from external ports to an internal web server:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 192.168.1.10:443
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 443 -j ACCEPT
SSH access to internal servers
Forward SSH connections to an internal server. Consider using non-standard ports to reduce automated attacks:
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.5:22
iptables -A FORWARD -p tcp -d 192.168.1.5 --dport 22 -j ACCEPT
This configuration forwards external port 2222 to the internal SSH port 22.
Warning: Maintain alternative access (console access, secondary SSH port) to prevent lockout if forwarding rules malfunction.