reglas de iptables para permitir el tráfico HTTP a un solo dominio

20

Necesito configurar mi máquina para permitir el tráfico HTTP hacia / desde serverfault.com solamente. Todos los demás sitios web, puertos de servicios no son accesibles. Se me ocurrieron estas reglas de iptables:

#drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

#Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

No funciona muy bien:

  • Después de soltar todo y pasar a la regla 3:

    iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT

Me sale este error:

iptables v1.4.4: host/network `serverfault.com' not found
Try `iptables -h' or 'iptables --help' for more information.

¿Crees que está relacionado con DNS? ¿Debería permitirlo también? ¿O debería simplemente poner las direcciones IP en las reglas? ¿Crees que lo que estoy tratando de hacer podría lograrse con reglas más simples? ¿Cómo?

Agradecería cualquier ayuda o pistas sobre esto. ¡Muchas gracias!

Zenet
fuente
2
No olvides sstatic.net y otros. serverfault.com no proviene completamente de serverfault.com
Zoredache
¿Se puede ejecutar un proxy en otro sistema? Esta es la mejor / más fácil solución: serverfault.com/questions/215134
mattdm

Respuestas:

29

Con las reglas de IPTables, el orden importa. Las reglas se agregan y se aplican en orden. Además, al agregar reglas manualmente, se aplican de inmediato. Por lo tanto, en su ejemplo, los paquetes que pasan por las cadenas INPUT y OUTPUT comienzan a descartarse tan pronto como se establece la política predeterminada. Esto también es, por cierto, por qué recibió el mensaje de error que recibió. Lo que está sucediendo es esto:

  1. Se aplica la política DROP predeterminada
  2. IPTables recibe un nombre de host como destino
  3. IPTables intenta una búsqueda de DNS en 'serverfault.com'
  4. La búsqueda de DNS está bloqueada por la acción DROP

Si bien las opciones de origen / destino aceptarán nombres de host, se desaconseja encarecidamente. Para citar la página del manual,

Los nombres de host se resolverán solo una vez, antes de que la regla se envíe al kernel. Tenga en cuenta que especificar un nombre para resolver con una consulta remota como DNS es una muy mala idea.

Slillibri golpeó el clavo en la cabeza que su respuesta, se perdió la regla ACEPTACIÓN DNS. En su caso, no importará, pero generalmente establecería la política predeterminada más adelante en el proceso. Lo último que desea es trabajar de forma remota y permitir SSH después de activar una denegación predeterminada.

Además, dependiendo de su distribución, debería poder guardar sus reglas de firewall de modo que se apliquen automáticamente en el momento de inicio.

Sabiendo todo eso y reorganizando su script, esto es lo que recomendaría.

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP
Scott Pack
fuente
3
Hermosa, bien elaborada respuesta.
JakeRobinson
1
Te lo agradezco, aunque también debes haber perdido mi error. Ups
Scott Pack
3
En realidad, puede colocar sus iptables -Pdeclaraciones en cualquier parte de su secuencia de comandos, ya que las políticas de cadena solo se aplican cuando los paquetes "se caen" al final de una cadena. Usualmente pongo las declaraciones de política (típicamente DROPpolíticas) en la parte superior de mis scripts de iptables.
Steven lunes
1
@ Steven: Tienes toda la razón. El OP parece estar escribiéndolos de forma interactiva. Supongamos que está conectado a su host a través de SSH y su primera regla es para la política DROP. Su conexión SSH se cortará antes de que pueda escribir más reglas. Este es el mismo problema de tiempo, si es una manifestación diferente, de lo que se encontró.
Scott Pack
Gracias. Estaba intentando esto. Pero no funcionó sin agregar sudo iptables -I OUTPUT 1 -o lo -j ACCEPT. ¿No debería ser eso agregado?
Kiran
7

Añadir

iptables -A OUPUT -p udp --dport 53 -j ACCEPT

para permitir búsquedas de DNS.

slillibri
fuente
5

Este tipo de requisito puede manejarse mejor con un proxy y / o filtro web. Dansgaurdian se puede configurar para hacer esto. Deberá usar las reglas NAT para forzar su tráfico a través del filtro.

El uso de iptables para filtrar permitirá cualquier sitio disponible desde las direcciones IP relevantes. Esto normalmente es un pequeño subconjunto de toda la web.

BillThor
fuente
1
Totalmente de acuerdo con esto. iptableses probablemente la herramienta incorrecta para usar aquí, ya que no se trata particularmente bien con los nombres DNS. Un proxy web con la configuración de filtro adecuada es mucho mejor.
Steven lunes
2

Me temo que iptables no funciona a este nivel, solo le importa la dirección IP, no el nombre de host. Si desea bloquear el acceso a otros hosts virtuales de nombre en la misma ip, deberá considerar la colocación de archivos .htaccess.

Niall Donegan
fuente
La cuestión es que cuando intento la regla 3 sin "soltar todo", ¡funciona bien con iptables!
Zenet
2
hmm, leí mal la pregunta. Correcto, lo que sucede en segundo plano es que iptables resolverá serverfault.com a 64.34.119.12 (vea la respuesta de slillibri para comprender por qué la resolución no estaba funcionando). Sin embargo, debido a que iptables no entiende los nombres de host, y solo permite la ip, podrá conectarse a cualquier sitio web en esa ip, si tiene varios sitios.
Niall Donegan
2
@Emily, puede funcionar bien, ya que se agrega la regla, pero si la dirección IP de serverfault.com cambia, no se permitirá el tráfico. Permitir un sitio como google.com que tiene cientos de direcciones que se cambian con frecuencia no funcionaría en absoluto.
Zoredache
1

Necesita configurar esto en su servidor web. iptables es un filtro de paquetes. Las transacciones HTTP envían el nombre del sitio (es decir, stackoverflow) como parte de la carga útil de TCP (es decir, no como parte del encabezado TCP, que es lo que iptables lee fácilmente).

Teniendo en cuenta eso, y el hecho de que las transacciones HTTP seguramente se distribuirán en múltiples paquetes (es decir, no puede coincidir con una cadena en el encabezado HTTP), esto es mucho mejor manejado por la configuración de su servidor web o por un proxy en el frente de eso.

Sería útil saber el razonamiento detrás de esto, hay un par de otras alternativas:

  1. Redireccionar a la URL correcta si ingresan la URL incorrecta (por ejemplo, redirigir a stackoverflow.com si ingresan a www.stackoverflow.com)
  2. Dígale a su servidor web que no sirva hosts que no sean stackoverflow.com
  3. Coloque el sitio en una IP separada que nada más resuelva y solo haga que su servidor web lo escuche.
Philip Reynolds
fuente
Hola Phil, no estoy seguro de entender qué servidor web. No tengo un servidor web. Estoy haciendo esta configuración en mi computadora.
Zenet