Seguridad
- Instalación y uso del cortafuegos ufw
- Cambiar los puertos por defecto
- Asegurar el servidor SSH
- Conexión SSH mediante clave pública
- Cambiar el nombre del usuario principal
- Instalar Fail2ban
- Crear un túnel SSH
- DNS sobre HTTPS
Instalación y uso del cortafuegos ufw
Sin un cortafuegos activo, nuestra Raspberry está expuesta a recibir posibles ataques e intrusiones desde Internet (o incluso desde otros ordenadores de la red local). El cortafuegos nos permite vigilar los puertos de comunicaciones y controlar todo lo que entra en nuestra máquina desde el exterior y también todo lo que sale de ella hacia fuera. De todas las posibilidades que ofrece Raspberry Pi OS, hemos elegido ufw porque, a nuestro juicio, es el más fácil de configurar. De hecho, su nombre se correspone con el acrónimo de uncomplicated firewall (cortafuegos sin complicaciones).
Así pues, vamos a instalarlo:
sudo apt install ufw
Por defecto, el firewall ya incorpora un par de reglas básicas: impide todo el tráfico entrante, pero permite el tráfico saliente. Esto sería el equivalente a escribir estas dos reglas:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Puertos y servicios
Para trabajar con ufw y manejar los puertos es necesario saber que cada puerto admite dos protocolos: TCP y UDP. Al abrir un puerto debemos indicar, como veremos más adelante, el protocolo que queremos usar. Si no indicamos ninguno, se usarán ambos.
Para facilitarnos la tarea, el cortafuegos trae ya predefinidos algunos de los servicios más habituales. Para conocer la lista completa de estos servicios, escribimos el siguiente comando:
sudo ufw app list
Así pues, podemos permitir la entrada, por ejemplo, al servidor SSH de la forma habitual, es decir, indicando el número del puerto:
sudo ufw allow 22/tcp
o, gracias a dicha lista, de una forma más sencilla, haciendo referencia simplemente al nombre del servicio:
sudo ufw allow SSH
Lo mismo sucede en el caso del servidor web que tengamos instalado, ya sea éste Apache, Nginx, Lighttpd o cualquier otro. Podemos hacerlo de las dos maneras que acabamos de ver; bien abriendo directamente el puerto:
sudo ufw allow 80/tcp
o bien haciendo referencia al servicio correspondiente:
sudo ufw allow WWW
También viene predefinido el protocolo CIFS, que es el que usa el servidor Samba. Gracias a ello es posible abrir los puertos correspondientes (ya que son varios, unos TCP y otros UDP) ya sea usando el nombre del protocolo::
sudo ufw allow CIFS
o mediante el nombre del servidor:
sudo ufw allow Samba
A continuación vamos a abrir los puertos que utilizan otros servicios que tenemos instalados en la Raspberry. El primero que abriremos será el puerto 9091, que es el que viene asignado por defecto para acceder a Transmission mediante el navegador web, y también el puerto que hayamos indicado en la configuración del programa para establecer las conexiones (supongamos que es el 44027):
sudo ufw allow 9091/tcp
sudo ufw allow 44027 [se usan ambos protocolos: TCP y UDP]
Haremos lo propio asimismo con los puertos 21, 8200 y 1194, que se refieren, respectivamente, a los servidores FTP, DLNA y WireGuard que tenemos instalados en nuestro sistema:
sudo ufw allow 21/tcp
sudo ufw allow 8200/tcp
sudo ufw allow 51820/udp
Intervalos de puertos
Si tenemos la necesidad de abrir varios puertos consecutivos (por ejemplo, del 25000 al 30000, como en el caso de los puertos pasivos del servidor FTP), podemos abrirlos todos de una vez:
sudo ufw allow 25000:30000/tcp
Limitar conexiones
En algunos servicios, como SSH, resulta muy útil poder limitar la cantidad de conexiones que se pueden realizar en un tiempo determinado:
sudo ufw limit 22/tcp
Con esta regla se pueden denegar conexiones a una dirección IP que haya intentado realizar 6 o más conexiones en los últimos 30 segundos. Esta opción resulta muy útil para defenderse de bots que realizan ataques de fuerza bruta.
Permitir entradas por IP
Es posible indicar al cortafuegos que permita la entrada a una IP concreta:
sudo ufw allow from 203.1.117.4
O indicar si queremos circunscribir dicha entrada a un puerto específico:
sudo ufw allow from 203.1.117.4 to any port 22 proto tcp
De esta forma, sólo desde la IP indicada se tendrá acceso al sevidor SSH.
Permitir servicios LAN
Como acabamos de ver, y opcionalmente para aquellos servicios que vayamos a usar exclusivamente dentro de nuestra LAN, es decir, sólo de forma interna y que, por tanto, no necesitan salir a Internet (como DLNA, CUPS, Samba o RPi-Monitor), en lugar de abrir por separado cado uno de los puertos que corresponden a esos servicios (como hemos hecho más arriba), podemos decirle al cortafuegos, de una sola vez, que acepte todas las conexiones provenientes de cualquier dispositivo de nuestra red local:
sudo ufw allow from 192.168.1.0/24
O que acepte sólo las destinadas a un puerto concreto:
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
Denegar entradas
Lo mismo que creamos reglas para permitir la entrada por un puerto y acceder al servicio asociado al mismo, también podríamos, si fuera necesario, denegarla. Por ejemplo, impedir el acceso al servidor web:
sudo ufw deny 80/tcp [HTTP]
sudo ufw deny 443/tcp [HTTPS]
O denegar el acceso a un determinado host indicando su IP:
sudo ufw deny from 192.168.1.35 to any [red local/LAN]
sudo ufw deny from 202.54.5.7 to any [red externa/WAN]
Es posible indicar la IP y también especificar el puerto:
sudo ufw deny from 202.54.5.7 to any port 80 proto tcp
Pero si ya tenemos reglas previamente establecidas para ese puerto (por ejemplo, sudo ufw allow 80/tcp), entonces es necesario que la nueva regla se ejecute antes, por lo que hemos de darle prioridad colocándola en primer lugar:
sudo ufw insert 1 deny from 202.54.5.7 to any port 80 proto tcp
Borrar reglas
A la hora de borrar una regla ya establecida, lo más cómodo es usar el siguiente comando, que nos las ofrece numeradas:
sudo ufw status numbered
De esta forma, sólo tenemos que indicar su número en el listado. Por ejemplo:
sudo ufw delete 2
Aunque también es posible hacerlo indicando el puerto (o puertos) incluido/s en la regla que queremos eliminar:
sudo ufw delete allow 22/tcp
Interfaces de red
Con el comando ifconfig se nos muestran todas las interfaces de red que tenenos activas. Si queremos aplicar reglas sólo a la interfaz Ethernet (eth0), haremos lo siguiente:
sudo ufw allow in on eth0 to any port 80 proto tcp
Si, por el contrario, deseamos que se aplique a la interfaz inalámbrica (wlan0), usaremos este nombre en la regla:
sudo ufw allow in on wlan0 to any port 22 proto tcp
Comandos importantes
Veamos otros comandos importantes. Por ejemplo, una vez instalado el cortafuegos y definidas las reglas, es necesario activarlo:
sudo ufw enable
También podemos desactivarlo:
sudo ufw disable
Reiniciarlo:
sudo /etc/init.d/ufw restart
Mostrar su estado:
sudo ufw status verbose
O borrar todas las reglas de una vez y dejar ufw por defecto:
sudo ufw reset
Con ufw ya configurado y activado, podremos acceder a través de la red (tanto LAN como WAN) a las distintas aplicaciones y servidores que hemos ido instalando en la Raspberry Pi. Es muy importante recordar esto: si queremos tener acceso a un servicio instalado en nuestra placa, ya sea desde la red local o a través de Internet, tenemos que abrir antes el puerto correspondiente en el cortafuegos (tanto para acceso LAN como WAN) y en el router (sólo para acceso WAN). Si no lo hacemos, ufw impedirá el acceso y no podremos conectar con dicho servicio.
El fichero de log
El cortafuegos posee un fichero de log donde se guardan las peticiones de conexión entrantes y salientes. Para comprobar si lo tenemos activado, escribimos lo siguiente:
sudo ufw status verbose
Probablemente veamos Logging: on (low), lo que significa que está activado en el nivel por defecto, que es bajo (low). Si mostrara Logging: off, entonces es que está desactivado. Lo podemos activar con
sudo ufw logging on
Para ver su contenido es conveniente usar el comando less:
sudo less /var/log/ufw.log
Con la barra espaciadora continuaremos viendo el fichero hasta llegar al final del mismo y entonces podremos salir con la tecla q.
El fichero anterior no es el único donde se guardan datos de logs. También existen otros dos, de carácter general, pero cuyo contenido se puede filtrar usando grep:
sudo grep -i ufw /var/log/syslog
sudo grep -i ufw /var/log/kern.log
Como vimos antes, el nivel por defecto para los logs es low, pero existen cinco niveles: off, low, medium, high y full. Podemos cambiarlo así:
sudo ufw logging logging_level
Cambiar los puertos por defecto
Además de usar un cortafuegos, una buena manera de proteger aún más nuestra máquina contra posibles intrusiones externas es cambiar los puertos por defecto de los distintos servicios que estemos usando. Tomemos como ejemplo los puertos estándar de los servidores SSH y HTTP (servidor web), que son el 22 y el 80, respectivamente. En el fichero de configuración /etc/ssh/sshd_config podemos modificar el puerto del servidor SSH, mientras que en el fichero /etc/apache2/ports.conf es posible hacer lo mismo con el servidor web Apache.
Si lo hacemos, hemos de tener en cuenta que a partir de entonces, cuando queramos acceder al servicio correspondiente, debemos incluir el número del puerto. Por ejemplo, si cambiamos el puerto del servidor web al 8090, ahora tendremos que escribirlo al final y precedido de dos puntos (:), así:
http://midominio.com:8090 [acceso por Internet]
http://192.168.1.33:8090 [acceso por red local]
En el caso del servidor SSH, lo indicaremos mediante -p puerto, del siguiente modo:
ssh -p 35126 piuser@midominio.com [acceso por Internet]
ssh -p 35126 piuser@192.168.1.33 [acceso por red local]
Asegurar el servidor SSH
Si accedemos a nuestra Raspberry mediante SSH a través de Internet, deberíamos de preocuparnos por asegurar el servidor, ya que los intentos de acceso no autorizado a los servidores SSH son muy frecuentes. Veamos a continuación algunos parámetros que podemos modificar o añadir para que nuestro servidor SSH esté más seguro.
Lo primero que tenemos que hacer es entrar en el archivo de configuración para realizar los cambios:
sudo nano /etc/ssh/sshd_config
Veremos una gran cantidad de opciones de configuración en él. Una de las primeras que encontraremos es la que indica el puerto de acceso al servidor, que por defecto es el 22. Si lo cambiamos (poniendo, por ejemplo, el puerto 3426), dificultaremos mucho el trabajo a quien intente acceder a nuestra máquina:
Port 3426
Algo importante que debemos comprobar es la directiva de seguridad que permite o deniega el acceso a root, el superusuario o administrador de los sistemas UNIX/Linux. Muchos de los ataques que se realizan, especialmente contra servidores, se concentran en particular sobre este usuario con la esperanza de que tenga una contraseña débil, algo que (desgraciadamente) sucede con demasiada frecuencia.
Por defecto, la directiva que controla el acceso de root se encuentra así:
PermitRootLogin prohibit-password
Esto significa que se prohíben todos los métodos de autentificación interactivos, permitiendo sólo la autentificación mediante Publickey, Hostbased y GSSAPI. Sin embargo, es mucho más seguro no permitir el acceso del administrador del sistema de ninguna de las maneras. Por eso, lo que haremos será impedir la entrada a root de todas las formas posibles, sean cuales sean, lo que conseguiremos cambiando así esta línea:
PermitRootLogin no
Otra opción que podemos modificar es la que indica la cantidad de minutos que la pantalla de login estará disponible para que el usuario se identifique. Pasado ese tiempo, si no nos hemos identificado, la conexión se cerrará:
LoginGraceTime 1m
Prestaremos atención asimismo a las dos siguientes directivas de seguridad:
MaxAuthTries 3
MaxSessions 4
Sirven para dificultar los ataques de fuerza bruta. La primera indica el número máximo de errores permitidos al hacer login. Si sobrepasamos ese número, se nos mostrará un mensaje de error y habrá que volver a empezar de nuevo. La segunda directiva se refiere al número máximo de conexiones simultáneas por IP que permite el servidor.
Aunque por defecto las siguientes líneas ya vienen configuradas correctamente, no está de más asegurarnos de que se exija el uso de una contraseña de acceso y que no se acepten contraseñas vacías o en blanco:
PasswordAuthentication yes
PermitEmptyPasswords no
Hechas las modificaciones, guardamos los cambios y comprobamos que la configuración del fichero es correcta, para lo cual hay que escribir este comando:
sudo sshd -t
Si no aparece ningún mensaje de error, es que todo está bien. Es importante comprobar que el archivo de configuración es correcto porque si no, cuando reiniciemos el servicio (o la propia Raspberry), el servidor SSH no arrancará y no podremos conectarnos.
Una vez que nos hemos asegurado de que todo está en orden, necesitamos reiniciar el servicio para que los cambios surtan efecto:
sudo service ssh restart
Permitir o prohibir el acceso a usuarios
Si hay varios usuarios en el sistema, podemos añadir también al final del fichero de configuración una directiva para que sólo los usuarios especificados tengan acceso al mismo:
AllowUsers piuser josem
O, si se prefiere, usar en su lugar esta otra para impedir el acceso a los usuarios que se indican expresamente en ella:
DenyUsers luisp manuh
Comprobar intentos de acceso no autorizados
Periódicamente es aconsejable mirar el fichero /var/log/auth.log para comprobar si ha habido algún intento de entrada ilegal. Si los hubiese, el siguiente comando nos ayudará a encontrarlos:
sudo cat /var/log/auth.log | grep 'Invalid user\|Failed'
Y este otro contará cuántas líneas con intentos de intrusión aparecen:
sudo cat /var/log/auth.log | grep 'Invalid user\|Failed' | wc -l
Conocer el origen de la IP atacante
Podemos conocer el país de donde provienen los intentos de entrada ilegal en nuestro servidor SSH instalando esta utilidad:
sudo apt install geoip-bin
Sólo tenemos que indicar la IP obtenida en el fichero /var/log/auth.log y nos dirá a qué país pertenece. Por ejemplo:
geoiplookup 218.87.109.156
GeoIP Country Edition: CN, China
Es posible afinar aún más la búsqueda y conocer el país, la localidad donde tiene su origen la IP e incluso el ISP que la suministra. Para ello podemos ir a este sitio web. Además de esos datos, esta otra web nos permite saber si la IP ha sido denunciada por otros usuarios como maliciosa.
Más sobre seguridad
Para finalizar, añadiremos un par de notas importantes para hacer que nuestro servidor resulto más seguro:
- 1.) Las contraseñas de usuario que usemos deben de ser "fuertes", es decir, tener cierta extensión (8 caracteres o más) y estar compuestas por una combinación de letras (mayúsculas y minúsculas), números y otros caracteres no alfabéticos (como signos de puntuación). Además, la palabra resultante no debe tener sentido, de manera que no aparezca en ningún diccionario.
- 2.) En lugar de usar una contraseña, también podemos, como se muestra en el siguiente apartado, conectarnos empleando autentificación mediante clave pública. Este sistema, además de ahorrarnos el tener que memorizar la contraseña, resulta un método de acceso muchísimo más seguro, prácticamente imposible de romper por fuerza bruta. Emplear este método es especialmente recomendable si, por algún motivo, nos venos obligados a usar el puerto SSH estándar (22).
Conexión SSH mediante clave pública
Cuando nos conectamos a la Raspberry por SSH, lo hacemos normalmente mediante un usuario y una contraseña. Sin embargo, es mucho más seguro hacerlo utilizando un par de claves (pública y privada), con lo que, además, ya no será necesario tener que recordar la contraseña cada vez que nos conectemos.
Si utilizamos alguna versión de Linux o de macOS en nuestro PC, podremos generar las dos claves desde el mismo y enviar la clave pública a la Raspberry. Lo haremos de esta forma (cambiando piuser por el nombre del usuario que estemos usando en nuestro sistema):
cd .ssh
ssh-keygen -t rsa -b 2048 -f id_rsa -P ""
ssh piuser@192.168.1.33 < ~/.ssh/id_rsa.pub 'mkdir -p .ssh && cat >> .ssh/authorized_keys'
Lo que hemos hecho es ir al directorio oculto .ssh de nuestro PC, generar un par de claves RSA de 2048 bits y luego enviar a la Raspberry (cuya IP local es 192.168.1.33) el contenido del fichero que posee la clave pública (id_rsa.pub), que se copiará dentro del archivo /home/piuser/.ssh/authorized_keys.
A continuación entramos en la Raspberry, editamos el fichero de configuración del servidor SSH:
sudo nano /etc/ssh/sshd_config
y anulamos la autentificación mediante contraseña, de manera que quede así:
PasswordAuthentication no
Ya sólo queda reiniciar el servidor para que el cambio en la modalidad de acceso surta efecto:
sudo service ssh restart
Es MUY IMPORTANTE guardar ambos ficheros en un sitio seguro. La clave privada (id_rsa) tenemos que copiarla en cada uno de los dispositivos desde los que vayamos a acceder a la Raspberry. En los sistemas Linux, lo habitual es guardarla en el directorio oculto /home/usuario/.ssh. Además, es necesario que el fichero tenga permiso (normalmente de sólo lectura) únicamente para el usuario que va a realizar la conexión, pero no para los demás; es decir:
chmod 400 id_rsa
Si lo hemos hecho como acabamos de indicar, nos conectaremos escribiendo el siguiente comando:
ssh -i "~/.ssh/id_rsa" piuser@192.168.1.33
Cambiar el nombre del usuario principal
Las versiones anteriores de Raspberry Pi OS se instalaban con un usuario (pi) y su contraseña (raspberry) creados por defecto. A partir de la versión del 4 de Abril de 2022 es necesario, por razones de seguridad, escribir un nombre de usuario y una contraseña personalizada durante la instalación, tal y como se muestra aquí. Pero en cualquier momento podemos volver a cambiar el nombre del usuario.
MUY IMPORTANTE: Si deseamos hacer esto, el momento de hacerlo es justo después de instalar el SO y antes de instalar ninguna otra aplicación, pues estas podrían configurarse con el usuario por defecto, y al cambiar éste posteriormente, obtendríamos mensajes de error o problemas de funcionamiento.
Para realizar el cambio, será necesario habilitar la cuenta del administrador de los sistemas Linux, llamado root. Y para lograrlo, lo único que debemos hacer es asignale a éste una contraseña:
sudo passwd root
Alterar la seguridad
Como medida de seguridad, no se permite la conexión por SSH al usuario root, así que tendremos que cambiar esto para permitirle el acceso. Para lograrlo, editamos el fichero de configuración del servidor SSH:
sudo nano /etc/ssh/sshd_config
Buscamos la variable PermitRootLogin y le cambiamos el valor a yes:
PermitRootLogin yes
Ahora reiniciamos el sistema:
sudo reboot
y entramos por SSH como root. Siendo administrador, ya podemos renombrar al usuario actual (supongamos que es piuser) por un nuevo nombre de usuario (por ejemplo, jlopez) y mover todo el contenido de la carpeta personal de piuser a la carpeta personal del nuevo usuario:
usermod -l jlopez piuser -md /home/jlopez
Hacemos lo mismo con el grupo, cambiando el nombre del anterior por el nuevo:
groupmod -n jlopez piuser
Efectuados todos los pasos anteriores, ya podemos reiniciar:
sudo reboot
y entrar con el nombre del nuevo usuario que hemos creado (jlopez), cuya contraseña será la misma que tenía el usuario anterior.
Restablecer la seguridad
Para dejar las cosas como estaban inicialmente y evitar comprometer la seguridad del sistema, haremos dos cosas. Primero deshabilitamos el usuario root, para lo cual basta con eliminar su contraseña:
sudo passwd -l root [nos pedirá la contrasela de jlopez]
En segundo lugar, volvemos a editar el fichero de configuración del servidor SSH:
sudo nano /etc/ssh/sshd_config
e impedimos el acceso al administrador (aunque ya esté inhabilitado en el sistema) volviendo a asignar el valor no a la directiva PermitRootLogin:
PermitRootLogin no
Sólo nos queda reiniciar el servidor para que el cambio surta efecto:
sudo service ssh restart
AVISO: Como medida de seguridad extra, el sistema nos pedirá que introduzcamos la contraseña del usuario cada cierto tiempo cuando hagamos uso del comando sudo.
Instalar Fail2ban
Una buena manera de incrementar la seguridad en la Raspberry es instalar el servicio Fail2ban, que vigila los intentos de acceso a los servidores que tengamos instalados y banea (bloquea) aquellas IPs que hayan hecho un intento ilegal de entrar en el sistema mediante ataques de fuerza bruta:
sudo apt install fail2ban
Lo primero que haremos será una copia del fichero de configuración, pero cambiando la extensión .conf por .local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Y trabajaremos sobre esta copia, así que procedemos a editarla:
sudo nano /etc/fail2ban/jail.local
En la sección [DEFAULT] encontramos varias líneas relativas a la configuración genérica del servicio. Las fundamentales son: ignoreip (IPs que no deseemos que se baneen, que corresponden a localhost [127.0.0.1/8 ::1], y además añadiremos todas las IPs de nuestra red local [192.168.1.0/24]); bantime (tiempo de bloqueo); findtime (tiempo durante el que se espera hasta alcanzar el número máximo de intentos de acceso fallidos de un cliente) y maxretry (número de intentos de login fallidos para que se active el bloqueo).
[DEFAULT]
#
# MISCELLANEOUS OPTIONS
#
# "ignoreip" can be a list of IP address, CIDR masks or DNS hosts...
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
. . . . . .
bantime = 30m
findtime = 25m
maxretry = 3
. . . . . .
En el ejemplo anterior, el servicio se ha configurado de tal forma que, si durante un plazo de 25 minutos (findtime), un cliente (dirección IP) realiza 3 intentos fallidos de acceso (maxretry), su IP será bloqueada durante 30 minutos (bantime). Hasta que no transcurra dicho tiempo, no se le permitirá volver a hacer un nuevo intento de conexión. El tiempo suele indicarse en segundos, aunque, para mayor comodidad, también puede añadirse una letra para expresarlo en minutos (m), horas (h), días (d) o semanas (w).
Más abajo, en el apartado JAILS es donde se activa cada uno de los servicios que tengamos instalados. Así, en [sshd] activaremos la seguridad del servidor SSH contra ataques de fuerza bruta. Cada servicio se activa poniendo enabled = true al comienzo de su sección. La opción mode la podemos dejar como viene por defecto (normal). En port dejamos ssh si estamos usando el puerto por defecto (22) o bien pondremos el número de puerto por el que hayamos decidido cambiarlo. Si lo deseamos, es posible poner un bantime y un maxretry específicos para cada servicio. Las demás opciones las dejamos como están.
#
# JAILS
#
#
# SSH servers
#
[sshd]
# To use more aggressive sshd modes...
enabled = true
mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
. . . . . .
Como se puede ver si continuamos bajando aún más en el fichero de configuración, Fail2ban se puede aplicar también a otros servidores que tengamos instalados (servidor web, servidor FTP, servidor MySQL/MariaDB, etc.). Por ejemplo, en el caso de tener un servidor web con Apache, deberíamos de activar al menos estos módulos:
#
# HTTP servers
#
[apache-auth]
enabled = true
. . . . . .
[apache-badbots]
enabled = true
. . . . . .
[apache-noscript]
enabled = true
. . . . . .
[apache-overflows]
enabled = true
. . . . . .
Y si hemos instalado Nginx, estos dos:
[nginx-http-auth]
enabled = true
. . . . . .
[nginx-botsearch]
enabled = true
. . . . . .
Acabada la configuración, sólo tenemos que reiniciar el servicio:
sudo service fail2ban restart
Comprobaciones
Desde este momento podremos realizar diversas comprobaciones, como conocer su estado:
systemctl status fail2ban
Ver los servicos que tenemos activos:
sudo fail2ban-client status
O el estado actual de un servicio concreto (ssh en este caso), que nos mostrará si tiene alguna IP baneada en este momento:
sudo fail2ban-client status sshd
Se puede echar un vistazo al fichero de log para comprobar si ha habido intentos de acceso no autorizados:
sudo cat /var/log/fail2ban.log
Pero es más fácil y rápido hacerlo con este comando, que muestra las IPs bloqueadas/desbloqueadas y en qué servicio han tenido lugar:
sudo cat /var/log/fail2ban.log | grep 'Ban\|Unban'
O con este otro, que muestra un resultado similar al anterior: el servicio afectado y las IPs bloqueadas:
sudo fail2ban-client banned
Bloqueo manual
Si lo deseamos, es posible bloquear una IP manualmente para un servicio concreto:
sudo fail2ban-client set sshd banip 232.68.124.21
O desbloquearla:
sudo fail2ban-client set sshd unbanip 232.68.124.21
Baneo especial a las IPs reincidentes
Fail2ban ya tiene una "cárcel" (jail) para combatir la reincidencia. Sólo tenemos que editar el fichero de configuración:
sudo nano /etc/fail2ban/jail.local
y buscar con Ctrl+w el apartado [recidive], activarlo y darle un tratamiento especial a esas IPs que persisten una y otra vez en reintentar su entrada ilegal:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 2w
findtime = 2d
Para que esto funcione, debemos asegurarnos de que el nivel de registro (loglevel) no esté puesto en DEBUG:
sudo fail2ban-client get loglevel
Lo normal es que esté en INFO, con lo que todo está correcto y no es necesario hacer nada más. Pero si no fuera así y estuviera en DEBUG, necesitamos cambiar el loglevel. Para ello, haremos una copia del fichero principal de configuración:
sudo cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local
Editamos el nuevo archivo que hemos creado:
sudo nano /etc/fail2ban/fail2ban.local
y ponemos el nivel de registro a INFO:
[DEFAULT]
# Option: loglevel
# Notes.: Set the log level output.
# CRITICAL
# ERROR
# WARNING
# NOTICE
# INFO
# DEBUG
# Values: [ LEVEL ] Default: ERROR
#
loglevel = INFO
Hecho el cambio, reiniciamos el servicio y comprobamos que el nivel ha cambiado, de manera que ya no aparece DEBUG sino INFO:
sudo service fail2ban restart
sudo fail2ban-client get loglevel
Para comprobar las IPs baneadas:
sudo fail2ban-client status recidive
Fail2ban no funciona correctamente
1.) No se activa después de instalar
Tras instalar y configurar el servicio, al iniciarlo por primera vez y comprobar su estado con
sudo systemctl start fail2ban
sudo systemctl status fail2ban
obtenemos un mensaje de error similar al siguiente:
ERROR Failed during configuration: Have not found any log file for sshd jail
Esto ocurre porque, por algún motivo, no existe el fichero de log /var/log/auth.log asociado al servidor SSH. Podríamos crearlo manualmente, pero la forma más adecuada de hacerlo es instalando el paquete rsyslog:
sudo apt install rsyslog
y reiniciando a continuación el sistema:
sudo reboot
Ahora ya podemos comprobar que está activo:
sudo systemctl status fail2ban
2.) No se activa al reiniciar
Si nos encontramos con el problema de que el servicio no se activa automáticamente tras apagar o reiniciar el sistema (lo comprobamos con sudo systemctl status fail2ban), debemos ejecutar estos tres comandos:
sudo fail2ban-client stop
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Esta acción debería de solucionar el problema.
Recibir un correo de alerta al bloquear una IP
Podemos hacer que Fail2ban nos envíe un correo cuando detecte un intento de intrusión y bloquee una determinada IP, informándonos de este hecho. Para lograrlo, lo primero que hemos de hacer es seguir los pasos para instalar un sistema de envío de correos desde la terminal.
Luego volvemos al fichero de configuración:
sudo nano /etc/fail2ban/jail.local
Dentro de él, en la sección # ACTIONS, localizamos y configuramos los siguientes parámetros:
destemail = Dirección de email para recibir los avisos sender = pi@raspberrypi [email usado en ciertas acciones] mta = mail [Servidor de correo que usaremos] action = %(action_mw)s [Está al final de la sección]
En la primera línea hemos de escribir la dirección de email en la que deseamos recibir los avisos, mientras que en las demás pondremos únicamente lo que aparece en color rojo.
Hecho lo anterior, guardamos los cambios realizados en el fichero y reiniciamos el servicio:
sudo service fail2ban restart
Comprobamos su estado para asegurarnos de que todo funciona correctamente:
sudo systemctl status fail2ban
- 1.- Si el servicio está activado [Active: active (running)], es que todo ha ido bien.
- 2.- Si, por el contrario, aparece un mensaje de error, comprobamos que no hemos cometido níngún fallo al configurar los datos del correo que introdujimos
más arriba. Una vez hecha la comprobación, ejecutamos lo siguiente:
sudo service fail2ban stop
sudo service fail2ban start - Y observamos de nuevo que el servicio esté activado:
sudo systemctl status fail2ban
A partir de este momento, cada vez que haya un intento de acceso no autorizado y se bloquee la IP correspondiente, se nos enviará un aviso a la dirección de correo que hemos indicado, incluyendo información sobre la IP y el ISP desde los que se ha intentado acceder ilegalmente a nuestra máquina. Como medida de seguridad extra, también nos avisará (con un email por cada servicio que tengamos activado) cada vez que se detenga Fail2ban por algún motivo, incluyendo la desconexión o reinicio de la Raspberry.
Crear un túnel SSH
Si estamos fuera de casa, posiblemente tengamos la oportunidad de conectarnos a Internet a través de una red inalámbrica pública (de un hotel, bar, biblioteca,...) y navegar desde ella; pero hacerlo de esta forma tiene sus riesgos: alguien conectado a la misma red, y que esté usando un sniffer, podría, por ejemplo, obtener los nombres de usuario y las contraseñas que escribamos en el navegador si la web no usa el protocolo seguro HTTPS. Podríamos evitar esto y navegar de una forma segura si tuviéramos instalado un servidor VPN en nuestra Raspberry y nos conectáramos a él. Pero si no lo tenemos instalado, hay una alternativa sencilla que nos servirá para salir del paso: crear un túnel SSH y navegar de manera segura por él. La diferencia es que en el caso de la VPN, todo el tráfico entre el servidor y el cliente (lo que incluye cualquier servicio o aplicación que usemos) está cifrado, mientras que en la alternativa que vamos a explicar, sólo lo estará el tráfico que se genere en el navegador.
Vamos a realizar el proceso en dos pasos: primero configuramos el cliente SSH para crear el túnel y luego haremos los cambios oportunos en el navegador. Así pues, nos conectamos a la red inalámbrica pública. A continuación, si usamos Windows, arrancamos el cliente PuTTY y nos vamos a la categoría Connection - SSH - Tunnels. Ahí escribimos un puerto cualquiera (comprendido entre el 1025 y el 65535; por ejemplo, el 3590) en "Source port" y pinchamos en el botón "Add" para añadirlo. Luego en "Destination" marcamos "Auto" y "Dynamic". Nos debe de quedar así:
Despúes subimos hasta la categoría Session de PuTTY y en "Host Name" escribimos la IP pública de la RasPi (si tenemos IP fija) o un DNS dinámico (que podemos crear en No-ip, por ejemplo) para conectarnos con el servidor SSH remoto de nuestra Raspberry:
Hacemos clic en el botón "Open" y escribimos el nombre de usuario y contraseña para establecer la conexión SSH con la Raspberry Pi. Dejamos PuTTY abierto.
NOTA: Nos podemos ahorrar toda la anterior configuración del cliente si usamos la línea de comandos. En este caso tan sólo tendremos que escribir esto en una terminal:
ssh -D 3590 -p 22 pi@midominio.no-ip.org
cambiando, lógicamente, midominio.no-ip.org por el DDNS o la IP pública que tengamos.
El segundo paso es arrancar el navegador (Firefox en nuestro caso), nos vamos a Ajustes - General - Configuración de red, hacemos clic en "Configuración" y ahí definimos manualmente el Host SOCKS poniéndole la IP 127.0.0.1, el mismo puerto que abrimos antes para el túnel SSH (3590) y seleccionando "SOCKS v5" debajo. Debe de quedar así:
Pinchamos en "Aceptar" y ya podemos navegar con seguridad a través del túnel SSH que hemos creado. Pero antes debemos tener en cuenta un par de cosas:
- 1.) Naturalmente, es necesario que el puerto 22 esté abierto en el router y redirigido a la IP local de la RasPi para que la conexión con el servidor SSH funcione a través de Internet.
- 2.) Si por algún motivo la conexión SSH se desconectase, el navegador mostraría un error, de manera que nos daríamos cuenta enseguida de que el túnel ya no está funcionando.
DNS sobre HTTPS
DNS sobre HTTPS (DNS over HTTPS o, abreviado, DoH) es una forma de mejorar la seguridad y la privacidad de nuestras solicitudes de DNS utilizando el protocolo seguro HTTPS. Y es que, de forma predeterminada, una solicitud de DNS se envía en claro, es decir, sin cifrar, normalmente por el puerto 53 UDP. Esto significa que es posible interceptar esa petición y usarla para rastrearnos, impedir el acceso a un sitio web o incluso manipular los datos y reenviar dicha solicitud a otra web diferente y maliciosa (lo que se conoce como DNS hijacking).
Si configuramos DNS sobre HTTPS, las solicitudes que realicemos se harán de manera cifrada, a través del puerto 443 TCP, entre nosotros y el proveedor de DNS que usemos (en este caso, Cloudflare) y ni siquiera nuestro ISP sabrá los sitios a los que accedemos. El único que podrá ver nuestras peticiones será quien nos ofrezca el servicio de DNS; por eso es necesario recurrir a un proveedor de confianza. Pero recordemos que lo que estamos cifrando es la petición DNS en sí, no el tráfico web. Para esto último, las webs que visitemos deberán tener implementado también el protocolo HTTPS.
En los siguientes pasos mostraremos cómo instalar el demonio Cloudflared en la Raspberry Pi y prepararlo para enviar solicitudes DNS over HTTPS tanto desde la misma como a través de Pi-hole. Hay que tener en cuenta que, a pesar de haber sido desarrollado por Cloudflare, podemos usar el servicio Cloudflared para conectarnos a otros servidores de DNS sobre HTTPS, como Google o Quad9, por ejemplo.
Pasos previos
Lo primero que tenemos que hacer es instalar Pi-hole. Después continuaremos el proceso añadiendo un par de herramientas que vamos a necesitar (aunque, dependiendo de la versión del SO, es posible que ya estén instaladas):
sudo apt install curl lsb-release
Luego descargamos la clave GPG del repositorio oficial de Cloudflare (lo que sigue es una sola línea):
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg > /dev/null
A continuación añadimos dicho repositorio (como antes, lo que sigue también es una sola línea):
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
Por último, actualizamos la lista de paquetes:
sudo apt update
Instalación de Cloudflared
Hechos los pasos anteriores, ya podemos instalar Cloudflared:
sudo apt install cloudflared
Es necesario crear un usuario bajo el que correrá el demonio:
sudo useradd -s /usr/sbin/nologin -r -M cloudflared
Ahora crearemos el servicio de Cloudflared que funcionará como un proxy DoH. Para ello, en el fichero
sudo nano /etc/systemd/system/cloudflared.service
insertamos este contenido:
[Unit]
Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target
[Service]
Type=simple
User=cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query
Restart=on-failure
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
Aquí estamos usando los servidores DNS de Cloudflare (1.1.1.1, 1.0.0.1), pero podemos cambiar las IPs por las de otros proveedores que ofrezcan DoH (Google o Quad9, por ejemplo).
Si tenemos instalado el cortafuegos ufw, debemos abrir el puerto indicado:
sudo ufw allow 5053/tcp
sudo ufw allow 5053/udp
Activamos el servicio que hemos creado:
sudo systemctl enable cloudflared
A continuación lo arrancamos:
sudo systemctl start cloudflared
Y finalmente comprobamos que está en funcionamiento:
sudo systemctl status cloudflared
Comprobación en la RPi
Antes de configurar Pi-hole para usar DNS sobre HTTPS, veamos si funciona desde la propia Raspberry Pi. Para ello haremos una petición:
dig @127.0.0.1 -p 5053 google.com
Podemos comprobar que la resolución del nombre ha sido satisfactoria.
Configuración de Pi-hole
Una vez comprobado su funcionamiento en la Raspberry, accederemos a la interfaz web de administración de Pi-hole escribiendo la dirección IP local de la Raspberry en el navegador de cualquier dispositivo conectado a nuestra LAN:
192.168.1.33/admin
En el menú de la izquierda pinchamos en Settings, luego hacemos clic arriba, en la pestaña DNS, y comprobamos que, en el apartado Upstream DNS Servers izquierdo, todas las casillas de los servidores DNS estén desmarcadas. A continuación, en el derecho, en el subapartado Custom 1 (IPv4), marcamos la casilla de verificación y debajo escribimos lo siguiente:
127.0.0.1#5053
Debe quedar así:
No debemos olvidar guardar los cambios pulsando en el botón Save que se encuentra en la parte inferior derecha.
Comprobando el servicio
Si al realizar la configuración pusimos los servidores de Cloudflare, podemos comprobar que realmente estamos usando DNS sobre HTTPS (DoH) accediendo desde una máquina cualquiera de nuestra LAN a esta URL:
https://1.1.1.1/help
El resultado debería ser similar a este:
A partir de este momento todas las peticiones DNS estarán cifradas. Nadie, excepto Cloudflare, tendrá acceso al historial de navegación, y según ellos, lo eliminan en 24 horas. Ni siquiera nuestro proveedor de servicios de Internet (ISP) podrá saber el contenido que visitamos. Por eso, algunos países están haciendo lo posible para intentar acabar con este sistema de privacidad.