miércoles, 21 de octubre de 2020

Aumentando la seguridad

En la entrada anterior apliqué unas reglas de cortafuegos muy monas, y activé fail2ban.

Pero dichas reglas son solamente para IPv4, y hay que repetirlas en IPv6. Pero ojo, que en IPv6 el ICMP no es simplemente un protocolo de apoyo, es parte fundamental de la infraestructura, y si los paqutes no pasan, no hay comunicación (véase RCF 4890):

ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p tcp -m tcp --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-replay -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type ttl-exceeded -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -J INPUT DROP
ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport http -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport https -j ACCEPT
ip6tables -A OUTPUT -p tcp -m tcp --dport domain -j ACCEPT
ip6tables -A OUTPUT -p udp -m udp --dport domain -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-reply -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type ttl-exceeded -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type parameter-problem -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A OUTPUT -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -J OUTPUT DROP
ip6tables -J FORWARD DROP

Para conseguir que las reglas se mantengan al reiniciar, basta con instalar el paquete iptables-persistent.

Por fail2ban para IPv6 no tenemos que preocuparnos, ya que funciona automáticamente.

La otra cosa pendiente es que no vale de mucho parar a un atacante por unos minutos si después vuelve a las andadas. La configuración por defecto de fail2ban prohíbe la entrada de paquetes durante 10 minutos. Esto para los ataques casuales, pero a los atacantes serios no. Pero subir el tiempo puede dejarle fuera a uno mismo si tiene problemas con la configuración del teclado, por ejemplo.

La solución a este tipo de problemas es prohibir el acceso de nuevo, por más tiempo, a los reincidentes. Siguiendo (un poco) los pasos de The art of web, creamos dos jaulas nuevas, cada una de ellas más dura que la anterior.

En /etc/fail2ban/jail.local añadimos estas líneas:

[sshd-fail2ban-L1]
# 3 veces en 6 horas, 24 horas
enabled = true
port = ssh
filter = sshd-fail2ban-L1
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 21600
bantime = 86400

[sshd-fail2ban-L2]
# 3 veces en 7 días, 30 días
enabled = true
port = ssh
filter = sshd-fail2ban-L2
logpath = /var/log/fail2ban.log
maxretry = 3
findtime = 604800
bantime = 2592000

A continuación, creamos el fichero /etc/fail2ban/filter.d/sshd-fail2ban-L1.conf con este contenido (ojo al espacio final en ignoreregex) como filtro:

[DEFAULT]
[Definition]
failregex = \[sshd\] Ban <HOST>
ignoreregex =

Y este otro contenido (la misma advertencia) como el fichero /etc/fail2ban/filter.d/sshd-fail2ban-L2.conf como el otro filtro:

[DEFAULT]
[Definition]
failregex = \[sshd-fail2ban-L1\] Ban <HOST>
ignoreregex =

Ahora basta con un par de órdenes y ya tenemos un sistema un poco más robusto:

fail2ban-client add sshd-fail2ban-L1
fail2ban-client start sshd-fail2ban-L1
fail2ban-client add sshd-fail2ban-L2
fail2ban-client start sshd-fail2ban-L2

No hay comentarios: