How to Forward HTTP/SSH Ports to Internal Server Using iptables on CentOS 6.4 Router


8 views

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