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 SSH | Token | |
|---|---|---|
| Se configura | Una vez y nunca más | Cada vez que caduca |
| Caduca | No | Sí, tú eliges cuándo |
| La dirección empieza por | git@github.com: | https://github.com/ |
| Dónde se guarda | Un archivo en tu carpeta personal | En el gestor de claves del sistema |
| Cuándo la prefiero | Tu máquina de siempre | Una 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.