12. Cortafuegos

Contenido:

12.a. Cortafuegos

Mucha gente piensa a menudo que un cortafuegos (firewall) es la máxima expresión de la seguridad, pero están equivocados. En muchos casos un cortafuegos mal configurado da menos seguridad que no tener uno instalado. Un cortafuegos también es un componente de software y debería tratarse de la misma manera que cualquier otro software, porque puede contener agujeros de seguridad.

¡Así que piénselo antes de implementar un cortafuegos! ¿Realmente lo necesita? Si cree que lo necesita, escriba una directriz sobre cómo debería funcionar, qué tipo de cortafuegos, y cómo debería operar. Pero primero lea esta guía.

Los cortafuegos se usan con dos propósitos:

Básicamente hay tres tipos de cortafuegos:

Un cortafuegos debería ser una máquina dedicada que no ejecute otros servicios (sshd es el único) y asegurada tal como recomienda esta guía.

12.b. Filtrado de paquetes

Todo el tráfico de la red se transmite como paquetes. Grandes cantidades de tráfico se dividen en paquetes pequeños para un mejor manejo y se juntan cuando llegan a su destino. La cabecera de cada paquete contiene la información de cómo y dónde debe ser entregado. Y estas informaciones son exactamente las que un cortafuegos de filtrado de paquetes utiliza. El filtrado se basa en:

En otras palabras, este filtrado se fundamenta en la información de la cabecera del paquete y no en su contenido.

Debilidades:

Ventajas:

Ejemplos de cortafuegos de filtrado de paquetes libres en Linux:

Nota: Se recomienda utilizar iptables. Ipchains es obsoleto.

12.c. Circuit relay

Un circuito de nivel de puerta de enlace es un cortafuegos que valida las conexiones antes de permitir el intercambio de datos. Esto significa que simplemente no permite o deniega paquetes basándose en su cabecera si no que determina si la conexión entre los dos extremos es válida de acuerdo a las reglas configuradas antes de abrir una sesión y permitir que los datos sean intercambiados. El filtrado está basado en:

Todo el tráfico es validado y monitorizado, y el tráfico no deseado se descarta.

Debilidades:

12.d. Aplicación de puerta de enlace

La pasarela de aplicación de puerta de enlace es un "proxy" para aplicaciones, que intercambian datos con los sistemas remotos en nombre de sus clientes. Suele estar a salvo detrás de una DMZ ("zona desmilitarizada": la porción de una red privada que es visible a través del cortafuegos) o de un cortafuegos que no permite conexiones desde el exterior. El filtrado está basado en:

Ventajas:

Debilidades:

Las aplicaciones de pasarela están consideradas la mejor solución segura puesto que no tienen que ser ejecutadas como root y los hosts tras ellos no son accesibles desde Internet.

Ejemplo de una aplicación de pasarela libre:

12.e. Iptables

Para poner en funcionamiento iptables, tiene que estar habilitado en el núcleo. Yo lo he añadido como módulo (la orden iptables lo cargará como se necesita) y he recompilado mi núcleo (pero puede compilarlo embebido, si quiere deshabilitar los Módulos Cargables del Núcleo como se indicaba anteriormente). Para más información al respecto de como configurar su núcleo para iptables vea a Iptables Tutorial Chapter 5: Preparations. Después de que haya compilado su nuevo núcleo (o mientras lo compila) tiene que añadir la orden iptables . Simplemente con emerge iptables ya debería funcionar.

Ahora compruebe que funciona ejecutando iptables -L. Si falla, algo está mal y deberá revisar su configuración una vez más.

Iptables es el nuevo y fuertemente mejorado filtro de paquetes en el núcleo de Linux 2.4.x. Es el sucesor del anterior filtro de paquetes ipchains del núcleo de linux 2.2.x. Una de las más grandes mejoras es que iptables es capaz de realizar filtrado de estado de paquetes. Con el filtrado de estado es posible mantener el registro de cada conexión TCP establecida.

Una conexión TCP consiste en una serie de paquetes que contienen información respecto la dirección IP origen, la IP de destino, puerto de origen, puerto de destino, y un número de secuencia para que los paquetes puedan juntarse sin perder datos. TCP es un protocolo orientado a la conexión en contraste a UDP que es "sin conexión".

Examinando la cabecera del paquete TCP, un filtro de estado de paquetes puede determinar si un paquete TCP recibido es parte de una conexión ya establecida o no y decidir si aceptarlo o rechazarlo.

Es posible engañar a un filtro de paquetes que no verifique el estado de los mismos para que acepte paquetes que deberían ser desechados si se manipula la cabecera del paquete TCP. Esto puede hacerse alterando el indicador SYN u otros indicadores en la cabecera TCP para fabricar un paquete malicioso que parezca formar parte de una conexión establecida (puesto que el filtro de paquetes por si mismo no hace un seguimiento de la conexión). Con un filtro de estado de paquetes es posible descartar aquellos paquetes que no formen parte de una conexión ya establecida. Esto detendrá también la posibilidad de "escaneos pasivos", un tipo de exploración de puertos en la cual quien realiza la exploración envía paquetes con indicadores que están lejos de ser registrados por un cortafuegos ordinario.

Iptables proporciona otras prestaciones como NAT (Network Address Translation) y limitación de tasas. La limitación de tasas es muy práctica para prevenir ciertos ataques DoS ("Denial of Service", denegación de servicio) como las inundaciones SYN ("SYN floods")

Una conexión TCP se establece con una "conversación en tres fases". Para iniciar la conexión TCP la parte de cliente envía un paquete al servidor con el flag SYN habilitado. Cuando el servidor recibe el paquete con el SYN responde enviando un paquete SYN+ACK de vuelta al cliente. Entonces el SYN+ACK es recibido en el cliente que responde con un tercer paquete ACK reconociendo la conexión.

Un ataque de inundación SYN se realiza enviando paquetes SYN de forma que no se responda el correspondiente paquete SYN+ACK. El cliente puede crear un paquete con una dirección IP origen falsa puesto que no necesita la respuesta. El sistema del servidor añadirá una entrada en la cola de las conexiones pendientes de establecer cuando se reciba el paquete SYN y esperará a recibir el paquete final ACK antes de borrar esta entrada de la cola. La cola tiene un número limitado de posiciones (slots) y si todas estas posiciones están ocupadas no podrá abrir nuevas conexiones. Si el paquete ACK no se recibe antes de un tiempo determinado la entrada se borrará automáticamente de la cola. Este tiempo de espera es variable, pero normalmente es de 30 a 60 segundos o incluso más. La parte de cliente inicia el ataque enviando gran número de paquetes SYN con diferentes IP origen y enviándolos a la IP objetivo todo lo rápido que pueda y de ese modo llenará la cola de las conexiones pendientes de establecer y por tanto impedirá que otros clientes establezcan una conexión legítima con el servidor.

Aquí es donde la limitación de tasas se vuelve útil. Es posible limitar la tasa de paquetes SYN aceptados usando -m limit --limit 1/s. Esto limitará el número de paquetes SYN aceptados a uno por segundo y por tanto evitará el riesgo de inundaciones SYN en nuestros equipos.

Nota: Otra opción para prevenir inundaciones SYN es SYN cookies, que permite a su ordenador responder a paquetes SYN sin llenar el espacio de la cola de conexiones. Las galletas (cookies) SYN pueden ser habilitadas en la configuración del Núcleo de Linux, pero hoy en día todavía están consideradas como experimentales.

¡Ahora algunas prácticas!

Cuando iptables se activa en el núcleo proporciona 5 lugares donde especificar las reglas. Estos lugares se llaman INPUT, OUTPUT, FORWARD, PREROUTING y POSTROUTING. Cada uno de ellos es a su vez una cadena que consiste en una serie de reglas. Cada regla especifica una cabecera de paquete con la que compararse, después indica qué hacer con el paquete. Si la regla no coincide con el paquete se consulta la siguiente regla en la cadena.

Puede añadir reglas directamente en estas 5 cadenas principales o crear nuevas cadenas y añadirlas como si fueran reglas a una cadena existente. Iptables admite las siguientes opciones.

Opción: Descripción:
-A Añadir
-D Borrar
-I Insertar
-R Reemplazar
-L Listar
-F Borra todas las reglas de una o de todas las cadenas
-Z Pone a cero los contadores en una o en todas las cadenas
-C Verifica ese paquete en la cadena
-N Crea una nueva cadena definida por el usuario
-X Borra una cadena definida por el usuario
-P Cambia la forma de actuar de una cadena respecto un objetivo
-E Cambia el nombre de la cadena
-p Protocolo
-s Dirección o máscara de origen
-d Dirección o máscara de destino
-i Nombre de entrada (nombre ethernet)
-o Nombre de salida (nombre ethernet)
-j Salto (objetivo de la regla)
-m Coincidencia extendida (puede usar una extensión)
-n Salida numérica para las direcciones y puertos
-t Tabla a manipular
-v Modo de información detallada
-x Expande los números (muestra valores exactos)
-f Solo hacer coincidir el segundo fragmento o posteriores
-V Versión de paquete
--line-numbers Muestra los números de línea al listar

Primero trataremos de bloquear todos los paquetes ICMP en nuestra máquina, solo para familiarizarnos con iptables.

Listado de Código 5.1: Bloquear todos los paquetes ICMP

# iptables -A INPUT -p icmp -j DROP

Primero indicamos la cadena o regla donde debe ser añadida, después el protocolo de los paquetes, y finalmente el destino. El destino puede ser el nombre de una cadena definida por el usuario o uno de los siguientes ACCEPT, DROP, REJECT, LOG, QUEUE, MASQUERADE. En este ejemplo usamos DROP que desechará el paquete sin responder al cliente.

Nota: El destino LOG es del tipo conocido como "non-terminating". Si un paquete concuerda con una regla con el destino LOG, en lugar de para la evaluación, el paquete continua siendo comparado con las otras reglas. Esto le permite registrar el paquete mientras se se procesa con normalidad.

Ahora intente ping localhost. No recibirá ninguna respuesta puesto que iptables desechará todos los paquetes ICMP entrantes. No podrá hacer ping a otras máquinas puesto que los paquetes ICMP de respuesta también son desechados. Ahora elimine la cadena para permitir el tráfico ICMP de nuevo.

Listado de Código 5.2: Elimina todas las reglas

# iptables -F

Ahora veamos el filtrado de paquetes de estado en iptables. Si buscamos activar una inspección de estado en los paquetes entrantes en eth0, podríamos activarlo con la orden:

Listado de Código 5.3: Acepta paquetes originados en una conexión entrante o ya establecida

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Esto aceptará cualquier paquete de una conexión ya establecida o con relación a la cadena INPUT. También puede desechar cualquier paquete que no esté en la tabla de estado indicando iptables -A INPUT -i eth0 -m state --state INVALID -j DROP justo antes de la orden anterior. Esto habilita el filtrado de estado de paquetes en ipetables cargando la extensión "estate". Si quiere permitir a otros conectarse a su máquina puede usar el indicador --state NEW. Iptables contiene algunos módulos con propósitos diversos. Algunos de ellos son:

Módulo/Concordancia Descripción Opciones extendidas
mac Comprueba la extensión para los paquetes que provienen de esa dirección mac. --mac-source
state Activa la inspección de estado --state (los estados son ESTABLISHED,RELATED, INVALID, NEW)
limit Limitación de tasas --limit, --limit-burst
owner Intenta comparar varias características del creador de los paquetes --uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean Varios chequeos aleatorios en los paquetes

Intentemos crear una cadena definida por el usuario y añadirla a una de las ya existentes:

Listado de Código 5.4: Creación de una cadena definida por el usuario

  (Creamos una nueva cadena con una regla)
# iptables -X micadena
# iptables -N micadena
# iptables -A micadena -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
(El comportamiento por defecto es permitir todo el tráfico saliente. El entrante se desecha.)
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP
(Y la añadimos a la cadena INPUT)
# iptables -A INPUT -j micadena

Aplicando la regla a la cadena input obtenemos la directriz: Se permite todos los paquetes salientes y se desechan todos los entrantes.

Puede encontrar más documentación en Documentación sobre netfilter/iptables.

Veamos ahora un ejemplo completo. En este caso el comportamiento de mi cortafuegos/puerta de enlace indica:

Listado de Código 5.5: /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#interior
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#exterior
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net
}

rules() {
  stop
  ebegin "Estableciendo las reglas internas"

  einfo "Estableciendo la regla por defecto para drop"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  # Regla por defecto
  einfo "Creando las cadenas de estado"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \
      "Bad packet from ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  # Tráfico ICMP
  einfo "Creando la cadena icmp"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  # Tráfico entrante
  einfo "Creando la cadena para el tráfico ssh entrante"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  #Protección "Flood"
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

  # Tráfico saliente
  einfo "Creando la cadena para el tráfico ssh saliente"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Creando la cadena para el tráfico DNS saliente"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \
     -j ACCEPT

  einfo "Creando la regla para el tráfico http/https saliente"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  # Detección de scanners de puertos
  einfo "Creando la cadena de detección de scanner de puertos"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # Aplicando y añadiendo estados no válidos a las cadenas
  einfo "Aplicando cadenas en INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -p icmp -j icmp_allowed
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Aplicando cadenas en FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -p icmp -j icmp_allowed
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Aplicando cadenas en OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -p icmp -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  # Permite a los clientes enrutar a través de NAT (Network Address
  # Translation)
  $IPTABLES -t nat -A POSTROUTING -o $OINTERFACE -j MASQUERADE
  eend $?
}

start() {
  ebegin "Iniciando el cortafuegos"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} no existe. Usando las reglas por defecto."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Parando el cortafuegos"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Estatus"
  $IPTABLES -L -n -v --line-numbers
  einfo "Estatus NAT"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Estableciendo reglas 'panic'"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Guardando las reglas del cortafuegos"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Restaurando las reglas del cortafuegos"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      restaura si existe y si no fuerza las reglas"
  echo "stop)       elimina todas las reglas y lo permite todo"
  echo "rules)      fuerza el establecimiento de nuevas reglas"
  echo "save)       gruada la configuración en ${FIREWALL}"
  echo "restore)    restaura la configuración desde ${FIREWALL}"
  echo "showstatus) muestra el estatus"
}

Algunos consejos para cuando cree un cortafuegos:

  1. Cree su directriz de cortafuegos antes de implementarlo
  2. Hágalo simple
  3. Conozca cómo trabajan los protocolos (lea lo más relevante de RFC (Request For Comments))
  4. Tenga bien presente que un cortafuegos solo es otro software ejecutándose como root
  5. Compruebe su cortafuegos

Si piensa que iptables es difícil de comprender o le lleva mucho tiempo configurar un cortafuegos decente, puede usar Shorewall. Básicamente utiliza iptables para generar las reglas del cortafuegos, pero se concentra en reglas y no en protocolos específicos.

12.f. Squid

Squid es un servidor proxy muy potente. Puede filtrar el tráfico atendiendo a: tiempo, expresiones regulares en la ruta/URI, dirección IP de origen y destino, dominio, navegador, nombre de usuario autentificado, mime-type y número de puerto (protocolo). Probablemente olvido algunas características, pero puede ser pesado cubrir aquí la lista entera de características.

En el ejemplo siguiente he añadido un filtrado de pancartas ("banners") en lugar de un filtro basado en sitios porno. La razón de esto es que Gentoo.org no debe ser catalogado como un sitio pornográfico. Y yo no quiero malgastar mi tiempo intentando buscar algunos sitios buenos.

En este caso, mi directriz de acceso es:

Esto se implementa en 4 pasos fáciles.

Listado de Código 6.1: /etc/squid/squid.conf

# Enlaza con una IP y un puerto
http_port 10.0.2.1:3128

# Configuración standard
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# Añade listas de control de acceso básico
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# Añade quien puede acceder a este servidor proxy
acl localnet src 10.0.0.0/255.255.0.0

# Y los puertos
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# Añade una lista de control de acceso basada en
# expresiones regulares mediante urls
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# Añade una lista de control de acceso basada en día y hora
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

# Permite el acceso administrativo desde localhost
http_access allow manager localhost
http_access deny manager

# Solo permite purgar peticiones desde localhost
http_access allow purge localhost
http_access deny purge

# Deniega peticiones hacia puertos desconocidos
http_access deny !Safe_ports

# Deniega CONNECT a otros puertos distintos de SSL
http_access deny CONNECT !SSL_ports

# Mis propias reglas

# Añade una página para ser mostrada cuando
# se elimina una pancarta
deny_info NOTE_ADS_FILTERED url_ads

# Entonces lo rechaza
http_access deny url_ads

# Deniega todos los archivos
http_access deny archives

# Restringe el acceso a las horas de trabajo
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# Deniega el resto
http_access deny all

Después complete los ficheros que no quiere que sus usuarios descarguen. Yo he indicado zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz and z files.

Listado de Código 6.2: /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[Gg][Zz]$
\.[Zz]$

Nota: Por favor, tenga en cuenta los [] con mayúsculas y minúsculas en cada carácter. Esto sirve para que alguien no se salte las reglas accediendo a un fichero llamado AvI en lugar de avi.

Ahora vamos a añadir las expresiones regulares para identificar a las pancartas. Probablemente se puede ser más creativo.

Listado de Código 6.3: /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

Y como último paso, queremos que este fichero sea mostrado cuando una pancarta sea eliminada. Básicamente es un medio archivo html con una imagen gif transparente de 4x4 pixels.

Listado de Código 6.4: /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif">
<TITLE>ERROR: La URL solicitada no puede ser recuperada</TITLE>
</HEAD>
<BODY>
<H1>Anuncio filtrado</H1>

Nota: No cierre las etiquetas <HTML> <BODY>. Eso lo hará squid.

Como puede ver, Squid tiene muchas posibilidades y es muy efectivo tanto como filtro como proxy. Incluso se pueden usar proxies Squid encadenados para escalar en redes muy grandes. La configuración que he indicado aquí es muy conveniente para una pequeña red de 1 a 20 usuarios.

Pero combinar el filtrado de paquetes (iptables) y una pasarela de aplicaciones (Squid) es probablemente la mejor solución, incluso si Squid está ubicado en un lugar seguro y donde nadie pueda acceder desde el exterior. Continuamos teniendo que preocuparnos de los ataques desde dentro.

Ahora tiene que configurar los navegadores en los clientes para usar el servidor proxy. La puerta de enlace evitará que los usuarios tengan cualquier contacto con el exterior salvo que usen el proxy.

Nota: En Mozilla Firefox se consigue en Edición->Preferencias->Avanzadas->Red.

También se conseguir un proxy transparente usando iptables dirigiendo todo el tráfico saliente a un proxy Squid. Esto se hace añadiendo una regla de forwarding/prerouting en la pasarela:

Listado de Código 6.5: Activa el reenvío de puertos hacia nuestro servidor proxy

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

Nota: Si el proxy se está ejecutando en el host que hace el filtrado de paquetes --y aunque que no se recomienda, puede ser necesario si no tiene suficientes máquinas disponibles-- use un destino REDIRECT en lugar de DNAT (REDIRECT dirige los paquetes al localhost).

12.g. Lecciones aprendidas

Hemos aprendido esto:

  1. Un cortafuegos puede representar un riesgo por si mismo. Un cortafuegos mal configurado es peor que no tenerlo
  2. Cómo configurar una pasarela básica y un proxy transparente
  3. La clave para tener un buen cortafuegos es conocer el protocolo que queremos permitir
  4. Que el tráfico IP puede contener datos no legítimos, por ejemplo los paquetes ICMP pueden llevar una carga oculta
  5. Cómo prevenir un ataque SYN
  6. El filtrado de tráfico HTTP quitando imágenes no adecuadas, descargas de ficheros de virus
  7. Combinar filtros de paquetes y pasarelas de aplicaciones proporcionan mayor control

Entonces si realmente necesita un cortafuegos, cree uno que satisfaga sus necesidades.