Table of Contents

Redirección de puertos en GNU/Linux

iptables: Reglas para redirección de puerto

Funciona en local y desde el exterior (Puerto 80 redirigido al 8000).

Redirigir un puerto ya sea interno o de una petición saliente a un puerto interno (REDIRECT)

# Puertos en local
iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8000
iptables -t nat -I OUTPUT -p tcp -o lo --dport 80 -j REDIRECT --to-ports 8000 # localhost:80 > localhost:8000
#iptables -t nat -I OUTPUT -p tcp -o eth0 --dport 80 -j REDIRECT --to-ports 8000 # Interfaz eth0 Puerto 80 > Interfaz eth0 Puerto 8000
 
# Puertos en destino remoto. Las conexiones a la IP 198.98.49.27:80 son redirigidas al puerto local 8000.
iptables -t nat -I PREROUTING --src 0/0 --dst 198.98.49.27 -p tcp --dport 80 -j REDIRECT --to-ports 8000
iptables -t nat -I OUTPUT --src 0/0 --dst 198.98.49.27 -p tcp --dport 80 -j REDIRECT --to-ports 8000

Redirigir un puerto, ya sea interno o de una petición saliente, a un puerto y dirección externa (DNAT).

# El tráfico saliente a la dirección 198.98.49.27:80 es redireccionado a 71.76.199.181:443
iptables -t nat -A  PREROUTING -p tcp -d 198.98.49.27 --dport 80 -j DNAT --to 71.76.119.181:443
iptables -t nat -A OUTPUT -p tcp -d 198.98.49.27 --dport 80 -j DNAT --to 71.76.119.181:443
 
# También podría usarse para redirecciones en local, como se hizo anteriormente con REDIRECT. Pera para redirecciones externas no es posible el uso de REDIRECT, únicamente DNAT.

Si se quiere guardar los cambios (/etc/sysconfig/iptables).

iptables-save

Redirección de puertos con iptables en Internet / Bloquear el acceso al puerto que recibe la redirección.

Si se usa redirección de puertos y además se tiene iptables configurado para denegar todo excepto el acceso a unos pocos puertos, hay que tener en cuenta que se deben tomar acciones complementarias.

En nuestro ejemplo tenemos una redirección, todo lo que vaya al puerto 80 se redirige al puerto 8080. Si unicamente está permitido desde el exterior el puerto 80 y no el puerto 8080, la redirección de puertos mediante iptables solo funcionará en local. Es decir, los clientes que accedan al puerto 80 no obtendrán la redirección.

La opción más simple sería usar en ese puerto socat u otro software (ej. Nginx) para redireccionar puertos. Pero si se quiere seguir con iptables y bloquear un puerto configurado para recibir redirecciones, se puede hacer lo siguiente.

1.- Se permite el tráfico al puerto que recibe redirecciones.

2.- Se crean las redirecciones. (Como las redirecciones pertenen a la tabla NAT, se podría hacer esto en cualquier otro momento.)

3.- Se crea una regla mangle para el puerto que no queremos esté accesible, en nuestro caso 8080.

iptables -t mangle -A PREROUTING -p tcp --dport 8080 -j MARK --set-mark 1

4.- Guardamos la configuación de iptables.

5.- Agregamos antes de la linea del paso 1 la siguiente regla de iptables.

#-A INPUT -m mark --mark 1 -j REJECT DROP # Si se recibe un escaneo de puertos,la salida sobre el estado del puerto será "filter"
-A INPUT -p TCP -m mark --mark 1 -j REJECT --reject-with tcp-reset # Si se recibe un escaneo de puertos,la salida sobre el estado del puerto será "close".

Veamos como quedaría un fichero de configuración con estos pasos dados.

############ MANGLE
*mangle
:PREROUTING ACCEPT [289:84029]
:INPUT ACCEPT [241:77872]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [234:77141]
:POSTROUTING ACCEPT [234:77141]
-A PREROUTING -p tcp -m tcp --dport 8080 -j MARK --set-xmark 0x1/0xffffffff
COMMIT
############ NAT
*nat
:PREROUTING ACCEPT [792:128694]
:INPUT ACCEPT [106:30853]
:OUTPUT ACCEPT [169:62244]
:POSTROUTING ACCEPT [169:62244]
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A OUTPUT -o lo -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
COMMIT
############ FILTER
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [4655:1541094]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
#-A INPUT -m mark --mark 1 -j REJECT DROP                                   
-A INPUT -p TCP -m mark --mark 1 -j REJECT --reject-with tcp-reset
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

socat

Redireccionar el puerto 4343 local al puerto 443 de una IP externa.

socat TCP4-LISTEN:443,fork TCP4:X.X.X.X:443
 
# Es posible concatenar varias redireccicones de la siguiente manera.
socat TCP4-LISTEN:443,fork TCP4:X.X.X.X:443|socat TCP4-LISTEN:8080,fork TCP4:X.X.X.X:80