Para un proyecto en el exterior escribí InstallingShorelineFirewall4Through42 para instalar la versión 4.2 en inglés.

Aprovechando que la instalación ahora es distinta, voy a hacerlo en castellano (e incluyendo soporte para IPv6 que está tan de moda ahora que se acabaron las direcciones IPv4).

Es recomendable tener un firewall en cualquier servidor (en realidad, en cualquier computadora) aun cuando esté en una red "protegida" por algún tipo de firewall.

El que yo prefiero usar en GNU/Linux es el Shoreline Firewall (Shorewall) ya que es suficientemente poderoso como para hacer cualquier cosa que se pueda hacer con netfilter/iptables (el esquema de packet filtering nativo del kernel linux) y es mucho más fácil de configurar que la utilización de comandos iptables en un script. Shorewall sólo utiliza archivos de texto para su configuración (ninguna GUI vistosa, gracias).

Como los paquetes de debian y ubuntu en general están bastante retrasados respecto de la versión estable actual, conviene usar los paquetes fuentes directamente que son fáciles de instalar y actualizar.

En general, cualquier distribución más o menos nueva de GNU/Linux tiene todos los pre-requisitos de Shorewall en su instalación básica.

Bajar e instalar

# La versión actual (2011-08) de shorewall es 4.4.22.3
# Fijarse en http://www.shorewall.net/pub/shorewall/ para ver cuál es la versión actual
MAJOR="4.4"
MINOR="22"
PATCH=".3"

# El ID de la clave GPG de Shorewall (lo vamos a usar para verificar el paquete)
GPGKEY="6C562AC4"

# bajar el software
mkdir -pv ~/soft/shorewall
cd ~/soft/shorewall

# Bajarse la clave de firmas gpg de shorewall (ID 6C562AC4)
# Lamentablemente, no tienen la clave en un servidor público
# de claves y el server https donde la tienen tiene un 
# certificado autofirmado, con lo cual nunca podemos estar
# completamente seguros de esta clave gpg.
# De todos modos, bajémosla...
wget --no-check-certificate https://lists.shorewall.net/shorewall.gpg.key
# y agreguémosla a nuestro "llavero"
gpg --import shorewall.gpg.key

# Ahora, bajamos y verificamos los paquetes
wget http://www.shorewall.net/pub/shorewall/${MAJOR}/shorewall-${MAJOR}.${MINOR}/shorewall-${MAJOR}.${MINOR}${PATCH}.tar.bz2
wget http://www.shorewall.net/pub/shorewall/${MAJOR}/shorewall-${MAJOR}.${MINOR}/shorewall-${MAJOR}.${MINOR}${PATCH}.tar.bz2.asc
fi
wget http://www.shorewall.net/pub/shorewall/${MAJOR}/shorewall-${MAJOR}.${MINOR}/shorewall6-${MAJOR}.${MINOR}${PATCH}.tar.bz2
wget http://www.shorewall.net/pub/shorewall/${MAJOR}/shorewall-${MAJOR}.${MINOR}/shorewall6-${MAJOR}.${MINOR}${PATCH}.tar.bz2.asc

# Verificar los paquetes (ignorar los WARNINGs acerca de "trusted signatures")

for PACKAGE in "" 6; do
  FILE=shorewall${PACKAGE}-${MAJOR}.${MINOR}${PATCH}.tar.bz2
  if [ ! -f ${FILE} ] ; then
    FILE=shorewall-${PACKAGE}-${MAJOR}.${MINOR}.tar.bz2
  fi
  gpg --verify ${FILE}.asc ||
     (echo '';echo '';echo '¡¡¡¡STOP!!!!';echo ${FILE} ' PARECE FALSO';echo '')
done

# Si no apareció ningún ¡¡¡STOP!!!! entonces sigamos adelante

# Abrimos los paquetes...
for PACKAGE in "" 6 ; do
  FILE=shorewall${PACKAGE}-${MAJOR}.${MINOR}${PATCH}.tar.bz2
  tar xjvf ${FILE}
done

# ...y los instalmos.
# Primero el paquete shorewall
cd shorewall-${MAJOR}.${MINOR}${PATCH}
sudo ./install.sh -s
cd ~/soft/shorewall
# Después el paquete shorewall6
cd shorewall6-${MAJOR}.${MINOR}${PATCH}
sudo ./install.sh -s
cd ~/soft/shorewall

ulogd

Para mantener separados los logs de netfilter (si no, se mezclan con todo lo que se loguee en el kernel facility del syslog), instalamos ulogd:

sudo apt-get install ulogd

Configuración

Ahora hay que configurar el firewall.

La opción -s que le pasamos a cada ./install.sh deja limpio el directorio de configuración (/etc/shorewall para shorewall y /etc/shorewall6 para shorewall6). Esto es, sólo deja el archivo de configuración principal (shorewall.conf o shorewall6.conf) y un archivo de parámetros (param) vacío.

Los archivos de configuración "limpios" que normalmente se instalan en /etc/shorewall se pueden copiar de /usr/share/shorewall/configfiles y los que se instalan en /etc/shorewall6 se pueden copiar de /usr/share/shorewall6/configfiles.

Con lo cual ahora tenemos los siguientes archivos:

shorewall.conf / shorewall6.conf

Vamos a hacer algunos cambios pequeños en la configuración por defecto.

Logging

Cambiamos todos los XXXXXXX_LOG_LEVEL para que en lugar de info (el default) tengan ULOG (siempre todo en mayúsculas).

También cambiamos LOGFILE (ojo que esto no hace que shorewall use ese archivo para escribir los logs (ya que esto lo hace netfilter), si no que le dice dónde leer el archivo para procesar los comandos "show log", "logwatch" y "'dump".

Las variables que cambiamos quedan así en /etc/shorewall/shorewall.conf (en /etc/shorewall6/shorewall6.conf no porque, lamentablemente, IPv6 no soporta ULOG y en ubuntu no tenemos NFLOG).

###############################################################################
#                       L O G G I N G
###############################################################################

BLACKLIST_LOGLEVEL=ULOG

LOG_MARTIANS=Yes

LOG_VERBOSITY=2

LOGALLNEW=

LOGFILE=/var/log/ulog/syslogemu.log

LOGFORMAT="Shorewall:%s:%s:"

LOGTAGONLY=No

LOGLIMIT=

MACLIST_LOG_LEVEL=ULOG

SFILTER_LOG_LEVEL=ULOG

SMURF_LOG_LEVEL=ULOG

STARTUP_LOG=/var/log/shorewall-init.log

TCP_FLAGS_LOG_LEVEL=ULOG

###############################################################################
#                  L O G G I N G
###############################################################################

BLACKLIST_LOGLEVEL=info

LOG_VERBOSITY=2

LOGALLNEW=

LOGFILE=/var/log/kern.log

LOGFORMAT="Shorewall:%s:%s:"

LOGLIMIT=

LOGTAGONLY=No

MACLIST_LOG_LEVEL=info

SFILTER_LOG_LEVEL=info

SMURF_LOG_LEVEL=info

STARTUP_LOG=/var/log/shorewall6-init.log

TCP_FLAGS_LOG_LEVEL=info

zonas anidadas

Para facilitar el funcionamiento de zonas anidadas, habilitamos un CONTINUE implícito (tanto en /etc/shorewall/shorewall.conf como en /etc/shorewall6/shorewall6.conf):

IMPLICIT_CONTINUE=Yes

optimización de reglas

Para optimizar las reglas casi sin afectar la legibilidad de las mismas ponemos (tanto en /etc/shorewall/shorewall.conf como en /etc/shorewall6/shorewall6.conf):

OPTIMIZE=1

Se pueden hacer más optimizaciones pero puede afectar el debugging de reglas. Ver la opción OPTIMIZE en man shorewall.conf y man shorewall6.conf

lock file

Por algún motivo, este parámetro está en blanco y, de acuerdo a la documentación de shorewall en debian (y ubuntu) debe ir así:

SUBSYSLOCK=/var/lock/shorewall

SUBSYSLOCK=/var/lock/shorewall6

otros archivos de configuración

Todos los archivos que se utilizan para configurar shorewall deben ir in /etc/shorewall y los que se utilizan para configurar shorewall6 en /etc/shorewall6.

Si bien la instalación no copia nada aquí, hay archivos por default para cada uno de estos en /usr/share/shorewall/configfiles/ y /usr/share/shorewall6/configfiles/ respectivamente.

Además, para cada archivo hay una versión que termina con ".annotated" donde están comentadas las configuraciones posibles en ese archivo.

zones

El archivo zones (tanto en /etc/shorewall como en /etc/shorewall6) se utiliza para definir (ponerles nombre a) las zonas que utilizaremos en las reglas y políticas (que se aplican para tráfico que va de una zona a otra).

Siempre hay que incluir en firewall como fw (ya viene en el archivo default).

Por ahora sólo agregamos una zona que llamamos net en cada uno de los archivos para referirnos a todos los hosts externos (internet). En shorewall el tipo de esta zona es ipv4 y en shorewall6 es ipv6

###############################################################################
#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv4

###############################################################################
#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv6

interfaces

Estos archivos se utilizan para definir las interfaces de red del equipo (nosotros tenemos una sola). Los nombres de zona asociados a una interface deben estar definidos en el archivo zones correspondiente. La zona fw no se puede asociar a una interface.

###############################################################################
#ZONE   INTERFACE       BROADCAST       OPTIONS
net     eth0            -               tcpflags,logmartians,nosmurfs

###############################################################################
#ZONE   INTERFACE       ANYCAST         OPTIONS
net     eth0            -               tcpflags

policy

En este archivo se definen las políticas de alto nivel para conexiones entre zonas. Es decir, se define qué se hará con las conexiones desde una zona a otra si no hay ninguna regla específica (en el archivo rules).

El orden de las políticas es importante. El archivo se procesa de arriba hacia abajo y la primera política que matchea fuente y destino se aplica.

Si ninguna política se aplica, el resultado es indefinido, por lo que es conveniente poner una política al final de todo el archivo con fuente all y destino all.

###############################################################################
#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
#                               LEVEL   BURST           MASK

# Por ahora permitimos todo el trafico saliente.
# En el futuro es conveniente restringir esto (se puede poner un REJECT
# para que 'conteste' rapido).
fw      net     ACCEPT

# Todo trafico entrante que no este explicitamente permitido en una regla
# lo descartamos y logueamos (esto loguea mucho, ya que normalmente, hay
# bots intentando hacer cualquier cosa).
net     fw      DROP            ULOG

# ESTA DEBE SER LA ULTIMA POLITICA
# Esto es una red de seguridad por si agregamos nuevas zonas y nos olvidamos
# de configurar una politica. Todo lo demas se descarta.
# ESTA DEBE SER LA ULTIMA POLITICA
all     all     DROP            ULOG

###############################################################################
#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
#                               LEVEL   BURST           MASK

# Por ahora permitimos todo el trafico saliente.
# En el futuro es conveniente restringir esto (se puede poner un REJECT
# para que 'conteste' rapido).
fw      net     ACCEPT

# Todo trafico entrante que no este explicitamente permitido en una regla
# lo descartamos y logueamos (esto loguea mucho, ya que normalmente, hay
# bots intentando hacer cualquier cosa).
net     fw      DROP            info

# ESTA DEBE SER LA ULTIMA POLITICA
# Esto es una red de seguridad por si agregamos nuevas zonas y nos olvidamos
# de configurar una politica. Todo lo demas se descarta.
# ESTA DEBE SER LA ULTIMA POLITICA
all     all     DROP            info

rules

Aquí van las reglas específicas que permiten o prohiben determinado tráfico desde una zona a otra. Las acciones se aplican al inicio de una conexión, los demás paquetes de la conexión siguen adelante.

El orden de las reglas es importante. El archivo se procesa de arriba hacia abajo y la primera regla que matchea fuente y destino se aplica. Todas las acciones salvo LOG y COUNT terminan el procesamiento.

####################################################################################################################################################################
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE            USER/   MARK    CONNLIMIT       TIME         HEADERS
#                                                       PORT    PORT(S)         DEST            LIMIT           GROUP
#SECTION ESTABLISHED
#SECTION RELATED
SECTION NEW

################
# DNS
################
# Permitimos consultas DNS salientes
DNS(ACCEPT)     $FW             all


################
# SSH
################
# Permitimos salir via SSH
SSH(ACCEPT)     $FW             all
# Permitimos entrar via SSH desde cualquier lado
# En el futuro habría que implementar algún doorknob para impedir ataques al SSH
SSH(ACCEPT)     all             $FW

################
# Web (http+https)
################
# Permitimos conexiones salientes a la web (esto despues lo podriamos restringir)
Web(ACCEPT)     $FW             all
# Permitimos que se vean nuestros servidores web
Web(ACCEPT)     all             $FW

Habilitar Shorewall

Para habilitar shorewall hay que editar los archivos /etc/default/shorewall y /etc/default/shorewall6 y poner:

startup=1

Para arrancarlos:

sudo invoke-rc.d shorewall start
sudo invoke-rc.d shorewall6 start

La instalación dejó configurado el arranque automático al bootear.

Modificar la configuración de syslog para que la salida del firewall no se mezcle con lo demás

Si bien configuramos iptables para que loguee utilizando ulogd, iptables6 no lo puede hacer, con lo cual todo el logging IPv6 del firewall (que puede ser mucho) saldrá mezclado en /var/log/syslog y /var/log/messages.

El logging de iptables usa la facility kernel del syslog (lo cual no se puede modificar), con lo cual se mezclará con cualquier otro mensaje con facility kernel de /var/log/messages y /var/log/syslog.

Para sacar los mensajes con facility kernel tenemos que editar /etc/rsyslog.d/50-default.conf:

*.*;auth,authpriv.none    -/var/log/syslog

esto quiere decir, "enviar todo a /var/log/syslog.conf excepto los mensajes de los facilities auth y authpriv. Para indicarle que tampoco mande los mensajes del facility kernel hay que dejar esa línea así:

*.*;auth,authpriv.none,kern.none    -/var/log/syslog

*.=info;*.=notice;*.=warning;\
    auth,authpriv.none;\
    cron,daemon.none;\
    mail,news.none      -/var/log/messages

esto envia algunos mensajes menos a /var/log/messages. Para quitar también de aquí los mensajes del facility kernel hay que dejar la línea así:

*.=info;*.=notice;*.=warn;\
    auth,authpriv.none;\
    cron,daemon.none;\
    kern.none;\
    mail,news.none      -/var/log/messages

Ahora los mensajes del facility kernel sólo aparecerán en el archivo /var/log/kern.log debido a la siguiente línea (que ya está así por defecto):

kern.*              -/var/log/kern.log

Ahora, sólo queda reiniciar el rsyslog:

sudo service rsyslog restart

InstalaciónDeShorelineFirewall (última edición 2011-08-21 22:39:34 efectuada por MarianoAbsatz)