Hace tiempo que intento mejorar la seguridad de los accesos SSH a mis servidores virtuales, pues creo que la configuración por defecto basada en usuario (root) y contraseña, no es suficiente y el acceso queda expuesto a ataques por fuerza bruta o simples robos de contraseña.
Hasta ahora venía usando un doble factor de autenticación basado en Google Authenticator. Aunque el sistema es efectivo, proceso que ya expliqué hace un tiempo en este artículo, no me gusta la idea de depender de un servicio como Google Authenticator, o de que mi servidor mantenga el paquete google-authenticator en futuras versiones, así que me he pasado al método de acceso por SSH Keys. Un método muy seguro basado en el sistema llave pública – llave secreta, utilizado en infinidad de aplicaciones.
Crear las SSH Keys
Crearemos las SSH Keys en nuestra máquina local (yo uso GNU/Linux y lo voy a explicar en base a estos sistemas, si usas otro tipo de sistema operativo, busca información adicional sobre cómo generar SSH Keys) abriendo un terminal y ejecutando el siguiente comando:
ssh-keygen
Nos preguntará si deseamos darle un nombre (es conveniente usar un nombre que nos de una pista sobre dónde la vamos a usar), por ejemplo «keyservidorclientes«.
Si no indicamos ningún nombre, se asignará por defecto: id_rda.
La segunda pregunta nos ofrece crear una frase de contraseña para nuestra llave secreta. Es opcional, pero si alguien accede a nuestra máquina local, podría acceder automáticamente a nuestros servidores sin mayor problema. La frase de llave secreta añade un factor de seguridad más para estos casos.
Tras asignar el nombre y frase se crearán dos ficheros dentro de /home/user/.ssh/
- keyservidorclientes.pub
- keyservidorclientes
o si no le hemos asignado un nombre al momento de crearlas:
- id_rda.pub
- id_rda
El primer fichero con extensión .pub contiene nuestra llave pública y el fichero sin extensión, nuestra llave secreta.
Organizar nuestras SSH Keys
Si vamos a generar muchos SSH Keys para diferentes servidores, una buena práctica es guardar cada par de llaves en directorios diferentes, por ejemplo:
.ssh/servidordesarrollo/keyservidordesarrollo.pub
.ssh/servidordesarrollo/keyservidordesarrollo
.ssh/servidorclientes/keyservidorclientes.pub
.ssh/servidorclientes/keyservidorclientes
.ssh/servidorbackups/keyservidorbackups.pub
.ssh/servidorbackups/keyservidorbackups
Después creamos (si no existe) un fichero de configuración donde asociamos cada acceso con la ubicación de sus SSH Keys. Este fichero se llama config y debemos ubicarlo en el directorio principal /home/user/.ssh/
Dentro referenciamos cada servidor con la ubicación de sus SSH Keys:
Host servidordesarrollo
HostName IP o dominio del tu servidor
User root
IdentityFile ~/.ssh/servidordesarrollo/keyservidordesarrollo
Host servidorclientes
HostName IP o dominio de tu servidor
User root
IdentityFile ~/.ssh/servidorclientes/keyservidorclientes
Host servidorbackpus
HostName IP o dominio de tu servidor
User root
IdentityFile ~/.ssh/servidorbackups/keyservidorbackups
...
Ahora para conectar con nuestro servidor virtual de clientes solo tenemos que ejecutar:
ssh root@servidorclientes
Y para conectar con nuestro servidor de backups sería:
ssh root@servidorbackups
Copiar las llaves públicas en nuestros servidores virtuales
Una vez generadas las SSH Keys en nuestra máquina local, tenemos que añadir la llave pública al servidor virtual.
Existen herramientas dentro de OpenSSH, que permiten copiar fácilmente nuestra llave pública a nuestro servidor virtual. Pero básicamente lo que hacen es leer nuestro fichero .pub y copiar su contenido al fichero authorized_keys de nuestro servidor virtual. A mí me gusta hacer este proceso manualmente y asegurarme de que todo se ha llevado a cabo correctamente.
Para ello abrimos nuestra llave pública (fichero.pub) con un editor de textos (o desde terminal con cat fichero.pub) y copiamos su contenido.
Nos conectamos a nuestro servidor virtual por el método normal SSH por contraseña y editamos con nano (o tu editor preferido), el archivo /home/user/.ssh/authorized_keys añadiendo el contenido copiado de nuestra llave pública. (Si queremos añadir otra clave pública, podemos hacerlo a continuación, en una nueva línea. Cuidado con no soobreesribir otras claves que ha hubiera en el archivo).
A partir de ahora podremos conectar vía SSH con nuestra SSH Key, utilizando la frase de nuestra clave privada en vez de la contraseña de root de nuestro servidor.
Esto hace que solo podamos acceder vía SSH desde nuestra máquina local y si conocemos la frase de nuestra clave secreta.
Deshabilitar el acceso normal por contraseña
Ahora hay que deshabilitar el acceso normal por contraseña, pues lo que queremos es mejorar la seguridad, de forma que solo se pueda acceder al servidor con la SSH Key.
El archivo que tenemos que editar se encuentra en /etc/ssh/sshd_config, así que con nano o el editor de terminal que prefieras localizamos la línea:
#PasswordAuthentication yes
Descomentamos quitando # y cambiamos a PasswordAuthentication no
PasswordAuthentication no
Adicionalmente comprobamos que esta línea está descomentada y en yes:
PubkeyAuthentication yes
Y reiniciamos el servicio SSH, en servidores Debian/Ubuntu es:
sudo systemctl restart ssh
Antes de cerrar sesión, por precaución, abre un segundo terminal y asegúrate de que puedes iniciar sesión con tu SSH Key. En caso de que no puedas, revierte los cambios anteriores y vuelve a reiniciar el servicio SSH.
Si todo ha ido bien, al intentar iniciar sesión mediante contraseña normal, aparecerá el error permiso denegado.
Posibles problemas con proveedores VPS/Cloud tipo AWS, IONOS, DigitalOceans…
Si hemos seguido los pasos anteriores y aún así podemos acceder mediante contraseña normal, es posible que nuestro proveedor VPS añada configuraciones adicionales durante el arranque que prevalezcan sobre nuestros cambios.
Por ejemplo, los servidores IONOS utilizan cloud-init, que añade configuraciones personalizadas durante el arranque que pueden anular nuestras propias modificaciones.
Para solucionarlo, vamos hasta el directorio /etc/cloud/cloud.cfg.d/.
Examinamos si existen archivos de configuración (con extensión .cfg) por si en alguno de ellos estuviese habilitada la opción PasswordAuthentication yes. De ser así, lo modificamos a PasswordAuthentication no.
Reiniciamos el servicio sshd y probamos a conectar vía SSH por el método normal a ver si ahora obtenemos el permiso denegado.
Una vez comprobamos cual es el archivo que bloquea nuestra configuración, podemos configurarlo como archivo inmutable, pues en el próximo reinicio del servidor, seguramente se vuelva regenerar con la configuración por defecto.
Para ello aplicamos chattr +i sobre el archivo de configuración en cuestión:
sudo chattr +i /etc/ssh/sshd_config.d/archivo.conf
Esto hace al archivo inmutable incluso para root.
Si tras reiniciar el servidor aún vuelve a habilitarse el acceso SSH por contraseña normal, podríamos como último recurso deshabilitar completamente el cloud-init.
sudo touch /etc/cloud/cloud-init.disabled
Y reniciar el servidor.
Aviso: Procede con precaución con esta opción, pues deshabilitar cloud-init, podría romper configuraciones importantes de tu proveedor VPS que provoquen errores futuros en el servidor.
Y hasta aquí el tutorial. Espero que como a mí, te sirva de mucha utilidad y securices al máximo tus VPS. Nos vemos en el siguiente post 😉
Deja una respuesta