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