armando un firewall

Satoru Lucas Shindoi lucas en shindoi.com.ar
Sab Nov 12 10:58:11 CLST 2005


gente:

Estoy armando un firewall usando iptables.
Por ahora decidí aplicar la política de denegar todo y abrir solo lo necesario (escucho criticas/apoyo a esta decisión)

Graficamente tengo:

[INET] ---- [(ppp0)--(eth1)LOCALHOST(eth0)] ---- [LAN]

En lineas generales, mi planteo es el siguiente (en pseudocodigo) pudiendo tener errores de concepto (creo):

POLITICA POR DEFECTO TODO DENEGADO (asi que a empezar a abrir)

TRAFICO ENTRANTE
PERMITIR TODO DESDE LOCALHOST
PERMITIR "casi" TODO DESDE LAN
PERMITIR ALGUNOS DESDE INET
DENEGAR RESTO (por la política por defecto DROP la considero redundante, escucho opiniones)

TRAFICO SALIENTE
PERMITIR TODO HACIA LOCALHOST
PERMITIR ALGUNOS HACIA LAN
PERMITIR ALGUNOS HACIA INET
DENEGAR RESTO (por la política por defecto DROP la considero redundante, escucho opiniones)

TRAFICO FORWARD
PERMITIR ALGUNOS DESDE LAN A INET
DENEGAR RESTO

Ahora expongo mi implementacion:

####
#!/bin/bash

#### Variables
# LOCALHOST
LO_IP="127.0.0.1"
LO_IFACE="lo"
# LAN
LAN_IP_RANGE="192.168.0.0/24"
LAN_IP="192.168.0.10"
LAN_BCAST_ADDRESS="192.168.0.255"
LAN_IFACE="eth0"
# INET
#INET_IP_RANGE="192.168.1.0/24"
#INET_IP="192.168.1.10"
#INET_BCAST_ADDRESS="192.168.1.255"
#INET_IFACE="eth1"
INET_IFACE="ppp0"
# Path IPTABLES
IPTABLES="/sbin/iptables"

## Cargar modulos de IPTABLES
/sbin/depmod -a
modprobe ip_tables
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
modprobe ip_nat_ftp
modprobe ip_nat_irc
modprobe ipt_MASQUERADE
modprobe ipt_LOG
modprobe ipt_REJECT
modprobe ipt_state
#modprobe ipt_owner

## Activar el forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

## "Limpiar" las tablas
/sbin/iptables -t nat -F
/sbin/iptables -t filter -F
/sbin/iptables -t mangle -F
/sbin/iptables -t nat -Z
/sbin/iptables -t filter -Z
/sbin/iptables -t mangle -Z
/sbin/iptables -t nat -X
/sbin/iptables -t filter -X
/sbin/iptables -t mangle -X

## Pongo la politica por defecto de INPUT, FORWARD and OUTPUT a DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

## Cadena bad_tcp_packets (una cadena tendiente a cortar de raiz paquetes "raros")
$IPTABLES -N bad_tcp_packets
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "NEW not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
# Paquetes obviamente de IP's spoofed
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 192.168.0.0/16 -j LOG --log-prefix "Spoofed packet CLASS C"
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 192.168.0.0/16 -j DROP
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 10.0.0.0/8 -j LOG --log-prefix "Spoofed packet CLASS A"
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 10.0.0.0/8 -j DROP
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 172.16.0.0/12 -j LOG --log-prefix "Spoofed packet CLASS B"
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 172.16.0.0/12 -j DROP

# Cadena allowed
# Paquetes de inicio de conexion y otros permitidos
$IPTABLES -N allowed
$IPTABLES -A allowed -p tcp --syn -j ACCEPT
$IPTABLES -A allowed -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p tcp -j DROP

# Cadena icmp_packets 
# Paquetes ICPM permitidos (ping y otros)
$IPTABLES -N icmp_packets
$IPTABLES -A icmp_packets -p icmp -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p icmp -s 0/0 --icmp-type 11 -j ACCEPT

# Cadena tcp_packets
$IPTABLES -N tcp_packets
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 21 -j allowed # FTP server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 22 -j allowed # SSH server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 25 -j allowed # SMTP server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 80 -j allowed # HTTP server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 110 -j allowed # POP3 server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 443 -j allowed # HTTPS server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 993 -j allowed # IMAPS server
#$IPTABLES -A tcp_packets -p tcp -s 0/0 --dport 995 -j allowed # POP3S server

# UDP ports
# nondocumented commenting out of these rules
#$IPTABLES -N udpincoming_packets
#$IPTABLES -A udpincoming_packets -p udp -s 0/0 --sport 53 -j ACCEPT # consultas a los DNS server
#$IPTABLES -A udpincoming_packets -p udp -s 0/0 --sport 123 -j ACCEPT # consultas a los NTP server
#$IPTABLES -A udpincoming_packets -p udp -s 0/0 --sport 1227 -j ACCEPT # para cliente dns2go
#$IPTABLES -A udpincoming_packets -p udp -s 0/0 --sport 2074 -j ACCEPT # lo vi en un ejemplo, no halle nada en /etc/service
#$IPTABLES -A udpincoming_packets -p udp -s 0/0 --sport 4000 -j ACCEPT # lo vi en un ejemplo, no halle nada en /etc/service


## Propuesta de Buanzo (gracias! estoy tratando de entender como armar el esquema pensado asi)
## Separar por interfaz, armando subcadenas del tipo iface_in, iface_fwd, iface_out....)
## Poner un log justo antes de cada -j DROP
#$IPTABLES -N lo_in
#$IPTABLES -N eth0_in
#$IPTABLES -N eth1_in
#$IPTABLES -N eth0_fwd
#$IPTABLES -N eth1_fwd
#$IPTABLES -N lo_out
#$IPTABLES -N eth0_out
#$IPTABLES -N eth1_out

###########################################################################
# Cadena INPUT (paquetes con destino final el firewall)

# Paquetes TCP que no quiero recibir
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

# Paquetes en lo
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j allowed
#IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j allowed # esto esta bien?

# Paquetes entrantes desde INET
$IPTABLES -A INPUT -p icmp -i $INET_IFACE -j icmp_packets
$IPTABLES -A INPUT -p tcp -i $INET_IFACE -j tcp_packets
#$IPTABLES -A INPUT -p udp -i $INET_IFACE -j udpincoming_packets

# Paquetes entrantes desde LAN
$IPTABLES -A INPUT -p icmp -i $LAN_IFACE -j icmp_packets
$IPTABLES -A INPUT -p tcp -i $LAN_IFACE -j tcp_packets
$IPTABLES -A INPUT -p udp -i $LAN_IFACE -j udpincoming_packets
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_BCAST_ADDRESS -j allowed # esta bien permitir esto?
#$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j allowed

# Reglas para networks especiales que no son parte de INET
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j allowed
#IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j allowed # esto esta bien?
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: "


###########################################################################
# Cadena FORWARD (paquetes que atraviesan el firewall)

# Paquetes TCP que no quiero dejar pasar

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
$IPTABLES -A FORWARD -s LAN_RANGE_IP -j ACCEPT

###########################################################################
# Cadena OUTPUT (paquetes que salen desde el firewall)

# Paquetes extraños TCP que no queremos dejar salir

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

# Reglas especiales para decidir a que IPs permitir.

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
#$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

# Registrar paquetes extraños que no coincidan con lo anterior.

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "

#### FIN (por ahora.....)

Bueno, me gustaria que lo vieran y criticaran (son bienvenidas las criticas de todo tipo :-D)
Yo deje algunos comentarios para intentar expresar lo que entiendo o para decir "esto no la capto ni ahi"

Hay varias reglas/lineas comentadas, el motivo es que tome un ejemplo que encontre en inet y lo use de plantilla. Fui sacando cosas que no me gustaban o que creia que me servian, modificando otras etc.
Por ultimo, un apartado especial sobre la idea que me tiro un amigo (Buanzo). Entendi la TEORIA pero no se como pasarla a la practica.
Realmente se me presenta una situacion extraña con netfilter/iptables: tengo la teoria en la cabeza, pero no la entiendo bien por lo que me cuesta horrores armar algo. Eso..... y la falta total de experiencia. Como muestra basta un boton: en cierta ocacion las lineas de LOG "llenaron" (por decirlo de una manera) la particion /var :-P

Pues un abrazo, espero sus comentarios y criticas. Y si algun alma caritativa (y paciente) me quiere aclarar algunos conceptos, le estare profundamente agradecido

Un abrazo a todos

-- 
Satoru Lucas Shindoi
CEL: 03783-15666916
ICQ: 95357247 - Jabber: lucxkers en jabber.org
Messenger: slshindoi en hotmail.com - Yahoo: slshindoi en yahoo.com.ar
--------------------------------------------------------------------------
GULCO - Grupo de Usuarios de GNU/Linux Corrientes - www.gulco.linux.org.ar
Sistemas de Informacion - DPEC - www.dpec.com.ar
LiNEA S.H. - Linux en el NEA Sociedad de Hecho


-- 
Satoru Lucas Shindoi
CEL: 03783-15666916
ICQ: 95357247 - Jabber: lucxkers en jabber.org
Messenger: slshindoi en hotmail.com - Yahoo: slshindoi en yahoo.com.ar
--------------------------------------------------------------------------
GULCO - Grupo de Usuarios de GNU/Linux Corrientes - www.gulco.linux.org.ar
Sistemas de Informacion - DPEC - www.dpec.com.ar
LiNEA S.H. - Linux en el NEA Sociedad de Hecho



Más información sobre la lista de distribución Linux