Los servidores VPS son frecuentemente atacados por intrusos. Un tipo común de ataque aparece en los registros del sistema como cientos de intentos de inicio de sesión ssh no autorizados. Configurar un firewall es muy útil, pero por sí solo puede no controlar adecuadamente los intentos de intrusión disruptiva.
Este tutorial muestra cómo construir una barrera de intrusión mejorada para FreeBSD usando dos programas, el ipfw
firewall y sshguard
. SSHGuard es un pequeño programa adicional que monitorea los registros del sistema en busca de entradas "abusivas". Cuando los delincuentes intentan obtener acceso, les sshguard
indica ipfw
que bloqueen el tráfico que se origina en la dirección IP del delincuente. El delincuente queda efectivamente excluido.
Una vez que se comprende cómo funcionan estos programas, administrar la protección del servidor es bastante simple. Aunque esta guía se centra en la configuración de FreeBSD, algunas partes se aplican a otros SO y software de firewall.
Paso 1. Configurando IPFW
FreeBSD ofrece 3 cortafuegos en su defecto ( GENERIC
) kernel, ipfw
, pf
, y ipfilter
. Cada uno tiene ventajas y ventiladores, pero ipfw
es el software de firewall nativo de FBSD y es bastante fácil de usar para nuestros propósitos. Vale la pena señalar que ipfw
hace muchas cosas como lo muestra su página de manual, sin embargo, las capacidades como NAT, configuración de tráfico, etc., no son necesarias para la situación típica de VPS. Afortunadamente, las características básicas del firewall cumplen fácilmente con nuestros requisitos.
Para iniciar el firewall en el momento del arranque, agregue lo siguiente a /etc/rc.conf
:
firewall_enable="YES"
firewall_script="/usr/local/etc/IPFW.rules"
firewall_logging="YES"
El service
comando está disponible para iniciar / detener el firewall manualmente:
[user@vultr ~]$ sudo service ipfw start
Naturalmente, ipfw
no hará nada hasta que agregue reglas, a menudo desde un archivo, en este ejemplo ubicado en /usr/local/etc/IPFW.rules
. De hecho, el archivo de reglas podría ubicarse en cualquier lugar o tener cualquier nombre, siempre que coincida con el parámetro "firewall_script". El archivo de reglas se describe en detalle a continuación.
sshguard
viene en varios sabores para usar con diferentes firewalls. Use la pkg
utilidad para buscar e instalar sshguard-ipfw
:
[user@vultr ~]$ sudo pkg install sshguard-ipfw
En la mayoría de los casos, eso es todo lo que hay que hacer. La variable apropiada se inserta automáticamente /etc/rc.conf
para iniciar el arranque:
sshguard_enable="YES"
Los valores predeterminados normalmente funcionan bien. Si se necesitan valores diferentes, la sshguard
página del manual proporciona información detallada sobre los parámetros:
# sshguard--program defaults, so don't need to be in rc.conf unless assigning different value
# sshguard_pidfile="/var/run/sshguard.pid"
# sshguard_watch_logs="/var/log/auth.log:/var/log/mail"
# sshguard_blacklist="40:/var/db/sshguard/blacklist.db"
# sshguard_safety_thresh="40"
# sshguard_pardon_min_interval="420"
# sshguard_prescribe_interval="1200"
Puede comenzar sshguard
con la service
invocación habitual :
[user@vultr ~]$ sudo service sshguard start
Paso 3. Crear un script de reglas
La parte más difícil es crear el conjunto de reglas del firewall. ipfw
puede utilizar el /etc/rc.firewall
script proporcionado , pero debe modificarse para acomodar SSHGuard, así como diferentes escenarios operativos. Varias páginas web y el Manual de FreeBSD tienen información útil sobre cómo hacer esto. Sin embargo, escribir un archivo de reglas no es tan difícil, además, un conjunto de reglas personalizado puede ser más fácil de entender y cambiar cuando sea necesario.
Una característica importante de las ipfw
reglas es que el primer partido gana, lo que significa que el orden de las reglas es importante. En ipfw
, cada regla es un comando y el archivo de reglas es un script de shell ejecutable. Eso permite cambiar el conjunto de reglas alterando las reglas y luego ejecutando el archivo de reglas como el script de shell que es:
[user@vultr /usr/local/etc]$ sudo ./IPFW.rules
En general, un archivo de reglas definirá una variable para el ipfw
comando, luego borrará las reglas actuales, emitirá reglas genéricas, luego procederá a establecer reglas "fuera", seguidas por las reglas "dentro". La página del manual de ipfw y otros recursos contienen una gran cantidad de información sobre la estructura de reglas y las opciones que son numerosas, por decir lo menos.
Desde que la versión sshguard de FreeBSD se actualizó a la versión 1.6.2, el método de inserción de reglas de bloqueo para delincuentes ha cambiado. Ahora las direcciones de los delincuentes se mantienen en una tabla ipfw (la tabla 22 para ser específica), en lugar de insertarse en las reglas anteriores a 55000 como antes.
Afortunadamente, es bastante simple configurar el archivo de reglas para usar la tabla. Es solo una cuestión de colocar la regla de la tabla en el lugar correcto y asegurarse de usar la sintaxis correcta al escribir la regla.
Cuando sshguard
encuentra un delincuente, coloca la dirección del delincuente en su lista negra y también inserta la dirección en la ipfw
tabla para que "active" la denegación de acceso. Esta regla cumplirá estos propósitos:
01000 deny ip from table\(22\) to any
Todavía es necesario poner reglas que permitan servicios entrantes por encima de 01000 en este caso. Por ejemplo, supongamos que la dirección 10.20.30.40
es un infractor en la tabla 22, y tenemos esta regla ipfw:
56420 allow tcp from any to me dst-port 22 in via $vif
Dado que ipfw
encuentra la regla 01000 antes de la regla 56420 , 10.20.30.40
está bloqueada . Nunca será visto por la regla "permitir 22 en" en absoluto. Si la regla de permiso tuviera un número "normal" como 00420 , el tráfico incorrecto se dejaría entrar y nunca se bloquearía (porque 00420 es menor que 01000 y "el primer partido gana").
Una buena característica de la versión actualizada es que ahora, cuando se inicia sshguard, todas las direcciones de la lista negra se agregan a la tabla y están disponibles para bloquear a los delincuentes entrantes sin demora. La lista negra es acumulativa y se retiene entre sesiones.
En este punto, probablemente sea sensato mostrar un ipfw
conjunto de reglas completo modificado para sshguard
. Los comentarios deberían hacer que sea bastante fácil seguir la lógica de la regla:
#!/bin/sh
# ipfw config/rules
# from FBSD Handbook, rc.firewall, et. al.
# Flush all rules before we begin.
ipfw -q -f flush
# Set rules command prefix
cmd="ipfw -q add "
vif="vtnet0"
# allow all for localhost
$cmd 00010 allow ip from any to any via lo0
# checks stateful rules. If marked as "keep-state" the packet has
# already passed through filters and is "OK" without futher
# rule matching
$cmd 00101 check-state
# allow DNS out
$cmd 00110 allow tcp from me to any dst-port 53 out via $vif setup keep-state
$cmd 00111 allow udp from me to any dst-port 53 out via $vif keep-state
# allow dhclient connection out (port numbers are important)
$cmd 00120 allow udp from me 68 to any dst-port 67 out via $vif keep-state
# allow HTTP HTTPS replies
$cmd 00200 allow tcp from any to any dst-port 80 out via $vif setup keep-state
$cmd 00220 allow tcp from any to any dst-port 443 out via $vif setup keep-state
# allow outbound mail
$cmd 00230 allow tcp from any to any dst-port 25 out via $vif setup keep-state
$cmd 00231 allow tcp from any to any dst-port 465 out via $vif setup keep-state
$cmd 00232 allow tcp from any to any dst-port 587 out via $vif setup keep-state
# allow icmp re: ping, et. al.
# comment this out to disable ping, et.al.
$cmd 00250 allow icmp from any to any out via $vif keep-state
# alllow timeserver out
$cmd 00260 allow tcp from any to any dst-port 37 out via $vif setup keep-state
# allow ntp out
$cmd 00270 allow udp from any to any dst-port 123 out via $vif keep-state
# allow outbound SSH traffic
$cmd 00280 allow tcp from any to any dst-port 22 out via $vif setup keep-state
# otherwise deny outbound packets
# outbound catchall.
$cmd 00299 deny log ip from any to any out via $vif
# inbound rules
# deny inbound traffic to restricted addresses
$cmd 00300 deny ip from 192.168.0.0/16 to any in via $vif
$cmd 00301 deny ip from 172.16.0.0/12 to any in via $vif
$cmd 00302 deny ip from 10.0.0.0/8 to any in via $vif
$cmd 00303 deny ip from 127.0.0.0/8 to any in via $vif
$cmd 00304 deny ip from 0.0.0.0/8 to any in via $vif
$cmd 00305 deny ip from 169.254.0.0/16 to any in via $vif
$cmd 00306 deny ip from 192.0.2.0/24 to any in via $vif
$cmd 00307 deny ip from 204.152.64.0/23 to any in via $vif
$cmd 00308 deny ip from 224.0.0.0/3 to any in via $vif
# deny inbound packets on these ports
# auth 113, netbios (services) 137/138/139, hosts-nameserver 81
$cmd 00315 deny tcp from any to any dst-port 113 in via $vif
$cmd 00320 deny tcp from any to any dst-port 137 in via $vif
$cmd 00321 deny tcp from any to any dst-port 138 in via $vif
$cmd 00322 deny tcp from any to any dst-port 139 in via $vif
$cmd 00323 deny tcp from any to any dst-port 81 in via $vif
# deny partial packets
$cmd 00330 deny ip from any to any frag in via $vif
$cmd 00332 deny tcp from any to any established in via $vif
# allowing icmp re: ping, etc.
$cmd 00310 allow icmp from any to any in via $vif
# allowing inbound mail, dhcp, http, https
$cmd 00350 allow udp from any 53 to me in via $vif
$cmd 00360 allow tcp from any 53 to me in via $vif
$cmd 00370 allow udp from any 67 to me dst-port 68 in via $vif keep-state
$cmd 00400 allow tcp from any to me dst-port 80 in via $vif setup limit src-addr 2
$cmd 00410 allow tcp from any to me dst-port 443 in via $vif setup limit src-addr 2
# SSHguard puts offender addresses in table 22. Set up the table rule
# Please note the '\(22\)' syntax, necessary since it's run as shell command
$cmd 01000 deny ip from table\(22\) to any
# allow inbound ssh, mail. PROTECTED SERVICES: numbered ABOVE sshguard blacklist range
$cmd 56420 allow tcp from any to me dst-port 22 in via $vif setup limit src-addr 2
$cmd 56530 allow tcp from any to any dst-port 25 in via $vif setup keep-state
$cmd 56531 allow tcp from any to any dst-port 465 in via $vif setup keep-state
$cmd 56532 allow tcp from any to any dst-port 587 in via $vif setup keep-state
# deny everything else, and log it
# inbound catchall
$cmd 56599 deny log ip from any to any in via $vif
# ipfw built-in default, don't uncomment
# $cmd 65535 deny ip from any to any
Paso 4. Inicio y prueba
Las necesidades del sistema varían y las diferentes opciones de puertos para bloquear o desbloquear se reflejan en el conjunto de reglas. Una vez que el conjunto de reglas haya finalizado, guarde el archivo /usr/local/etc/IPFW.rules
e inicie los servicios de FBSD:
# service ipfw start
# service sshguard start
¡El firewall aumentado ahora debería estar ejecutándose! Comprobar sshguard
:
[user@vultr ~]$ sudo pgrep -lfa ssh
Si se sshguard
está ejecutando, se muestran su línea de comando pid y completa:
720 /usr/local/sbin/sshguard -b 40:/var/db/sshguard/blacklist.db -l /var/log/auth.log -l /var/log/maillog -a 40 -p 420 -s 1200 -w /usr/local/etc/sshguard.whitelist -i /var/run/sshguard.pid
Esto muestra el conjunto de reglas del firewall con estadísticas y la última vez que un paquete coincide con la regla:
[user@vultr ~]$ sudo ipfw -cat list
Después de horas o días, las direcciones de los delincuentes se agregan a la lista negra y también a la tabla 22. Para ver todas las direcciones en la tabla, use este comando:
ipfw table 22 list
El resultado se imprime como:
10.10.10.118/32 0
10.10.10.72/32 0
...
Como se describió anteriormente, las conexiones desde estas direcciones no están permitidas. Por supuesto, en la primera ejecución sshguard
no habrá ninguna dirección en la lista, pero con el tiempo puede llegar a ser bastante larga. Una opción es crear reglas de bloqueo separadas para direcciones con múltiples entradas en la tabla y luego eliminarlas de la lista negra.
Paso 5. Mantenerse vigilante ...
Es una buena idea verificar ocasionalmente los registros para asegurarse de que las intrusiones estén controladas. En general, /var/log/auth.log
y /var/log/security
son informativos. Pueden aparecer lagunas o errores en la cobertura de los servicios de red. La modificación del conjunto de reglas del firewall según sea necesario es una parte normal de la administración del servidor.
En versiones anteriores de sshguard, cuando el /var/db/sshguard/blacklist.db
archivo había crecido, podía evitar que se sshguard
iniciara al iniciar el sistema. Eliminar o renombrar el archivo de la lista negra permitido sshguard
comenzar. Este problema parece estar solucionado en la última versión de sshguard, por lo que esta solución probablemente ya no sea necesaria.
Asegúrese de incluir en la lista blanca la dirección IP desde la que está conectado a la sesión SSH. Si accidentalmente se bloquea, siempre puede conectarse a la consola noVNC en https://my.vultr.com y poner en la lista blanca su IP.
En resumen, usar la combinación de ipfw
y sshguard
ayuda a mantener su sistema FreeBSD seguro y haciendo su trabajo. Minimizar la actividad intrusiva de la red tiene un beneficio adicional: menos "ruido" hace que sea más fácil rastrear y ajustar la operación del sistema, lo que contribuye a un servidor más seguro y de mejor funcionamiento.
Proteger efectivamente un sistema / servidor FreeBSD no es especialmente complicado. Si bien se requiere un esfuerzo modesto para ponerlo en funcionamiento, vale la pena en un VPS y una seguridad del proyecto sustancialmente mayores.