iptables redirige las solicitudes externas a 127.0.0.1

41

Tengo un servicio que se ejecuta en 127.0.0.1 con el puerto 2222. Necesito reenviar todas las solicitudes a 192.168.2.2:2222 (fuera de IP) solo desde la subred 192.168.1.0/24 a 127.0.0.1:2222.

Estoy tratando de usar esto, pero no funciona.

$ iptables -t nat -I PREROUTING -p tcp -d 192.168.1.0/24 --dport 2222 -j DNAT --to-destination 127.0.0.1:2222

¿Cómo puedo hacer que esto funcione?

UPD: Editar esquema de direcciones.

SimWhite
fuente
Necesitamos alguna aclaración. ¿De dónde viene el tráfico? ¿A dónde va originalmente el tráfico? ¿A dónde debe ir el tráfico? Mientras lo leo, desea que el tráfico de 192.168.1.0/24 a 127.0.0.1:2222 se redirija a 12.23.34.45:2222. Pero la respuesta de Warren supone que desea que el tráfico de 192.168.1.0/24 a 12.23.34.45:2222 se redirija a 127.0.0.1:222
Patrick
1
El tráfico proviene de la subred 192.168.1.0/24 a 192.168.2.2:2222 y debe traducirse al servicio en 127.0.0.1:2222. Estoy corregido esquema de direcciones.
SimWhite
1
¿Desea una regla que permita el tráfico al puerto 2222en la interfaz de bucle invertido desde la subred 192.168.1.0/24? Ese no es solo un tipo de configuración de regla única. Ver aquí: debuntu.org/…
slm
Sí. Según tengo entendido, ¿debo agregar la regla masq? El reenvío de IP ya está habilitado, por supuesto.
SimWhite
¿Por qué no ejecutarlo en una IP "real" y filtrar el tráfico proveniente de fuentes no deseadas? Para eso están los firewalls, esencialmente ...
vonbrand

Respuestas:

60

La regla de iptables que está utilizando funcionará, pero hay un cambio adicional que debe hacer:

sysctl -w net.ipv4.conf.eth0.route_localnet=1

(reemplazar eth0con el nic 192.168.2.2reside en)

Por defecto, este valor es 0, que le indica al núcleo que no enrute el tráfico externo destinado a 127.0.0.0/8. Esto es solo por seguridad ya que dicho tráfico no es normal.


Nota adicional: su regla actual de iptables es demasiado amplia. Su regla se especifica -d 192.168.1.0/24 --dport 2222como la coincidencia de destino, lo que significa que si su máquina intenta comunicarse con otro host en el puerto 2222 (es decir, el tráfico de salida), también se redirigirá. Necesitas cambiar la -dcoincidencia -d 192.168.2.2o agregar -i eth0(o lo que sea que sea tu nic).

Patricio
fuente
8
Esta información es sorprendentemente difícil de encontrar.
Wren T.
Sí, información muy valiosa y difícil de encontrar. ¡Gracias! Pero no tengo route_localnet. ¿Ha habido otros nombres para ello? (en Linux 2.6.30) ls /proc/sys/net/ipv4/conf/lan/: accept_redirects arp_accept arp_filter arp_notify disable_policy force_igmp_version log_martians medium_id proxy_arp secure_redirects shared_media accept_source_route arp_announce arp_ignore bootp_relay disable_xfrm reenvío mc_forwarding promote_secondaries rp_filter send_redirects tag
imz - Ivan Zakharyaschev
Ya veo, el parcheroute_localnet es más reciente (7 de junio de 2012) que mi kernel (2.6.30-std-def-alt15 # 1 SMP Lun Dec 14 08:45:48 UTC 2009). Ok, simplemente lograré el reenvío de puertos deseado (de afuera hacia adentro) con un proceso de reenvío como netcat( nc) xinetd, o las opciones de reenvío de puertos de ssh(este último es ineficaz y estúpido, por supuesto, pero lo menciono, porque, bueno, esta posibilidad está ahí).
imz - Ivan Zakharyaschev
2
Mis 2 centavos: puede habilitar este parámetro para todas las interfaces consysctl -w net.ipv4.conf.all.route_localnet=1
Dmitriusan
Como otros, esta información fue difícil de obtener. Gracias, si hubiera encontrado esto antes, me habría ahorrado una tonelada de esfuerzo.
Stephen Simpson,
3

Puede redirigir a localhost pero no a loopback (127.0.0.0/8). Loopback es una escapatoria. Tienes que redirigir a una de tus interfaces reales. Intenta usar REDIRECT.

iptables -t nat -A PREROUTING ..... -j REDIRECT --to-port 222

dresende
fuente
Esta es probablemente la mejor respuesta sin el sysctl voodo ...
Lester Cheung
Todavía no ayuda si el puerto 222 solo se escucha en localhost (la regla no cambiará la dirección de destino)
sanmai
En ese caso, use-j DNAT --to-destination w.x.y.z:222
dresende
2

¿Qué pasa si la respuesta correcta con route_localnetno funciona? ..

Si su kernel no incluye el parche pararoute_localnet , entonces ... ¡actualice el kernel!

O bien, hay otras formas de reenviar el tráfico que llega a una interfaz a otro puerto en otra interfaz (en particular, a localhost) ejecutando un proceso que escuche en la interfaz externa y reenvíe el tráfico.

netcat( nc), xinetdy ssh(y tal vez más) son todos ejemplos de programas capaces de hacer esto (aunque elegir sshsería extraño e ineficaz).

He escrito una configuración xinetdpara esto. Ahora este servicio aparece automáticamente:

# cat /etc/xinetd.d/z-from-outside 
# default: off
# description: Forward connections to the z port.
service z-from-outside
{
    disable         = no
    socket_type     = stream
    type        = UNLISTED
    wait            = no
    user            = nobody
    bind        = vaio.ob
    port        = 7070
    redirect    = localhost 7070
}
# 

( vaio.obes el nombre de este host en la interfaz de red externa).

Después de un service xinetd reload, verifiquemos que está escuchando:

# lsof -i -P | fgrep 7070
xinetd    556      root    6u  IPv4 1797906      0t0  TCP vaio.ob:7070 (LISTEN)
sshd    27438 tun_zzoom    4u  IPv4 1059100      0t0  TCP localhost.localdomain:7070 (LISTEN)
# 

Y de hecho, las conexiones pasan.

imz - Ivan Zakharyaschev
fuente