Puede que se de el caso de que halles algún error en tu código o trabajo, recuerda probar siempre en un entorno de testing antes añadir el código al trabajo final.
Solución:
Solución 1:
Este esquema debería ayudarlo a comprender cómo se realiza el manejo de paquetes:
Las reglas de filtro / ENTRADA solo ven los paquetes después de que fueron NATed en nat / PREROUTING, por lo que por defecto no se puede diferenciar entre recibir un paquete en el puerto 8080 porque un cliente lo envió allí directamente, de recibir un paquete en el puerto 8080 porque un cliente lo envió en el puerto 80 que luego fue redirigido al puerto 8080. En ambos casos, ven un paquete que llega al puerto 8080. Por lo tanto, necesita información adicional para poder diferenciar esos dos casos.
Lo primero es lo primero: esta regla debe eliminarse ya que es inútil:
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
porque, como se explicó, filter / INPUT no verá un paquete en el puerto 80: ahora está llegando al puerto 8080. No confíe tcpdump
ciegamente aquí: como se ve en el esquema, tcpdump
(AF_PACKET) ve los paquetes antes de todo esto, por lo que verá el puerto 80.
-
Puedes usar iptables’s
conntrack
coincidir que consulta el sistema de seguimiento de conexión de netfilter y, por lo tanto, tiene acceso a la información que falta: para este caso, si el paquete entrante actual es parte de una conexión que se sometió a una transformación DNAT o no, utilizando--ctstate DNAT
(REDIRECT es un caso especial de DNAT, al igual que MASQUERADE es un caso especial de SNAT). Hay otras opciones para este partido como--ctorigdstport
etc., que probablemente puedan lograr resultados similares.Solo pondré las reglas importantes sobre este caso, en lugar de todas, para ilustrar la explicación. Úselos, cuando sea necesario, en el lugar correcto.
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
probablemente justo después del genérico
... ESTABLISHED,RELATED -j ACCEPT
línea:iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate DNAT -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j DROP
(o no agregue esta última regla DROP si más adelante hay una regla de descarte general).
La primera regla INPUT coincidirá con el tráfico que llega al puerto 8080 que fue DNATed (aquí desde que llegó inicialmente al puerto 80), mientras que la segunda eliminará lo que queda por llegar al puerto 8080: intentos de conexión directa.
Nota: si se pregunta por qué
state
partido y elconntrack
partido se ve similar, questate
ha sido reemplazado porconntrack
. En realidad, internamente el módulo del kernelxt_conntrack.ko
maneja elstate
coincidir además de laconntrack
Match, para compatibilidad con versiones anteriores. -
Otro método para transmitir esta información es usar una marca de paquete, que es un método más genérico y se puede aplicar a muchos otros casos. Es un número arbitrario que marcará el paquete (solo en el kernel, no en el cable) y se puede usar en algunos lugares, incluidas las iptables.
mark
partido para alterar decisiones. Como elMARK
el objetivo no es un terminando regla se puede utilizar antes de la actualREDIRECT
regla. Como se muestran de nuevo en hexadecimal, los configuro también en hexadecimal. El valor es suyo para elegir lo que significa. Aquí 0x80 (que es el decimal 128) transmitirá la información “golpeó el puerto 80 y fue redirigido al puerto 8080” por sí solo, por lo que no es necesario volver a verificar el puerto más tarde, verificar la marca valida todo. Como de costumbre, lo que cuenta es el primer paquete de la conexión: cada uno de los otros paquetes de esta conexión se maneja mediante la regla genérica de estado de conntrack... ESTABLISHED,RELATED -j ACCEPT
.iptables -t nat -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 0x80 iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Después del genérico
... ESTABLISHED,RELATED -j ACCEPT
línea:iptables -A INPUT -m mark --mark 0x80 -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j DROP
También debo advertirle sobre el peligro de usar una regla RECHAZAR sin primero descartar (en lugar de rechazar) los paquetes de estado INVÁLIDOS. Esto puede ocasionar problemas de restablecimiento de conexión aleatorios en ciertos casos raros de congestión cuando los paquetes TCP llegan en el orden incorrecto. Actualmente se está considerando agregar documentación relevante de este problema:
Entonces, en lugar de:
-A INPUT ... -j REJECT
considere usar:
-A INPUT ... -m conntrack --ctstate INVALID -j DROP -A INPUT ... -j REJECT
Solucion 2:
REDIRECT simplemente cambia el número de puerto, por lo que si la conexión fue:
client -> public_addres:80
se vuelve
client -> public_address:8080
Por lo tanto, no podrá bloquear y aceptar al mismo tiempo haciendo lo que está haciendo.
Primero elimine esta regla:
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
Y use DNAT en lugar de REDIRECT, algo como:
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to 127.0.0.1:8080
Aquello podría funcionar.
También puede escuchar solo en 127.0.0.1:8080 (a diferencia de 0.0.0.0:8080).