Configuración del sistema cortafuegos

En esta sección realizaremos el despliegue del sistema cortafuegos. Para ello instalaremos el software de integración de netfilter del sistema luIDS, lo configuraremos para que use el sistema de listas que hemos creado en la sección anterior y finalmente configuraremos el cortafuegos mediante iptables para que delegue las decisiones en nuestro sistema.

Recuerde que tiene a su disposición todos los ficheros de configuración de esta guía en https://github.com/luids-io/docs/blob/master/es/modules/guide-basic-dns-whitehole-nfqueue/examples/.
Este proceso está probado únicamente en un sistema Ubuntu 20.04LTS server. Los binarios están compilados estáticamente y las rutas empleadas son las de una distribución estándar, por lo que el instalador debería funcionar en cualquier distribución.

Instalación de iptables

Además en esta guía utilizaremos iptables-persistent para establecer las reglas del cortafuegos. Lo instalaremos vía apt.

apt install iptables-persistent

Instalación del paquete netfilter de luIDS

Instalar netfilter (paquete de luIDS) es muy sencillo, basta descargar el instalador ya existente y ejecutarlo. Para ello puede dirigirse a https://github.com/luids-io/netfilter/releases y descargar la última versión del instalador (fichero installer_linux.sh). También puede simplemente copiar y pegar lo siguiente en una consola de comandos.

DOWNLOAD_URL=$(wget -O - https://api.github.com/repos/luids-io/netfilter/releases/latest| grep download.*installer | grep -v sha256 | cut -d '"' -f4)
wget ${DOWNLOAD_URL} -O installer_netfilter.sh
chmod 755 installer_netfilter.sh
sudo ./installer_netfilter.sh
Si está instalando el software en una arquitectura diferente a la amd64 (como en el caso de una Raspberry) deberá definirla en una variable de entorno al lanzar el instalador. Ejemplo: sudo ARCH=arm64 ./installer.sh. Las arquitecturas disponibles son: amd64, arm, arm64, mips, mips64, mips64le, ppc64 y s390x.

Configuración de lunfqueue

La configuración nuevamente se divide en configuración del servidor y definición del servicio.

Contenido de /etc/luids/netfilter/lunfqueue.toml
[nfqueue]
localnets = [ "127.0.0.0/8", "192.168.250.0/24" ]
qids      = [ 100 ]

[nfqueue.plugin]
files  = [ "/etc/luids/netfilter/plugins-nfqueue.json" ]

[ids.api]
files     = [ "/etc/luids/apiservices.json" ]

[log]
format = "log"
Deberás reemplazar la dirección de red 192.168.250.0/24 por la de tu red local.

El servicio se configurará mediante la definición de los plugins y acciones que se van a aplicar. Esto se realizará mediante el siguiente fichero de configuración.

Contenido de /etc/luids/netfilter/plugins-nfqueue.json
[
  {
    "name": "ip-processor",
    "class": "ipp",
    "actions": [
      {
        "name": "checkresolv",
        "class": "checkresolv",
        "services": { "resolvcache": "resolvcheck" },
        "rules": [
          { "when": "resolved",   "rule": { "verdict": "accept" } },
          { "when": "unresolved", "rule": { "log": true, "verdict": "drop" } }
        ]
      }
    ]
  }
]

Testearemos que la configuración es correcta.

# lunfqueue --config /etc/luids/netfilter/lunfqueue.toml --dry-run
INFO[0000] lunfqueue (version: 160c012 build: 2020-12-11T08:52:38+0100)
configuration seems ok

Una vez probado, inicializaremos y habilitaremos el servicio

systemctl start luids-lunfqueue
systemctl enable luids-lunfqueue

Ya tenemos configurado un servicio que escucha la entrada de paquetes en la cola netfilter 100. Ahora deberemos dirigir los paquetes que deseemos filtrar a dicha cola.

Configuración de netfilter mediante iptables

Vamos a configurar el sencillo firewall mediante el siguiente script. Nótese que únicamente dejaremos pasar el tráfico icmp para pruebas de conexión y el tráfico por los puertos 80 y 443 para navegación.

Contenido de init-firewall.sh
#!/bin/bash

## IMPORTANT: replace this values with your deployment values
INT_IFACE=enp0s8
INT_NETWORK=192.168.250.0/24
EXT_IFACE=enp0s3

## enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

## flush rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

## default policy
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

## enable ip masquerade
iptables -t nat -A POSTROUTING -o $EXT_IFACE -j MASQUERADE

## allow established
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

## allow internal connections to all firewall exposed services
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i $INT_IFACE -s $INT_NETWORK -j ACCEPT

## allow external connections to ssh
iptables -A INPUT -i $EXT_IFACE -p tcp –dport 22 -j ACCEPT

## set forwarding rules
iptables -A FORWARD -i $INT_IFACE -o $EXT_IFACE -s $INT_NETWORK \
        -p icmp -j NFQUEUE --queue-num 100
iptables -A FORWARD -i $INT_IFACE -o $EXT_IFACE -s $INT_NETWORK \
        -p tcp -m tcp -m multiport --dports 80,443 -j NFQUEUE --queue-num 100

Lo ejecutaremos.

chmod 755 init-firewall.sh
sudo ./init-firewall.sh

Ya tendremos nuestro cortafuegos configurado, ahora desde una máquina dentro de la red interna testearemos.

(RED-INTERNA)$ ping -c 3 ntp.ubuntu.com (1)
PING ntp.ubuntu.com (91.189.94.4) 56(84) bytes of data.
64 bytes from pugot.canonical.com (91.189.94.4): icmp_seq=1 ttl=61 time=41.6 ms
64 bytes from pugot.canonical.com (91.189.94.4): icmp_seq=2 ttl=61 time=37.5 ms
64 bytes from pugot.canonical.com (91.189.94.4): icmp_seq=3 ttl=61 time=39.1 ms

--- ntp.ubuntu.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 37.463/39.387/41.632/1.717 ms

(RED-INTERNA)$ ping -c 3 www.google.com (2)
ping: www.google.com: Nombre o servicio desconocido

(RED-INTERNA)$ ping -c 3 8.8.8.8 (3)
PING www.google.com (8.8.8.8) 56(84) bytes of data.

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2023ms
1 La conexión con una máquina de la lista blanca funciona correctamente.
2 La resolución de dominios que no estén en la lista blanca son contestadas con un "no existe el dominio".
3 Si tratamos de conectar directamente por ip no funciona ya que la dirección no se ha resuelto previamente por la máquina que hace el ping.

En el log de nuestro firewall tendremos algo parecido a lo siguiente.

# tail -f /var/log/syslog
...
Dec 28 16:55:17 luids-router ludns[2384]: [INFO] plugin/xlisthole: 192.168.250.100:59838 check 'www.google.com' response: false ''
Dec 28 16:55:17 luids-router ludns[2384]: [INFO] plugin/xlisthole: 192.168.250.100:59838 check 'www.google.com' response: false ''
Dec 28 16:56:00 luids-router lunfqueue[1876]: level=info msg="ip-processor.checkresolv: 192.168.250.100->8.8.8.8 8.8.8.8 {Result:false Last:0001-01-01 00:00:00 +0000 UTC Store:2020-12-28 15:01:44.8925821 +0000 UTC}"
Dec 28 16:56:01 luids-router lunfqueue[1876]: level=info msg="ip-processor.checkresolv: 192.168.250.100->8.8.8.8 8.8.8.8 {Result:false Last:0001-01-01 00:00:00 +0000 UTC Store:2020-12-28 15:01:44.8925821 +0000 UTC}"
Dec 28 16:56:02 luids-router lunfqueue[1876]: level=info msg="ip-processor.checkresolv: 192.168.250.100->8.8.8.8 8.8.8.8 {Result:false Last:0001-01-01 00:00:00 +0000 UTC Store:2020-12-28 15:01:44.8925821 +0000 UTC}"

En la traza de la caché tendremos algo parecido a lo siguiente.

# cat /var/lib/luids/dns/cache-trace.log
...
20201228165352,collect,127.0.0.1:42516,192.168.250.100,ntp.ubuntu.com,91.189.94.4,91.189.89.198,91.189.89.199,91.189.91.157,
20201228165352,collect,127.0.0.1:42516,192.168.250.100,ntp.ubuntu.com,2001:67c:1560:8003::c7,2001:67c:1560:8003::c8,
20201228165352,check,127.0.0.1:42510,192.168.250.100,,91.189.94.4,true
20201228165600,check,127.0.0.1:42510,192.168.250.100,,8.8.8.8,false

Consolidación del firewall

Ahora que hemos comprobado que el sistema funciona correctamente sólo falta hacer las reglas que hemos definido persistentes para ello simplemente introduciremos.

sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6