openssh.jpg

Hoy toca hablar de OpenSSH, y es que la semana pasada se descubrió una vulnerabilidad grave que podría comprometer las claves privadas de los usuarios que se conectan a un servidor. Y como son claves privadas, nadie debería conocerlas, sólo nosotros. Así que, hoy es un buen día para compartir algunas medidas que podemos tomar para endurecer nuestros servidores y hacer nuestro SSH más seguro.

En el post, muchas veces hablaré de incluir cierta línea en los archivos de configuración, aunque normalmente, muchas distribuciones traen un archivo de configuración por defecto, en ese caso, debemos asegurarnos de que la línea está y que el valor es correcto (a veces tendremos que cambiar un yes por un no, o un número, etc).

No utilices passwords clásicos

Evita hacer la conexión a partir de contraseñas de toda la vida, esas cadenas de texto que tienen que aprenderse los usuarios para poder entrar en el servidor. Es muy recomendable utilizar pares de claves pública y privada (el servidor debe conocer las claves públicas de los usuarios que tienen acceso).

Como usuarios, en el ordenador cliente, debemos ejecutar:

$ ssh-keygen -b 4096

Esto nos creará dos archivos ~/.ssh/id_rsa y ~/.ssh/id_rsa.pub (podemos cambiar su nombre, el comando anterior nos preguntará si queremos almacenar las claves en otro archivo). El primer archivo será la clave privada y el segundo la clave pública. Podemos abrir los archivos con cualquier editor de texto sin problema, pero no modificarlos.

Seguidamente, dentro del servidor, debemos añadir el contenido del archivo id_rsa.pub al final del archivo ~/.ssh/authorized_keys
A partir de ahora, debemos tener el archivo id_rsa en nuestro ordenador siempre que queramos acceder a dicho servidor, este archivo será nuestra contraseña.

Puedes ver más información aquí.

Configuración del archivo de claves

Nuestro archivo de claves públicas (puede haber varias claves públicas para un mismo usuario, ya que puede que vayamos a acceder a él desde varios sistemas), por defecto está en ~/.ssh/authorized_keys
pero tal vez queramos especificar otro archivo, y puede que no esté en una ruta cómoda para el usuario. Podemos meterlo en /etc/ si lo deseamos, por ejemplo, o dentro de /var/. Podemos utilizar como palabras clave (%h que nos devuelve el $HOME del usuario y %u que nos devuelve el nombre de usuario) para formar la ruta de acceso al archivo de claves públicas autorizadas.
Para cambiarlo, debemos añadir a /etc/ssh/sshd_config lo siguiente:

AuthorizedKeysFile /var/claves/%u/authorized_keys

Si aún así prefieres seguir con passwords planos…

Vamos a configurar un poco mejor /etc/ssh/sshd_config y añadir unas cuantas cosas interesantes para passwords planos.
Es muy recomendable no permitir contraseñas vacías, para ello:

PermitEmptyPasswords no

Limitar el tiempo que le damos al usuario para enviarnos la contraseña (con un par de minutos sobra, aunque podemos limitarlo más):

LoginGraceTime 120

Limitar el número de contraseñas fallidas, así ralentizamos los ataques de fuerza bruta:

MaxAuthTries 3

Denegar acceso al usuario root

Es muy importante denegar el acceso al usuario root si nuestro servidor tiene conexión a Internet. Si es un ordenador de casa no es plan de ponernos paranoicos, siempre pueden entrar en nuestra wifi y ponerse a lanzar ataques a los equipos, pero no es tan probable.
Ya contaré la anécdota completa un día, pero un usuario malintencionado puede entrar, y de hecho entra, y se pone a probar contraseñas típicas.

Para ello, debemos entrar en /etc/ssh/sshd_config e incluir la línea:

PermitRootLogin no

Denegar autentificación por Password

Al principio hablamos de utilizar pares de claves pública y privada como contraseña, está bien, pero si el servidor sigue aceptando autentificación con password plano, podemos ser víctimas de un ataque y podrán probar contraseñas para intentar entrar.
Para ello en /etc/ssh/sshd_config debemos añadir:

PasswordAuthentication no

Separación de privilegios

Suele venir activada por defecto en instalaciones modernas. Se trata de que el proceso del OpenSSH crea una conexión con un proceso que no tiene permiso para hacer demasiado, sólo atender al tráfico entrante y abrir conexiones, pero cuando un usuario se identifica con éxito, se cambiará al usuario que acaba de entrar y funcionará de forma normal. Así es mucho más difícil que un ataque a OpenSSH durante el proceso de identificación pueda ser dañino si tiene éxito.
Para ello añadir en /etc/ssh/sshd_config:

UsePrivilegeSeparation no

Denegamos conexiones concurrentes sin autentificación

Puede que un atacante intente establecer varias conexiones a la vez en nuestro servidor para probar autentificaciones distintas, aunque podemos pararle los pies añadiendo lo siguiente a /etc/ssh/sshd_config:

MaxStartups 2

 

Así sólo podrá hacer dos conexiones a la vez. Podemos limitarlo más, pero a mí me gusta establecer varias conexiones a la vez para algunas tareas.

Cambiar el puerto

El puerto estándar del servicio SSH es el 22. Y por ello, es un puerto que se va a probar ante cualquier escaneo sencillo. Es común que algún usuario intente ver qué puertos tenemos abiertos, y muchas veces no se prueban todos los puertos posibles, sino los más típicos. Entonces, ¿por qué no dificultamos un poco encontrar este servicio? Podemos poner un puerto como el 222, o el 1234 o 5432. Para ello en /etc/ssh/sshd_config debemos añadir:

Port 5432

Limitar los dispositivos de escucha

En el caso en el que nuestro servidor tenga varios dispositivos de red (cable, inalámbrico, acceso telefónico, VPN, etc), podemos hacer que sólo sea posible la escucha desde uno o varios dispositivos. Por ejemplo, podemos hacer que sólo esté abierto el servicio SSH por VPN (suele ser el dispositivo tun0
), o por eth0 (muchos VPS suelen tener varios dispositivos de red). Para ello podemos añadir en /etc/ssh/sshd_config lo siguiente:

ListenAddress 192.168.1.6

Debemos incluir la dirección IP de nuestro servidor.

Expulsar a usuarios inactivos

No sabemos si los usuarios que se conectan al servidor están en su casa, o en un sitio público (o con acceso físico de otros usuarios), por otro lado, mantener usuarios inactivos es un gasto innecesario de recursos de nuestro servidor. Por lo que podemos expulsarlos cuando lleven 10 minutos (600 segundos) sin hacer nada añadiendo en /etc/ssh/sshd_config lo siguiente:

ClientAliveInterval 600
ClientAliveCountMax 0

Los servidores SSH enviarán señales para mantener vivos a los clientes (es decir, que no se desconecten), en este caso se enviará una señal cada ClientAliveInterval, y le estamos diciendo que el número de señales que enviaremos por cliente será 0, por lo que se desconectarán automáticamente.

Advertencia disuasoria

Podemos poner un mensaje antes de que un usuario se conecte, algo así como que los accesos no autorizados serán denunciados, que se está monitorizando la IP de los accesos o algo así. Intenta que el mensaje sea creíble y duro a la vez. Ese mensaje lo grabas en un archivo de texto, por ejemplo /etc/disuasorio y lo añadimos a /etc/ssh/sshd_config:

Banner /etc/disuasorio

Eso sí, no incluyas la versión de OpenSSH, ni el sistema operativo que usas, ni tu uptime, ni ninguna de esas cosas chulas que a los frikis nos hacen ilusión porque esa información puede ser utilizada en nuestra contra.

Usuarios y grupos permitidos

Podemos especificar qué usuarios vamos a permitir entrar en nuestro servidor, ya que puede que haya usuarios que no nos interesa que entren libremente, o un antiguo empleado cuyo usuario sigue siendo útil, pero no queremos que pueda entrar ya. Para ello, podemos utilizar en /etc/ssh/sshd_config:

AllowUsers alberto bruno carlos ernesto

o si es más fácil decir el grupo:

AllowGroups admins developers

Limitar conexiones entrantes al puerto de SSH

Puede que un usuario malintencionado nos quiera aplicar la fuerza bruta para averiguar nuestras claves. Para ello, intentará establecer automáticamente múltiples conexiones a nuestro servidor probando una clave distinta cada vez hasta que acierte. Podemos, con un pequeño script de iptables limitar las conexiones por minuto que se establecen al puerto 22 (o 5432 si lo hemos cambiado):

1
2
3
4
5
6
#!/bin/bash
IPTABLES=`which iptables` # Podemos reemplazarlo por la ruta y nombre del ejecutable de iptables
iface=eth1
port=22
$IPTABLES -I INPUT -p tcp --dport ${port} -i ${iface} -m state --state NEW -m recent  --set
$IPTABLES -I INPUT -p tcp --dport ${port} -i ${iface} -m state --state NEW -m recent  --update --seconds 60 --hitcount 5 -j DROP

O si preferimos usar ufw, podemos limitar a 6 conexiones cada 30 segundos simplemente utilizando:

# ufw limit ssh

o

# ufw limit 5432

Usar Latch en nuestro servidor

Latch es una aplicación que nos permite activar o desactivar nuestros credenciales en diferentes servicios. Funciona a través de una aplicación para móvil y podemos permitir o denegar nuestra autentificación en webs o servidores. Trae muchos plugins oficiales y posibilidad para crear plugins por parte de terceros.

En definitiva, es una forma de permitir que nos podamos identificar en nuestro servidor SSH o denegarlo. Podemos permitir la identificación cuando estemos delante de nuestro ordenador y denegarla cuando no, por ejemplo, o denegarla cuando sospechemos que alguien puede tener nuestra clave.

Para eso podemos encontrar guías aquí o aquí. Necesitamos tiempo paciencia y ganas.

Otras ideas interesantes

Hay muchas más cosas por hacer, por ejemplo, monitorizar el uso que se hace del servidor con auditd.

Otras técnicas interesantes son el port knocking, que es como llamar a una puerta con una cierta contraseña. Tú le dices a quien está dentro: “llamaré 3 veces rápidamente, luego una pausa y luego 2 veces lentamente”, mientras no escuches eso, no abras a nadie. Lo mismo puedes hacer en un servidor de Internet, originalmente tienes los puertos cerrados en un firewall, pero tras una secuencia de intentos de conexión a ciertos puertos, el firewall te da acceso al puerto que te interesa, y lo podemos hacer para las conexiones SSH. Podemos hacerlo con reglas de iptables o con knockd (que por detrás usará iptables, pero es mucho más amigable).

Incluso podemos hacer que un usuario determinado (a través de su clave pública) sólo sea capaz de ejecutar un comando. Normalmente se ejecuta el comando que le da acceso a shell, pero tal vez queremos restringir algo más el permiso de ejecución que le damos a un usuario. Para ello, en el archivo de authorized_keys podemos anteponer a cada clave ‘command=”comando”‘ y será el único comando que se ejecute en la sesión.

 

Fuente: poesiabinaria

¿Quién está en línea?

Hay 5419 invitados y ningún miembro en línea