In this setup, we have:
- Public interface (eth1) with IP x.x.x.x
- Private interface (eth2) with IP 192.168.1.1
- Internal server at 192.168.1.2
First, ensure IP forwarding is enabled in the kernel:
echo 1 > /proc/sys/net/ipv4/ip_forward
To make this persistent across reboots, edit /etc/sysctl.conf
:
net.ipv4.ip_forward = 1
Then apply the changes:
sysctl -p
Set up basic NAT for outgoing traffic:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -A FORWARD -i eth1 -o eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth2 -o eth1 -j ACCEPT
For SSH forwarding (port 22):
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 22 -j DNAT --to-destination 192.168.1.2:22
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 22 -j ACCEPT
For HTTP forwarding (port 80):
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 80 -j ACCEPT
Check your rules with:
iptables -t nat -L -n -v
iptables -L -n -v
Test connectivity from an external machine:
ssh user@x.x.x.x # Should connect to 192.168.1.2
curl http://x.x.x.x # Should reach web server on 192.168.1.2
Save your iptables rules:
service iptables save
Or on CentOS 6:
iptables-save > /etc/sysconfig/iptables
- Verify the destination server's firewall is disabled
- Check that the internal server's gateway points to 192.168.1.1
- Use tcpdump to monitor traffic flow:
tcpdump -i eth1 port 22 or port 80
- Check kernel logs for NAT errors:
dmesg | grep NAT
Here's my setup:
- Public interface (eth1): x.x.x.x (public IP)
- Private interface (eth2): 192.168.1.1
- Internal server: 192.168.1.2
First ensure IP forwarding is enabled:
echo 1 > /proc/sys/net/ipv4/ip_forward
To make this persistent across reboots, add to /etc/sysctl.conf
:
net.ipv4.ip_forward = 1
For SSH (port 22):
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 22 -j DNAT --to-destination 192.168.1.2:22
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 22 -j ACCEPT
For HTTP (port 80):
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 80 -j ACCEPT
Masquerading for outgoing traffic:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Allow established connections:
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
On CentOS 6.4:
service iptables save
From an external machine:
ssh -v x.x.x.x
curl http://x.x.x.x
Problem: Connection timeout
Solution: Check if forwarding is enabled and firewall allows traffic
Problem: Can connect but gets refused
Solution: Verify the target service is running on the internal server
Example forwarding multiple ports:
iptables -t nat -A PREROUTING -i eth1 -p tcp -m multiport --dports 22,80,443 -j DNAT --to-destination 192.168.1.2
iptables -A FORWARD -p tcp -d 192.168.1.2 -m multiport --dports 22,80,443 -j ACCEPT
- Limit source IPs when possible:
iptables -t nat -A PREROUTING -i eth1 -p tcp -s 1.2.3.4 --dport 22 -j DNAT --to-destination 192.168.1.2:22
- Consider using rate limiting for SSH
- Implement fail2ban for additional protection