Saltar al contenido

SSH

El canal por el que se administra cualquier máquina que no está delante: qué se instala, qué se endurece en su configuración, cómo se entra sin escribir contraseñas, y cómo se copian ficheros y se abren túneles sobre esa misma conexión.

Qué se instala y dónde se configura

SSH tiene dos mitades y hay que tener claro cuál se está instalando. El servidor es el demonio que escucha y permite que otros entren; el cliente es el programa con el que se sale hacia fuera. En la familia Debian, un paquete instala solo el servidor y otro instala las dos mitades.

bash
apt install openssh-server   # solo el servidor
apt install ssh              # cliente y servidor

Esa división se repite en la configuración, y confundir los dos ficheros es un clásico. El del servidor lleva una d de demonio en el nombre; el del cliente no. Tocar el equivocado es la razón habitual de que un cambio no tenga ningún efecto.

FicheroA quién configura
/etc/ssh/sshd_configAl servidor: quién puede entrar y cómo
/etc/ssh/ssh_configAl cliente: cómo se conecta esta máquina hacia fuera

Endurecer un servidor SSH es un puñado de directivas, y son exactamente las que se preguntan porque son las que aparecen en cualquier guía de bastionado.

DirectivaQué controla
PortEl puerto de escucha. Por defecto el 22
ListenAddressPor qué dirección se escucha, si la máquina tiene varias
PermitRootLoginSi se permite entrar directamente como root
PasswordAuthenticationSi se admite contraseña o solo clave pública
AllowUsersLista blanca de cuentas que pueden conectarse
AllowGroupsLo mismo, por grupo en vez de por cuenta
ClientAliveIntervalSegundos de inactividad antes de cerrar la sesión
bash
# fragmento de /etc/ssh/sshd_config
Port 22
PermitRootLogin no
PasswordAuthentication no
AllowGroups administradores
ClientAliveInterval 300

Desactivar la entrada directa como root y la autenticación por contraseña son las dos medidas de mayor efecto: obligan a entrar con una cuenta nominal y con clave, que es lo que corta de raíz los ataques por fuerza bruta.

Para el examen

  • Fichero de configuración: sshd_config

  • Las dos medidas de mayor efecto: desactivar la entrada directa como root y la autenticación por contraseña

  • Qué se consigue: obligar a cuenta nominal y clave

Las claves y los cuatro ficheros de confianza

La seguridad de SSH descansa en criptografía de clave pública. Cada usuario genera un par: una clave privada, que no sale nunca de su máquina, y una pública, que se puede repartir sin riesgo. Quien tenga la pública puede comprobar que quien se conecta posee la privada, sin que la privada viaje jamás.

FicheroDónde viveQué contiene
~/.ssh/id_ed25519 o id_rsaEn el clienteLa clave privada del usuario
~/.ssh/id_ed25519.pub o id_rsa.pubEn el clienteLa clave pública correspondiente
~/.ssh/authorized_keysEn el servidorLas claves públicas admitidas para esa cuenta
~/.ssh/known_hostsEn el clienteLas huellas de los servidores ya visitados

Los dos últimos se confunden constantemente y la forma de recordarlos es preguntarse quién confía en quién. El fichero de claves autorizadas está en el servidor y dice en qué clientes confía. El de servidores conocidos está en el cliente y guarda la huella de cada servidor visitado, para avisar si algún día responde otra máquina en su lugar.

Aparte del par de cada usuario, el propio servidor tiene sus claves de máquina, en /etc/ssh, con un fichero por tipo de algoritmo. Su huella es lo que el cliente guarda como conocida, y de ahí sale el aviso de identificación cambiada cuando se reinstala un servidor y no se limpia la entrada antigua.

bash
ssh-keygen -t ed25519 -C "mrey en el portátil"
ssh-keygen -t rsa -b 4096
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub   # ver la huella

Sobre el tipo de clave conviene un aviso de vigencia: DSA está obsoleto y OpenSSH lo desactivó por defecto hace años, así que verlo en un enunciado como opción recomendada es una pista de respuesta incorrecta. Hoy se genera ed25519, o RSA de 3072 bits o más.

Copiar la clave pública al servidor tiene una orden dedicada que evita hacerlo a mano y con los permisos mal puestos. Es lo que convierte una conexión que pide contraseña en una que entra sola.

bash
ssh-copy-id mrey@srv-temario
ssh mrey@srv-temario         # ya no pide contraseña

authorized_keys está en el servidor y guarda claves públicas de clientes. known_hosts está en el cliente y guarda huellas de servidores. Si se intercambian en una respuesta, es la incorrecta.

Para el examen

  • authorized_keys: en el SERVIDOR: claves públicas admitidas

  • known_hosts: en el CLIENTE: huellas de los servidores

El agente de autenticación

Una clave privada debería estar protegida por una frase de paso, porque si no, quien copie el fichero entra en todos los servidores. El problema práctico es que entonces hay que teclear esa frase en cada conexión, y quien administra cincuenta máquinas acaba quitándola.

La solución es el agente de autenticación: un proceso que mantiene la clave descifrada en memoria durante la sesión. Se teclea la frase una vez, al añadir la clave, y a partir de ahí las conexiones no vuelven a pedirla.

bash
eval $(ssh-agent)          # arrancar el agente en esta sesión
ssh-add ~/.ssh/id_ed25519  # añadirle la clave, pidiendo la frase una vez
ssh-add -l                 # qué claves tiene cargadas
ssh-add -D                 # descargarlas todas

Hay una tercera herramienta de la familia, ssh-keyscan, que recopila las claves públicas de un conjunto de servidores. Se usa para rellenar el fichero de servidores conocidos de golpe cuando se despliegan muchas máquinas, en vez de aceptar la huella a mano una por una.

El agente guarda la clave descifrada en memoria, no la contraseña de la cuenta. Por eso sigue funcionando aunque el servidor tenga desactivada la autenticación por contraseña.

Para el examen

  • Qué guarda: la clave privada descifrada en memoria

  • Lo que NO guarda: la contraseña de la cuenta

  • Por eso: funciona aunque el servidor no admita autenticación por contraseña

Conectarse y ejecutar en remoto

El uso normal del cliente es abrir una sesión interactiva, pero hay una segunda forma que es la que convierte SSH en una herramienta de administración masiva: si detrás del destino se pone una orden, esta se ejecuta en la máquina remota, se devuelve su salida y la conexión se cierra. Sin sesión, sin terminal, apto para guiones.

bash
ssh mrey@srv-temario                       # sesión interactiva
ssh -l mrey srv-temario                    # la misma conexión, otra sintaxis
ssh mrey@srv-temario "df -h /srv"          # una orden y se cierra
ssh -p 2222 mrey@srv-temario               # puerto distinto del 22

Esa capacidad es la base de todo lo que viene después. Recorrer una lista de servidores ejecutando la misma orden en cada uno es lo que hace por dentro una herramienta como Ansible, y explica por qué esta no necesita instalar ningún agente.

Existe además el reenvío del agente, que sirve para saltar de un servidor a otro sin volver a autenticarse. Conviene entender bien qué reenvía: no manda la clave privada, que nunca sale de la máquina de origen, sino el canal hacia el agente, de modo que el servidor intermedio puede pedirle firmas.

bash
ssh -A mrey@salto
# desde ahí, la siguiente conexión usa el agente de la máquina de origen
ssh mrey@srv-interno

El reenvío del agente es cómodo y tiene coste: quien tenga privilegios en el servidor intermedio puede usar el agente reenviado mientras la sesión esté abierta. No se activa por costumbre, se activa cuando hace falta.

Para el examen

  • Reenvío del agente: cómodo, pero con coste

  • Su riesgo: quien tenga privilegios en el servidor intermedio puede usarlo mientras la sesión siga abierta

Túneles y copia de ficheros

Sobre una conexión SSH se puede transportar tráfico de otros servicios. La idea es abrir un puerto en un extremo de manera que todo lo que llegue a él salga por el otro extremo del túnel, cifrado por el camino. Es la forma de llegar a un servicio que no está publicado hacia fuera.

ModificadorTipo de túnelDónde se abre el puerto
-LLocalEn la máquina desde la que se lanza el cliente
-RRemotoEn la máquina servidor a la que se conecta

El túnel local es el habitual: se abre un puerto en el propio equipo y todo lo que se dirija a él sale por el servidor hacia el destino indicado. Sirve, por ejemplo, para abrir la consola de una base de datos que solo escucha en la red interna.

bash
# el puerto 15432 local sale hacia la base de datos interna
ssh -L 15432:bd-interna:5432 mrey@srv-salto

# el túnel inverso: abre un puerto en el servidor remoto
ssh -R 8080:localhost:3000 mrey@srv-salto

La copia de ficheros va sobre el mismo canal. scp usa la sintaxis de copia de siempre añadiendo el usuario y la máquina delante de la ruta, con dos puntos de separación. El sentido de la copia lo marca el orden: primero el origen y después el destino.

bash
scp mrey@srv-temario:/srv/contenido/temario.json ./copias/
scp -r ./contenido mrey@srv-temario:/srv/
scp -p informe.pdf mrey@srv-temario:/tmp/    # conserva fechas y atributos
scp -l 4096 grande.tar.gz mrey@srv-temario:/srv/   # limita el ancho de banda

Al lado de scp está sftp, que hace lo mismo pero de forma interactiva, con órdenes de sesión para moverse por los directorios, listar y transferir. Es más cómodo cuando no se sabe de antemano qué hay que traerse.

-L abre el puerto en el equipo local y -R en el remoto. La regla es que la letra indica dónde queda escuchando el puerto, no hacia dónde va el tráfico.

Para el examen

  • -L: abre el puerto en el equipo LOCAL

  • -R: abre el puerto en el REMOTO

  • Qué indica la letra: dónde queda escuchando, no hacia dónde va el tráfico