Alternative Port Forwarding Methods on Linux When iptables NAT is Unavailable


2 views

Many cloud providers restrict access to kernel modules like iptables-nat for security reasons. When you try running:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:80

You might get errors like:

iptables: No chain/target/match by that name

When kernel-space NAT isn't available, these user-space alternatives work well:

1. socat - The Socket Swiss Army Knife

Simple TCP forwarding example:

socat TCP4-LISTEN:8080,fork TCP4:192.168.1.100:80

For UDP forwarding:

socat UDP4-LISTEN:53,fork UDP4:8.8.8.8:53

2. rinetd - Lightweight Forwarder

Install via package manager then configure /etc/rinetd.conf:

# bindadress bindport connectaddress connectport
0.0.0.0 3306 db.internal.example.com 3306
0.0.0.0 27017 mongodb-replica.example.com 27017

3. HAProxy - Advanced TCP Proxy

Sample configuration for multiple ports:

frontend http-in
    bind *:80
    bind *:443
    default_backend servers

backend servers
    server server1 10.0.0.2:80 check
    server server2 10.0.0.3:443 check

For production systems, you'll want these running as services. Example systemd unit for socat:

[Unit]
Description=Socat port forwarding
After=network.target

[Service]
ExecStart=/usr/bin/socat TCP4-LISTEN:8080,fork TCP4:192.168.1.100:80
Restart=always
User=nobody

[Install]
WantedBy=multi-user.target

User-space forwarding has higher overhead than kernel NAT. Benchmarks typically show:

  • socat: ~5,000 connections/sec
  • rinetd: ~7,000 connections/sec
  • HAProxy: ~50,000 connections/sec

Always:

1. Run forwarders as unprivileged users
2. Implement connection rate limiting
3. Use TCP wrappers where possible
4. Monitor connection counts

Many VPS providers running Virtuozzo/OpenVZ containers disable NAT kernel modules for security reasons. This becomes problematic when you need to forward multiple ports (both TCP and UDP) for applications like game servers, VoIP, or custom services.

Here are proven methods that don't require iptables -t nat:

1. socat - The Multipurpose Relay

socat can forward both TCP and UDP ports with minimal overhead:


# TCP forwarding (local 8080 to remote 192.168.1.100:80)
socat TCP4-LISTEN:8080,fork,reuseaddr TCP4:192.168.1.100:80

# UDP forwarding (local 5353 to remote DNS server)
socat UDP4-LISTEN:5353,fork,reuseaddr UDP4:8.8.8.8:53

2. ncat from nmap Package

Nmap's ncat provides persistent forwarding with logging:


# Persistent TCP forward with logging
ncat -l -p 3389 --sh-exec "ncat 192.168.1.15 3389" --keep-open \
     --log-file /var/log/ncat_rdp.log

3. rinetd - Lightweight Forwarding Daemon

Configure multiple forwards in /etc/rinetd.conf:


# BindAddress BindPort ConnectAddress ConnectPort
0.0.0.0 25565 10.0.0.5 25565
0.0.0.0 27015 10.0.0.6 27015

Then start with rinetd -f -c /etc/rinetd.conf

For bulk port forwarding, consider these approaches:

Port Range Forwarding with xinetd

Create a custom service in /etc/xinetd.d/forwardrange:


service forwardrange
{
    disable = no
    socket_type = stream
    protocol = tcp
    user = nobody
    wait = no
    redirect = 192.168.1.100 20000-30000
    port = 20000-30000
}

Automated Setup Script

Bash script to forward multiple ports from a list:


#!/bin/bash
declare -A ports=(
    ["tcp:80"]="192.168.1.100:8080"
    ["udp:53"]="8.8.8.8:53"
    ["tcp:443"]="192.168.1.101:8443"
)

for port in "${!ports[@]}"; do
    proto="${port%%:*}"
    portnum="${port##*:}"
    target="${ports[$port]}"
    socat ${proto^^}4-LISTEN:${portnum},fork,reuseaddr ${proto^^}4:${target} &
done
  • socat: Best for dynamic setups and testing
  • rinetd: Ideal for production with many static forwards
  • xinetd: Best when needing service management features