Capítulo 13 de 33 13 secciones 8 min

La llave para entrar a GitHub

Por qué tu contraseña no sirve y qué es eso de la llave SSH

<strong>GitHub dejó de aceptar contraseñas en 2021.</strong> Hoy hay dos formas de entrar: una llave SSH, que se genera con <code>ssh-keygen</code> y se pega una vez en la web, o un token, que es una contraseña larguísima con fecha de caducidad. La llave SSH es la que recomiendo: se configura en cinco minutos y no la vuelves a tocar. Y de los dos archivos que genera, el único que se copia a algún lado es el que termina en <code>.pub</code>.

Este capítulo existe porque es donde se atasca casi todo el mundo. Llegas con tu repositorio listo, escribes git push, GitHub te pide usuario y contraseña, se las das, y te contesta que no 😤

No estás haciendo nada mal. Es que GitHub dejó de aceptar contraseñas en agosto de 2021, y el mensaje de error no lo dice con esas palabras.

Una nota sobre este capítulo

En todo el libro los comandos se ejecutan antes de publicarse. Este es el único donde ssh-keygen no se ejecuta, por dos razones: no viene con Git (es de OpenSSH, otro programa) y generar llaves de verdad para meterlas en un libro sería justo lo que este capítulo te pide no hacer 🔐

Lo que sí se ejecuta aquí es todo lo del remoto, que es la otra mitad del problema y la que más gente tiene mal configurada.

El error que te trajo aquí

$ git push origin main
Username for 'https://github.com': tuusuario
Password for 'https://tuusuario@github.com':
remote: Support for password authentication was removed on August 13, 2021.
fatal: Authentication failed for 'https://github.com/tuusuario/ventas-miss-yera.git/'

Ese es el mensaje completo, y dentro está la explicación. Lo que falta es qué hacer 🔑

Las dos formas de entrar

Llave SSHToken
Se configuraUna vez y nunca másCada vez que caduca
CaducaNoSí, tú eliges cuándo
La dirección empieza porgit@github.com:https://github.com/
Dónde se guardaUn archivo en tu carpeta personalEn el gestor de claves del sistema
Cuándo la prefieroTu máquina de siempreUna máquina prestada o un servidor

Qué es una llave, en cristiano

Una llave SSH son dos archivos que nacen juntos y se necesitan:

  • La privada, que es tu llave de casa. Nunca sale de tu máquina, nunca se pega en ningún sitio, nunca se manda por WhatsApp.
  • La pública, que es la cerradura. Esa sí se reparte, y es la que pegas en GitHub.

Cualquiera con la cerradura puede comprobar que tu llave encaja, pero de la cerradura no se puede deducir la llave. Por eso la pública se puede publicar sin que pase nada 🔒

Generarla

Un solo comando. El -C del final es una etiqueta para que dentro de dos años sepas de qué máquina era:

$ ssh-keygen -t ed25519 -C "mi-laptop"

Generating public/private ed25519 key pair.
Enter file in which to save the key (~/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_ed25519
Your public key has been saved in ~/.ssh/id_ed25519.pub

Te pregunta dos cosas. Dónde guardarla: dale enter, el sitio por defecto está bien. Y una frase de seguridad: es opcional y sirve por si te roban la laptop.

Fíjate en las dos últimas líneas, porque ahí está todo el capítulo: dos archivos, el mismo nombre, y uno con .pub.

Cuál es cuál, sin abrir nada peligroso

Los dos archivos se distinguen por cómo empiezan, y eso se puede mirar sin enseñar nada. Vamos a hacer un par de archivos de mentira, escritos a mano, solo para practicar la comprobación:

mkdir practica-llaves
cd practica-llaves
printf 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI+ejemplo+de+mentira mi-laptop\n' > ejemplo.pub
printf -- '-----BEGIN OPENSSH PRIVATE KEY-----\nesto-no-es-una-llave-real\n-----END OPENSSH PRIVATE KEY-----\n' > ejemplo
ls
cut -c1-11 ejemplo.pub
head -1 ejemplo
ejemplo
ejemplo.pub
ssh-ed25519
-----BEGIN OPENSSH PRIVATE KEY-----

La pública empieza por ssh-ed25519 y cabe en una línea. La privada empieza por -----BEGIN y ocupa varias.

Si el archivo que abriste empieza por -----BEGIN, ciérralo. Ese no es el que se pega 🚫

Dónde se pega la pública

El contenido entero del archivo .pub, de ssh-ed25519 hasta la etiqueta del final, va en GitHub en Settings > SSH and GPG keys > New SSH key. Una vez. Para siempre 📌

cat ejemplo.pub
cut -d' ' -f3 ejemplo.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI+ejemplo+de+mentira mi-laptop
mi-laptop

Esa tercera palabra es la etiqueta que pusiste con -C. Con tres o cuatro máquinas es lo único que te dice cuál puedes borrar sin dejarte fuera a ti misma 🏷️

Cambiar la dirección de HTTPS a SSH

Aquí está la parte que más gente tiene mal. Si tu proyecto ya está conectado por https, la llave no sirve de nada hasta que le cambies la dirección al remoto. Y no hay que clonar de nuevo:

cd ..
mkdir ventas-miss-yera
cd ventas-miss-yera
git init -q
printf 'ciudad,monto\nLima,1200\nArequipa,890\n' > ventas.csv
git add ventas.csv
git commit -q -m "Primeras ventas de Lima y Arequipa"
git remote add origin https://github.com/tuusuario/ventas-miss-yera.git
git remote -v
origin	https://github.com/tuusuario/ventas-miss-yera.git (fetch)
origin	https://github.com/tuusuario/ventas-miss-yera.git (push)

Esa dirección con https:// va a pedir token cada vez. Se cambia con una línea:

git remote set-url origin git@github.com:tuusuario/ventas-miss-yera.git
git remote -v
git log --oneline
origin	https://github.com/tuusuario/ventas-miss-yera.git (fetch)
origin	https://github.com/tuusuario/ventas-miss-yera.git (push)
2a3fc36 Primeras ventas de Lima y Arequipa

El repositorio no se entera. Solo cambió la puerta por la que entra, y tu commit sigue exactamente donde estaba 🚪

El error de agregar dos veces el mismo remoto

git remote add origin git@github.com:tuusuario/otro-proyecto.git
error: remote origin already exists.

Git te frena porque add es para crear y ya existe. Cuando lo que quieres es cambiarlo, el comando es set-url 🔁

Comprobar que funciona

Cuando ya pegaste la pública en GitHub, este comando te lo confirma:

$ ssh -T git@github.com
Hi tuusuario! You've successfully authenticated, but GitHub does not provide shell access.

Dice "does not provide shell access" y suena a error. No lo es: significa "te reconozco, pero aquí no hay nada más que hacer". Es el mensaje de éxito 😄

La trampa

Sigues un tutorial para conectar tu máquina con GitHub, generas la llave y copias el archivo que te pide pegar en la página.

$ ls ~/.ssh
id_ed25519  id_ed25519.pub

$ cat ~/.ssh/id_ed25519       # y este es el que pegaste
-----BEGIN OPENSSH PRIVATE KEY-----
Qué está mal

Pegaste la llave privada, que es justo la que nunca sale de tu máquina 🔐

Son dos archivos con el mismo nombre y la diferencia es el .pub del final: ese es el que se pega, el otro se queda. La privada es literalmente la llave de tu casa y la pública es la cerradura, que puedes repartir sin miedo.

Si te pasó, no sirve de nada borrar el comentario donde la pegaste. Hay que generar un par nuevo y quitar el viejo de GitHub, igual que cambiarías la chapa de la puerta.

La regla para no equivocarse nunca: si el archivo no termina en .pub, no se copia a ningún lado.

Comprueba que se entendió

Comprueba que lo tienes

Un compañero te pide tu llave para que puedas entrar al repositorio del equipo. ¿Qué le mandas?

  • El archivo id_ed25519
  • El archivo id_ed25519.pub
  • Los dos, por si acaso
  • Mi contraseña de GitHub

Ejercicios

1. Distingue una llave de la otra

Con los dos archivos de práctica, comprueba cuál se puede enseñar mirando solo el principio.

cd ../practica-llaves
cut -c1-11 ejemplo.pub
head -1 ejemplo
echo "solo el .pub se copia"
ssh-ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
solo el .pub se copia

Una línea corta que empieza por ssh- contra un bloque que empieza por -----BEGIN.

2. Conecta un proyecto por HTTPS

Crea el repositorio de canales y apúntale la dirección web.

cd ..
mkdir canales-venta
cd canales-venta
git init -q
printf 'canal,monto\nBodegas,4200\n' > canales.csv
git add canales.csv
git commit -q -m "Ventas del canal bodegas"
git remote add origin https://github.com/tuusuario/canales-venta.git
git remote -v
origin	https://github.com/tuusuario/canales-venta.git (fetch)
origin	https://github.com/tuusuario/canales-venta.git (push)

Ese https:// del principio es el que va a pedir token.

3. Pásalo a llave

Cambia la dirección del remoto a la forma con SSH.

git remote set-url origin git@github.com:tuusuario/canales-venta.git
git remote -v
origin	https://github.com/tuusuario/canales-venta.git (fetch)
origin	https://github.com/tuusuario/canales-venta.git (push)

set-url es el comando entero. No hay que clonar de nuevo ni perder nada.

4. Comprueba que la historia no se movió

Mira que el commit sigue ahí después de cambiar la puerta.

git log --oneline
cat canales.csv
5d7b179 Ventas del canal bodegas
canal,monto
Bodegas,4200

La forma de autenticarse no toca el repositorio. Son cosas separadas 🧩

5. Intenta agregarlo otra vez

Prueba a usar add cuando el remoto ya existe.

git remote add origin git@github.com:tuusuario/otro.git
error: remote origin already exists.

Git no pisa una configuración que ya está. Para cambiarla, set-url 🛡️

6. Guarda un segundo destino

Un repositorio puede tener varios remotos con apodos distintos, útil cuando el mismo proyecto vive en dos sitios.

git remote add respaldo git@gitlab.com:tuusuario/canales-venta.git
git remote -v
origin	https://github.com/tuusuario/canales-venta.git (fetch)
origin	https://github.com/tuusuario/canales-venta.git (push)
respaldo	git@gitlab.com:tuusuario/canales-venta.git (fetch)
respaldo	git@gitlab.com:tuusuario/canales-venta.git (push)

Dos destinos, dos apodos. origin no tiene nada de especial más allá de la costumbre 🏷️

7. Quita el que no usas

Borra el remoto de respaldo y comprueba que el proyecto sigue igual.

git remote remove respaldo
git remote -v
git log --oneline
origin	https://github.com/tuusuario/canales-venta.git (fetch)
origin	https://github.com/tuusuario/canales-venta.git (push)
5d7b179 Ventas del canal bodegas

Los remotos son configuración, no historia. Se ponen y se quitan sin que pase nada 🧷

Lo que te llevas

Tu contraseña no entra, entra una llave. Y si tu remoto sigue apuntando a https://, la llave no se usa: cámbialo con set-url.

Practica este capítulo 📓

Todo el código de arriba en un cuaderno que corre de principio a fin, y los ejercicios con una celda vacía para que los hagas tú. Se abre en Google Colab y no hay que instalar nada.

¿Tienes alguna duda o consulta?