sshguard: proteger servicios de ataques de fuerza bruta

Vamos a ver como proteger servicios que estén expuestos en una máquina utilizando sshguard. Un problema con el que hay que lidiar cuando quieres publicar servicios es la exposición de puertos, siempre que publicamos un servicio abrimos una puerta a los intentos de intrusión.

En el caso de puertos como ssh o el protocolo RPD en entornos Windows, que se utilizan para administrar remotamente los servidores, el problema no esta solo en la posible explotación del servicio utilizando una vulnerabilidad sino también en los intentos de acceso utilizando fuerza bruta (frecuentemente ataque por diccionario) donde se utiliza una base de datos de usuarios y passwords que se consideran de uso habitual y se van probando uno tras otro contra el servicio expuesto.

Esto no solo pone a prueba la solidez de nuestras password (que en el caso de ser complejas y personales son difícilmente explotables por este sistema) sino que inunda el sistema de conexiones, y los logs con errores de acceso (en líneas convencionales estos pueden rondar los 30.000 diarios).

Para lidiar con estos problemas existen diferentes soluciones. En algunos protocolos se utilizan proxys o firewalls de aplicación que se encargan de hacer una criba inicial. En otros protocolos la mejor opción es usarlos solo debajo de una VPN. Cuando estas opciones no son posibles podemos todavía usar otras alternativas como los Port Knocking o lo que nos ocupa en este post, los servicios como sshguard.

Lo que hace sshguard es analizar los log en busca de intentos fallidos de acceso. La aplicación reconoce los siguientes formatos de logs:

  • cockpit
  • Common Log Format
  • macOS log (desde la versión 2.0)
  • metalog
  • multilog
  • raw log files
  • syslog
  • syslog-ng
  • systemd journal (desde la versión 2.0)

Para este caso vamos a usar systemd que es actualmente uno de los sistemas más usados. sshguard no se limita solo al protocolo ssh, también es posible buscar ataques de fuerza bruta a en otros servicios. Actualmente los servicios que podemos proteger son:

  • OpenSSH
  • Sendmail
  • Exim
  • Dovecot
  • Cucipop
  • UWimap (imap, pop)
  • vsftpd
  • Postfix
  • proftpd
  • pure-ftpd
  • FreeBSD ftpd

En este caso usaremos ssh (OpenSSH) pero es muy fácil utilizar otros servicios.

Por último están las acciones a tomar cuando se detecta el ataque. Lo que hace sshguard es cerrar la conexión del atacante por un tiempo (puede cerrar el puerto atacado o todos los puertos). Para ello utiliza alguno de los firewall (o backends) siguientes:

  • FirewallD (Linux, dede la versión 2.0)
  • ipfw (FreeBSD, macOS)
  • IPFILTER (FreeBSD, NetBSD, Solaris)
  • netfilter/iptables (Linux)
  • netfilter/ipset (Linux, desde la versión 2.0)
  • PF (OpenBSD, FreeBSD, NetBSD, DragonFly BSD)
  • tcpd's hosts.allow (en casos de no tener ningún firewall activado)
  • IBM AIX's firewall

En este caso vamos a usar iptables en GNU/Linux.

Instalación

En equipos Debian/Ubuntu instalamos las dependencias:

❯ sudo apt install autoconf automake byacc flex gcc python-docutils

Clonamos el repositorio de git, construimos e instalamos:

❯ git clone https://bitbucket.org/sshguard/sshguard.git
❯ cd sshguard
❯ autoreconf -i
❯ ./configure
❯ make
❯ sudo make install

Una cualidad interesante de sshguard es que no tiene ninguna dependencia, de esta forma podemos instalar tan solo los ejecutables sin ninguna librería adicional en nuestros servidores

Configuración

Para la configuración usamos el fichero sshguard.conf que tenemos que crear en /usr/local/etc/. Podemos copiar el fichero de ejemplo que viene en la instalación y hacer las modificaciones oportunas:

❯ sudo cp ~/sshguard/examples/sshguard.conf.sample /usr/local/etc/sshguard.conf

Necesitamos indicar el backend que usaremos, en nuestro caso vamos a usar iptables, y donde se leerán los log (también se indica el tipo de log). Para ello basta con indicar dos opciones, el parámetro BACKEND y el LOGREADER. Quedaría algo como esto:

sshguard.conf
#!/bin/sh 
# sshguard.conf -- SSHGuard configuration 
 
# Options that are uncommented in this example are set to their default 
# values. Options without defaults are commented out. 
 
#### REQUIRED CONFIGURATION #### 
# Full path to backend executable (required, no default) 
BACKEND="/usr/local/libexec/sshg-fw-iptables" 
 
# Space-separated list of log files to monitor. (optional, no default) 
#FILES="/var/log/auth.log /var/log/authlog /var/log/maillog" 
#FILES="/var/log/auth.log"  
 
# Shell command that provides logs on standard output. (optional, no default) 
# Example 1: ssh and sendmail from systemd journal: 
LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -t sshd -o cat" 
# Example 2: ssh from os_log (macOS 10.12+) 
#LOGREADER="/usr/bin/log stream --style syslog --predicate '(processImagePath contains \"sshd\")'" 
 
#### OPTIONS #### 
# Block attackers when their cumulative attack score exceeds THRESHOLD. 
# Most attacks have a score of 10. (optional, default 30) 
THRESHOLD=10 
 
# Block attackers for initially BLOCK_TIME seconds after exceeding THRESHOLD. 
# Subsequent blocks increase by a factor of 1.5. (optional, default 120) 
BLOCK_TIME=120 
 
# Remember potential attackers for up to DETECTION_TIME seconds before 
# resetting their score. (optional, default 1800) 
DETECTION_TIME=1800 
 
# Size of IPv6 'subnet to block. Defaults to a single address, CIDR notation. (optional, default to 128) 
IPV6_SUBNET=128 
 
# Size of IPv4 subnet to block. Defaults to a single address, CIDR notation. (optional, default to 32) 
IPV4_SUBNET=32 

En nuestro fichero de configuración de iptables necesitamos 2 cosas, definir una nueva cadena (chain) llamada sshguard (iptables -N sshguard) e indicar que la cadena INPUT pase por esa cadena creada (iptables -A INPUT -j sshguard). Se recomienda incluirlo en el inicio de las reglas de filtrado de nuestro fichero iptables para descartar los paquetes lo antes posible. 

Una configuración mínima podría ser algo así:

fwbasic.sh
#!/bin/sh 
 
IPTABLES="/sbin/iptables" 
 
# Remove any existing rules from all chains  
$IPTABLES -F 
$IPTABLES -X 
$IPTABLES -t nat -F 
$IPTABLES -t nat -X 
$IPTABLES -t mangle -F 
$IPTABLES -t mangle -X 
 
# Default Policy  
#$IPTABLES -P INPUT ACCEPT 
#$IPTABLES -P FORWARD ACCEPT 
$IPTABLES -P OUTPUT ACCEPT 
#$IPTABLES -P OUTPUT DROP 
$IPTABLES -P INPUT DROP 
$IPTABLES -P FORWARD DROP 
 
# enable active connections  
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 
 
# enable traffic in lo adapter 
$IPTABLES -A INPUT -i lo -m state --state NEW -j ACCEPT 
$IPTABLES -A OUTPUT -o lo -m state --state NEW -j ACCEPT 
 
# sshguard 
$IPTABLES -N sshguard 
$IPTABLES -A INPUT -j sshguard 
 
# SSH WEB 
$IPTABLES -A INPUT -p tcp -m tcp -m multiport --dports 22, 80, 443 -m state --state NEW -j ACCEPT 
 
# log and drop 
$IPTABLES -N RULE_DROP_HV 
$IPTABLES -A INPUT -j RULE_DROP_HV 
$IPTABLES -A RULE_DROP_HV -j LOG --log-level warning --log-prefix "Access to server -- DENY " --log-tcp-sequence --log-tcp-options --log-ip-options 
$IPTABLES -A RULE_DROP_HV -j DROP 

Primero limpiamos todos los chains, definimos la política por defecto (debería ser siempre DROP por defecto en todos los chains, pero en este caso de ejemplo dejo sin filtrar la salida), y permitimos las conexiones establecidas. También permitimos todo en el adaptador loopback. Tenemos también las reglas de sshguard y en este caso solo se permite la entrada por ssh y web. Todo lo demás se escribe en el log y se descarta.

Solo nos queda crear un fichero de unidad de systemd para arrancar la aplicación como un servicio.

Cremos la siguiente unidad en /etc/systemd/system:

sshguard.service
# sshguard.service  
 
[Unit] 
Description=SSHGuard - blocks brute-force login attempts 
After=syslog.target 
After=iptables.target 
After=ip6tables.target 
 
[Service] 
ExecStartPre=/usr/local/sbin/fwbasic.sh 
ExecStart=/usr/local/sbin/sshguard 
Restart=always 
 
[Install] 
WantedBy=multi-user.target 

y la habilitamos:

❯ sudo systemctl enable sshguard

Ya podemos arrancar nuestro servicio:

❯ sudo systemctl start sshguard

Y ya tenemos nuestro sistema funcionando. Cuando se detecten ataques a los puertos que controlamos, en este caso sshsshguard bloqueará la IP del atacante durante 1800 segundos (como hemos indicado en el fichero de configuración). Por otro lado el sistema creará una blacklist con las ip de los atacantes persistentes donde quedarán de forma permanente (en este caso el fichero esta en /usr/local/etc/enemies).

 

Modificado por última vez enViernes, 09 Abril 2021 13:52
(3 votos)

Más en esta categoría:

« Scripts en Nmap

Deja un comentario

Asegúrese de introducir toda la información requerida, indicada por un asterisco (*). No se permite código HTML.