Saltar al contenido
Security 2026-09-05 22 min de lectura

Cómo configurar llaves SSH y desactivar contraseñas

Las llaves SSH sustituyen una contraseña reutilizable por un par criptográfico: la llave privada permanece en tu computador y la pública se instala en el VPS. El servidor permite la entrada solo a quien demuestra que posee la privada.

Cómo configurar llaves SSH y desactivar contraseñas
#SSH#VPS#Linux#Seguridad
T
Equipo Terranode
Editorial

Generar una llave Ed25519

Ejecuta en Windows Terminal, macOS o Linux:

bash
ssh-keygen -t ed25519 -a 100 -C "administracion-terranode"

Acepta la ruta propuesta y protege la llave con una frase de paso. Se crearán un archivo privado y otro terminado en .pub. Nunca envíes el privado.

Copiar la llave al VPS

En macOS o Linux:

bash
ssh-copy-id usuario@IP_DEL_VPS

Si el comando no existe, muestra la pública con type $env:USERPROFILE\\.ssh\\id_ed25519.pub en PowerShell o cat ~/.ssh/id_ed25519.pub en Linux/macOS. Pega una sola línea en ~/.ssh/authorized_keys del usuario remoto.

Corrige los permisos:

bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Probar antes de cambiar SSH

Mantén abierta la sesión actual. Desde otra terminal ejecuta:

bash
ssh -i ~/.ssh/id_ed25519 usuario@IP_DEL_VPS

Comprueba además que sudo whoami devuelve root. Si falla, no continúes.

Desactivar contraseñas y root remoto

Crea /etc/ssh/sshd_config.d/99-keys-only.conf:

text
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no

Valida la sintaxis y recarga, sin reiniciar a ciegas:

bash
sudo sshd -t
sudo systemctl reload ssh

Abre una tercera conexión para confirmar. Si Ubuntu usa cloud-init, revisa que otro archivo de configuración no reintroduzca PasswordAuthentication; sshd -T muestra los valores efectivos.

Usar varias llaves con un archivo config

En ~/.ssh/config del computador puedes guardar alias:

text
Host terranode-produccion
  HostName 203.0.113.10
  User adminweb
  IdentityFile ~/.ssh/id_ed25519_terranode
  IdentitiesOnly yes

Luego basta ssh terranode-produccion. Usa una llave distinta por persona; no compartas archivos privados entre el equipo. Para revocar acceso, elimina únicamente la línea pública de esa persona.

Errores frecuentes

Permission denied (publickey) suele indicar usuario incorrecto, llave equivocada o permisos inseguros. Revisa ssh -v desde el cliente y journalctl -u ssh desde la consola del VPS. Si la llave privada se filtra, elimínala de authorized_keys y genera otra.

Las llaves son una capa del checklist de seguridad de Ubuntu, junto con firewall, parches, privilegios mínimos y backups. Los VPS de Terranode ofrecen consola web para recuperar acceso si una configuración SSH falla.

Cómo funciona la autenticación por llave

El servidor guarda una clave pública y el cliente demuestra que posee la privada correspondiente firmando un desafío. La privada no se copia al VPS ni viaja durante el inicio de sesión. Una frase de paso protege el archivo local si alguien roba el portátil, mientras que un agente puede mantenerla desbloqueada durante una sesión.

Cada persona y dispositivo debería tener una identidad propia. Compartir id_ed25519 por correo o mensajería elimina la trazabilidad: no puedes revocar a un técnico sin cambiar el acceso de todos y tampoco sabes quién usó la cuenta.

Identifica claramente las públicas con comentarios:

bash
ssh-keygen -lf ~/.ssh/id_ed25519.pub
cat ~/.ssh/id_ed25519.pub

El comentario al final de la línea no participa en la criptografía, pero ayuda a reconocer ana-portatil-2026 frente a una lista de claves indistinguibles.

Generar llaves en Windows, macOS y Linux

OpenSSH usa el mismo comando en los tres sistemas actuales, aunque la ruta del perfil cambia. En PowerShell:

bash
ssh-keygen -t ed25519 -a 100 -C "ana-portatil-2026" -f "$env:USERPROFILE\.ssh\id_ed25519_terranode"

En macOS o Linux:

bash
ssh-keygen -t ed25519 -a 100 -C "ana-portatil-2026" -f ~/.ssh/id_ed25519_terranode

El parámetro -a aumenta las rondas usadas para proteger el archivo cuando introduces una frase. No mejora una llave sin frase de paso. Escoge una frase larga y única; no uses la contraseña del VPS.

Lista los archivos sin mostrar la privada:

bash
ls -l ~/.ssh/id_ed25519_terranode*
ssh-keygen -lf ~/.ssh/id_ed25519_terranode.pub

En Windows PowerShell puedes usar:

bash
Get-ChildItem "$env:USERPROFILE\.ssh\id_ed25519_terranode*"
ssh-keygen -lf "$env:USERPROFILE\.ssh\id_ed25519_terranode.pub"

Nunca pegues en un ticket el archivo sin .pub. Una privada OpenSSH suele comenzar con una cabecera que indica que es una clave privada; si la compartiste, considérala comprometida aunque luego borres el mensaje.

Instalar la pública en la cuenta correcta

La llave autoriza una cuenta concreta del servidor, no todo el VPS de forma abstracta. Si la copias para deploy, no permitirá entrar como root ni como otro usuario.

Con acceso por contraseña temporal en macOS o Linux:

bash
ssh-copy-id -i ~/.ssh/id_ed25519_terranode.pub deploy@IP_DEL_VPS

En Windows, o cuando ssh-copy-id no está disponible, puedes canalizar solo la pública:

bash
Get-Content "$env:USERPROFILE\.ssh\id_ed25519_terranode.pub" | ssh deploy@IP_DEL_VPS "umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys"

Antes de ejecutar, abre la .pub y confirma que contiene una sola línea. En el servidor revisa propietario y modos:

bash
chown -R "$USER":"$USER" ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
namei -l ~/.ssh/authorized_keys

namei -l muestra permisos de cada directorio del camino. Un authorized_keys correcto puede ser rechazado si el directorio personal pertenece a otra cuenta o es escribible por usuarios no confiables.

Probar la identidad exacta antes de endurecer sshd

Fuerza la llave que quieres comprobar para no entrar por accidente con otra cargada en el agente. Usa modo verboso y IdentitiesOnly:

bash
ssh -vv -o IdentitiesOnly=yes \
  -i ~/.ssh/id_ed25519_terranode \
  deploy@IP_DEL_VPS

Busca en la salida que el cliente ofrece esa pública y que el servidor la acepta. Ya dentro, confirma identidad y privilegios:

bash
id
sudo -v
sudo whoami

Mantén la sesión original abierta. La prueba debe hacerse en otra ventana porque una conexión ya establecida no demuestra que las nuevas sesiones funcionen.

Si administras el VPS por un puerto no estándar, inclúyelo en la prueba. No cambies a la vez puerto, usuario, firewall y autenticación: si falla, no sabrás qué capa bloqueó la entrada.

Entender los archivos de configuración incluidos

Las distribuciones modernas pueden cargar fragmentos desde sshd_config.d, y otro archivo puede cambiar el valor que acabas de editar. Antes de modificar, consulta las directivas activas y las inclusiones:

bash
sudo grep -RniE '^(Include|PasswordAuthentication|KbdInteractiveAuthentication|PubkeyAuthentication|PermitRootLogin)' \
  /etc/ssh/sshd_config /etc/ssh/sshd_config.d
sudo sshd -T | grep -E 'passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin'

sshd -T muestra la configuración efectiva general. Las reglas Match pueden variar según usuario, grupo u origen; si las usas, consulta el resultado con contexto específico:

bash
sudo sshd -T -C user=deploy,host=vps,addr=198.51.100.20 \
  | grep -E 'passwordauthentication|pubkeyauthentication|permitrootlogin'

No edites un fragmento generado automáticamente sin saber quién lo recrea. En imágenes cloud, cloud-init puede establecer autenticación durante el aprovisionamiento. Crea un archivo administrado por ti con un nombre y orden claros, y verifica el resultado efectivo.

Desactivar contraseñas con una secuencia recuperable

La seguridad del cambio depende tanto del contenido como del orden. Haz una copia, escribe el fragmento y valida antes de recargar:

bash
sudo cp -a /etc/ssh/sshd_config.d/99-keys-only.conf \
  /etc/ssh/sshd_config.d/99-keys-only.conf.bak 2>/dev/null || true
sudo tee /etc/ssh/sshd_config.d/99-keys-only.conf > /dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
EOF
sudo sshd -t

Si sshd -t no devuelve salida y termina correctamente, recarga el nombre de servicio de tu distribución:

bash
sudo systemctl reload ssh
systemctl is-active ssh
sudo sshd -T | grep -E 'passwordauthentication|kbdinteractiveauthentication|permitrootlogin'

En algunas distribuciones el servicio se llama sshd. Confírmalo con systemctl status ssh sshd en vez de copiar el nombre a ciegas.

Abre una tercera terminal con la llave. Luego ejecuta una prueba negativa explícita que no use identidades:

bash
ssh -o PubkeyAuthentication=no \
  -o PreferredAuthentications=password,keyboard-interactive \
  deploy@IP_DEL_VPS

Debe rechazar el acceso sin ofrecer una vía útil por contraseña. Solo entonces cierra las sesiones anteriores.

No usar root como cuenta cotidiana

Bloquear PermitRootLogin obliga a identificar primero a una cuenta y eleva después con sudo. Crea un usuario administrativo con grupos mínimos y prueba sus permisos antes de cerrar root:

bash
sudo adduser deploy
sudo usermod -aG sudo deploy
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo install -m 600 -o deploy -g deploy \
  /home/USUARIO_ACTUAL/.ssh/authorized_keys \
  /home/deploy/.ssh/authorized_keys

Copiar todas las públicas puede ser adecuado durante una migración, pero después revisa cuáles necesita deploy. Para equipos, es mejor añadir la pública de cada persona individualmente y evitar una cuenta compartida. Si la aplicación no requiere shell interactivo, usa una cuenta de servicio separada sin sudo.

sudo no debe convertirse en una contraseña conocida por todos. Mantén cuentas individuales o una solución de acceso que registre identidades; así la baja de una persona no exige coordinar un cambio global.

Usar ssh-agent sin dejar la privada desprotegida

El agente guarda temporalmente una llave desbloqueada y evita escribir la frase en cada conexión. En macOS o Linux:

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_terranode
ssh-add -l

En Windows, el servicio OpenSSH Authentication Agent puede habilitarse según la política del equipo y luego recibir la llave con ssh-add. Un agente desbloqueado hereda el nivel de seguridad de tu sesión local: bloquea la pantalla, cifra el disco y elimina la llave cuando termines en equipos compartidos.

bash
ssh-add -d ~/.ssh/id_ed25519_terranode

No uses una llave sin frase solo para evitar el agente en un portátil personal. Las automatizaciones sí pueden requerir identidades no interactivas; limítalas desde authorized_keys y protege el sistema que las ejecuta.

Organizar varios servidores con ~/.ssh/config

Un alias evita equivocarte de usuario, puerto o llave y hace que scripts como scp usen la misma configuración. Un archivo de cliente puede contener:

text
Host tienda-produccion
  HostName 203.0.113.10
  User deploy
  Port 22
  IdentityFile ~/.ssh/id_ed25519_terranode
  IdentitiesOnly yes
  ServerAliveInterval 30

Host tienda-bastion
  HostName 10.20.0.15
  User deploy
  IdentityFile ~/.ssh/id_ed25519_terranode
  ProxyJump tienda-produccion

Protege el archivo porque revela nombres y topología, aunque no contiene necesariamente secretos:

bash
chmod 600 ~/.ssh/config
ssh -G tienda-produccion | grep -E 'hostname|user|port|identityfile'
ssh tienda-produccion

ssh -G muestra la configuración resuelta sin conectarse. Es útil cuando varias secciones Host * y alias aplican opciones distintas.

Restringir una llave de automatización

Una llave usada por un backup no necesita una shell general. En authorized_keys, las opciones se escriben antes de la pública y pueden forzar un comando o bloquear funciones:

text
restrict,command="/usr/local/sbin/recibir-backup" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... backup-origen

restrict desactiva varias capacidades como reenvíos y asignación de terminal. El comando forzado debe validar entradas y escribir solo en la ruta prevista. Prueba la automatización y confirma que una shell interactiva es rechazada.

No reutilices esa llave limitada para administración. Separar identidades por función permite rotar el backup sin tocar accesos humanos y reduce lo que un sistema comprometido puede hacer.

Revocar accesos y responder a una filtración

Eliminar la línea pública corta nuevas autenticaciones, pero no necesariamente una sesión ya abierta. Identifica el comentario o huella antes de editar:

bash
ssh-keygen -lf ~/.ssh/authorized_keys
cp -a ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak
nano ~/.ssh/authorized_keys

Después comprueba sesiones y registros:

bash
w
sudo journalctl -u ssh --since '24 hours ago'
sudo last -a | head -30

Si sospechas compromiso, revisa también sudo, tareas programadas, nuevas cuentas, otras llaves y credenciales de aplicaciones. Rotar SSH no revoca tokens copiados desde el servidor ni deshace persistencia añadida por un atacante.

Una llave perdida pero protegida con frase no debe ignorarse. Revócala, genera otra y actualiza su inventario; no puedes saber si la frase resistirá para siempre.

Diagnosticar Permission denied (publickey)

La salida verbosa del cliente y el registro del servidor muestran lados distintos del intercambio. Desde el cliente:

bash
ssh -vvv -o IdentitiesOnly=yes \
  -i ~/.ssh/id_ed25519_terranode \
  deploy@IP_DEL_VPS

Desde la consola del VPS:

bash
sudo journalctl -u ssh -f
sudo sshd -T | grep -E 'authorizedkeysfile|pubkeyauthentication'
Mensaje o síntomaQué revisar
El cliente no ofrece la llaveRuta, agente e IdentityFile
Ofrece la pública pero se rechazaCuenta, authorized_keys y huella
bad ownership or modesPropietario y permisos de todo el camino
Funciona para un usuario, no otroLa pública está en el home equivocado
Funciona por IP, falla con aliasOpciones de ~/.ssh/config
Tras recarga acepta contraseñaOtro fragmento o regla Match sobrescribe

No cambies permisos de todo /home ni uses chmod 777. Corrige el archivo o directorio concreto y vuelve a probar con la sesión de rescate abierta.

Combinar llaves con las demás capas

Las llaves eliminan la adivinación de contraseñas en SSH, pero no corrigen un servicio desactualizado ni una cuenta con sudo excesivo. Mantén parches, limita el firewall, registra accesos y conserva una consola fuera de banda. Fail2Ban puede reducir ruido, aunque con contraseñas realmente desactivadas los intentos no tienen una credencial reutilizable que adivinar.

Haz una revisión periódica de authorized_keys: cada línea debe tener propietario, dispositivo y necesidad vigente. Una llave de un proveedor que terminó el proyecto hace meses es una cuenta pendiente aunque nunca aparezca en /etc/passwd.

Verificar la clave del host y evitar conectarte al servidor equivocado

La llave del usuario demuestra quién eres; la llave del host demuestra a qué servidor te conectas. En la primera conexión, OpenSSH muestra una huella. Aceptarla sin comparar permite que un intermediario o una IP reutilizada se haga pasar por el VPS.

Obtén las huellas desde la consola del proveedor o una sesión confiable:

bash
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
sudo ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub

Compara con la que muestra el cliente. Si aparece REMOTE HOST IDENTIFICATION HAS CHANGED, no ejecutes ssh-keygen -R hasta confirmar si el servidor fue reinstalado, cambió de IP o existe un ataque. Revisa la entrada concreta:

bash
ssh-keygen -F IP_DEL_VPS
ssh-keyscan -t ed25519 IP_DEL_VPS

ssh-keyscan recupera una pública, pero no autentica por sí mismo que sea la correcta. Verifícala mediante un canal independiente y luego actualiza known_hosts.

En automatizaciones, no uses StrictHostKeyChecking=no como solución permanente. Precarga una huella validada o administra certificados de host; de otro modo la tarea cifra la conexión con cualquier máquina que responda.

Añadir segundo factor sin reactivar contraseñas SSH

Una llave puede combinarse con otro método, pero la configuración debe distinguir autenticación de cuenta y contraseña reutilizable. OpenSSH permite exigir varias credenciales con AuthenticationMethods. La elección del segundo factor depende de la distribución, PAM y tu capacidad de recuperación.

Antes de habilitarlo, prueba el módulo en una cuenta no crítica, conserva consola y excluye de forma consciente automatizaciones que no pueden responder. Un ejemplo conceptual puede exigir pública más teclado interactivo:

text
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

Esto no es una configuración completa: PAM debe proporcionar el segundo factor y no caer de nuevo en una contraseña ordinaria. Revisa valores efectivos, prueba una segunda sesión y documenta códigos de recuperación. Una mala combinación puede bloquear todas las cuentas incluso con llaves válidas.

Rotar llaves sin interrumpir el acceso

La rotación segura agrega la pública nueva, la prueba y solo después elimina la antigua. Genera otra identidad con comentario y fecha, añádela como una nueva línea y fuerza su uso:

bash
ssh -o IdentitiesOnly=yes \
  -i ~/.ssh/id_ed25519_terranode_2026 \
  deploy@IP_DEL_VPS

Dentro confirma usuario y sudo. Después elimina la línea vieja por su huella o comentario, abre otra sesión y verifica que la antigua es rechazada:

bash
ssh -o IdentitiesOnly=yes \
  -i ~/.ssh/id_ed25519_terranode_antigua \
  deploy@IP_DEL_VPS

No borres el archivo privado antiguo del equipo hasta completar la prueba de rechazo y verificar todos los servidores del inventario. Si la misma pública se instaló en diez VPS, la rotación no termina al actualizar uno.

Automatizar authorized_keys sin duplicar ni borrar accesos ajenos

La automatización debe agregar una pública de forma idempotente y preservar las demás identidades autorizadas. Antes de cambiar, valida que el texto recibido sea una única pública y crea copia.

bash
cp -a ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak
grep -qxF 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... ana-portatil-2026' \
  ~/.ssh/authorized_keys \
  || printf '%s\n' 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... ana-portatil-2026' \
  >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

No copies el ejemplo literal: usa la pública completa verificada. Herramientas de configuración como Ansible reducen diferencias entre servidores, pero también necesitan una identidad de emergencia y una revisión para no reemplazar el archivo completo con una lista incompleta.

Guarda el inventario de accesos fuera de los VPS. Así puedes responder qué servidores aún confían en una llave comprometida y demostrar la revocación.

Respaldar una llave privada sin multiplicar copias inseguras

Una llave personal puede respaldarse cifrada, pero cada copia aumenta la superficie de robo. En equipos con cifrado de disco y recuperación corporativa quizá sea preferible generar una nueva identidad tras pérdida en lugar de almacenar privadas en carpetas sincronizadas.

No guardes llaves en repositorios, notas compartidas ni el mismo VPS que protegen. Si tu política exige copia, usa un almacén cifrado con acceso individual y prueba que la frase de paso sigue siendo necesaria. Documenta revocación: restaurar una privada antigua que ya fue retirada de authorized_keys no debe reabrir acceso.

Para automatizaciones, respalda preferentemente el procedimiento y la pública autorizada; rota la privada desde el sistema que ejecuta el job. Así la recuperación no depende de repartir un secreto histórico entre operadores.

Evitar el reenvío indiscriminado del agente

ssh -A permite que un servidor intermedio solicite firmas a tu agente mientras la sesión está abierta. La privada no se copia, pero un host comprometido puede usar el agente reenviado para saltar a otros destinos accesibles. No actives ForwardAgent yes de forma global.

Para llegar a un servidor privado a través de un bastión, ProxyJump suele ser mejor: el cliente establece la conexión final y usa localmente la identidad correspondiente.

text
Host bastion
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519_bastion
  ForwardAgent no

Host base-privada
  HostName 10.20.0.15
  User admin-db
  ProxyJump bastion
  IdentityFile ~/.ssh/id_ed25519_db
  ForwardAgent no
bash
ssh -G base-privada | grep -E 'proxyjump|identityfile|forwardagent'
ssh base-privada

Usa llaves distintas si los niveles de riesgo o responsables cambian. Limita el bastión con firewall, parches y registros; no debería alojar aplicaciones públicas innecesarias. Si excepcionalmente necesitas agent forwarding, restríngelo al alias exacto y elimina las llaves del agente al finalizar.

Preparar la recuperación antes de bloquear el último método

La consola web debe probarse antes de necesitarla. Confirma que puedes abrirla, que conoces las credenciales del proveedor y que permite iniciar en modo rescate o editar el disco. Una consola inexistente descubierta después de cerrar contraseñas convierte un error pequeño en reinstalación.

Guarda fuera del VPS los pasos para montar el sistema y corregir authorized_keys o el fragmento de sshd. No copies allí las privadas de todos los administradores. La recuperación necesita acceso al proveedor y una pública nueva verificable.

Si el equipo depende de una sola persona para esa consola, la autenticación técnica no es el único punto de fallo. Define responsable alterno, protege su cuenta con segundo factor y registra quién puede autorizar una recuperación.

Genera Ed25519, protege la llave privada, instala la pública y prueba una sesión nueva. Solo entonces desactiva contraseñas y root remoto. Este orden convierte un cambio delicado en un procedimiento reversible.

¿Listo para llevar tu sitio al siguiente nivel?

Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.

Ver planes de hosting

Preguntas frecuentes