domingo 6 de diciembre de 2009

Firewall para un solo host

Creación y ejecucion de iptables al inicio. Activación y desactivación manual del firewall.

Queremos un firewall que se inicie automáticamente al iniciar el sistema, ademas de poder iniciarlo, detenerlo y comprobarlo manualmente. Este script lo llamaremos firewall y Lo guardamos en /etc/init.d/.

#!/bin/sh
##etc/init.d/firewall
#####INICIO SCRIPT FIREWALL IPTABLES####
#simple start-stop INIT script para iptables
#start Inicia y construye el firewall, stop flush
#stop Todas las normas y politicas restauradas a ACCEPT
#restart reinicia, Ejecuta stop y start comandos.
#status Muestra todas las reglas activas, y los contadores de paquetes y bytes

startfile="/usr/local/bin/firewall_host"
stopfile="/usr/local/bin/fw_flush"
statusfile="/usr/local/bin/fw_status"

case "$1" in
start)
echo "Iniciando... $startfile: iptables esta en marcha"
/bin/sh $startfile start
;;

stop)
echo "Deteniendo... $stopfile: iptables esta detenido."
/bin/sh $stopfile stop
;;

status)
/bin/sh $statusfile status
;;

restart)
/bin/sh $stopfile stop
echo "El cortafuegos ha sido detenido."
/bin/sh $startfile start
echo "El firewall ha sido reiniciado."
;;
esac
#####FIN SCRIPT FIREWALL IPTABLES####

¿Como desactivamos nuestro firewall?
Este sera nuestro guion fw_flush que borrara todas las reglas de las tablas Filter, NAT y Mangle, todas las cadenas y pone a cero todos los contadores de paquetes bytes. Las politicas por defecto son restauradas a ACCEPT para que nada se quede bloqueado. Recuerde que este script es solo para root. Lo guardamos en /usr/local/bin/ chmod 0700.

#!/bin/sh
##/usr/local/bin/fw_flush
####INICIO SCRIPT FLUSH IPTABLES####
#elimina todas las reglas activas y cadenas,
#y las políticas por defecto se restablece a "ACCEPT"
#Esto es como NO tener ningún servidor de seguridad.

#define variables
ipt="/sbin/iptables"

echo "El firewall esta detenido. Todas las reglas y cadenas
han sido eliminadas, las politicas por defecto en ACCEPT.
Todos los contadores a cero."

#Politicas por defecto ACCEPT todo.
$ipt -P INPUT ACCEPT
$ipt -P FORWARD ACCEPT
$ipt -P OUTPUT ACCEPT
$ipt -t nat -P OUTPUT ACCEPT
$ipt -t nat -P PREROUTING ACCEPT
$ipt -t nat -P POSTROUTING ACCEPT
$ipt -t mangle -P INPUT ACCEPT
$ipt -t mangle -P OUTPUT ACCEPT
$ipt -t mangle -P FORWARD ACCEPT

#Todos los contadores a cero.
$ipt -Z
$ipt -t nat -Z
$ipt -t mangle -Z

#Flush todas las reglas, borrar todas las cadenas.
$ipt -F
$ipt -X
$ipt -t nat -F
$ipt -t nat -X
$ipt -t mangle -F
$ipt -t mangle -X
####FIN SCRIPT FLUSH IPTABLES####

Para conocer el estado de nuestro firewall utilizaremos este
script que llamaremos fw_status. Muestra todas las reglas y cadenas activas. Lo guardamos como fw_status en /usr/local/bin/ chmod 0700.

#!/bin/sh
#/usr/local/bin/fw_status
####INICIO SCRIPT STATUS IPTABLES####
##/usr/local/bin/fw_status script
#muestra todas las reglas y cadenas activas.

#define variables
ipt="/sbin/iptables"

echo "Las actuales reglas y cadenas activas:"

$ipt -t filter -L -v --line-numbers
$ipt -t nat -L -v --line-numbers
$ipt -t mangle -L -v --line-numbers
####FIN SCRIPT STATUS IPTABLES####

En un artículo anterior hemos configurado un cortafuegos para
una conexion-internet-compartido.html

Esta vez, un cortafuegos para una sola máquina. Este es nuestro firewall con politicas por defecto DROP. Le llamaremos firewall_host, lo pondremos en /usr/local/bin/ chmod 0700. Hemos pedido la aprobación de Sergio Gonzalez para modificar un poquito su sencillo, funcional y educativo cortafuegos que hemos encontrado en http://www.linuxtotal.com autor -- > sergio.gonzalez.duran@gmail.com

#!/bin/sh
##/usr/local/bin/firewall_host
#original de www.linuxtotal.com
#autor original: sergio.gonzalez.duran@gmail.com
#firewall para un solo host

#definir variables
ipt=/sbin/iptables
mod=/sbin/modprobe

#conjunto básico de módulos del kernel
$mod ip_tables
$mod ip_conntrack
$mod iptable_filter
$mod iptable_nat
$mod iptable_mangle
$mod ipt_LOG
$mod ipt_limit
$mod ipt_state
$mod ipt_MASQUERADE

# se establecen politicas "duras" por defecto, es decir solo
#lo que se autorice explicitamente podra ingresar o salir
# del equipo
$ipt -P INPUT DROP
$ipt -P OUTPUT DROP
$ipt -P FORWARD DROP

# a la interface lo (localhost) se le permite todo
$ipt -A INPUT -i lo -j ACCEPT
$ipt -A OUTPUT -o lo -j ACCEPT

# evitamos ataques syn-flood limitando el acceso de paquetes
# nuevos desde internet a solo 4 por segundo y los demas se
# descartan
$ipt -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 4 -j DROP

# se evitan paquetes tcp que sean nuevos y que no tengan el
# flag SYN es decir, hay ataques o escaneos que llegan como
# conexiones nuevas pero sin ser paquetes syn,
# definitivamente no nos interesan
$ipt -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# todo lo que sea icmp (ping) y que intente entrar, se
# descarta con esto bloqueamos cualquier tipo de paquetes
# con protocolo icmp evitando ataques como el del ping de
# la muerte, aunque esta regla podria provocar problemas
# de comunicacion con algunos ISP.
# Podríamos Aceptar importantes ICMP paquetes de manera
# que obviariamos poblemas de comunicacion con nuestro isp.
# para solucionarlo aceptamos importantes ICMP paquetes.
$ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$ipt -A INPUT -p icmp -j DROP

# por ultimo las dos siguientes reglas permiten salir del equipo
# (output) conexiones nuevas que nosotros solicitamos,
# conexiones establecidas y conexiones relacionadas, y deja
# entrar (input) solo conexiones establecidas y relacionadas.
$ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ipt -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
#####FIN SCRIPT FIREWALL HOST IPTABLES####

Puede Iniciar el firewall al inicio o con los comandos estandar estilo init.d:
Para iniciarlo en los niveles de ejecución 2, 3, 4 y 5 y detenerlo en los niveles de ejecución 0, 1 y 6:
# update-rc.d firewall start 01 2 3 4 5. stop 99 0 1 6.

Gestionarlo con los comandos estándar:
# /etc/init.d/firewall start | stop | status | restart

Es posible que quiera agregar reglas que permitan servicios SSH o peer to peer, como mensajería instantánea o BitTorrent. Utilice esta regla con los puertos adecuados para el protocolo desde el que vamos a permitir las peticiones de entrada del cliente:
$ipt -A INPUT -p tcp --destination-port [port range] -j ACCEPT

Tendrá que borrar esta regla:
$ipt -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 4 -j DROP

Llegados a este punto debemos saber que las directivas /etc/sysctl.conf son importantes medidas de seguridad del kernel. Agregue estos parámetros kernel a /etc/sysctl.conf:

net.ipv4.ip_forward = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0

Para activar sin reiniciar:

# /sbin/sysctl -p
# /etc/init.d/firewall start

Vamos a explicar el significado de los parametros del kernel.
net.ipv4.ip_forward = 0 # Asegurese de quer el reenvio esta desactivado ya que esta caja no es un router.

net.ipv4.icmp_echo_ignore_broadcasts = 1 # No responde a las transmisiones de ping. Estas junto con las multidifusiones suelen ser un ataque pitufo.

net.ipv4.tcp_syncookies = 1 # Proteccion contra un ataque de aluvion de SYN. Resulta de poca utilidad en un servidor cargado, puede causar problemas. En cambio lo utilizaremos en estaciones de trabajo y portatiles.

net.ipv4.conf.all.rp_filter = 1 # Mantiene el estado y protege contra el enmascaramiento del origen. Verifica que los paquetes que entran en una interfaz salgan de la misma interfaz. No utilizar con routers de multisede.

net.ipv4.conf.all.send_redirects = 0 # Solo lo necesitan los routers

net.ipv4.conf.all.accept_redirects = 0 # Las redirecciones ICMP son importantes para los routers. Desactivelo.

net.ipv4.conf.all.accept_source_route = 0 # Los paquetes enrutados por origen suponen un riesgo para la seguridad porque hacen que enmascarar las direcciones seguras sea muy fácil.

Comprobado el 5 de Dic del 2009 en un sistema GNU-Linux Debian-Lenny