L'Ana ja té el seu remot registrat. Escriu git push origin main amb tota la il·lusió i obté això:
Un indicatiu esperant alguna cosa que no sap gaire bé què és. I si teclegés la contrasenya amb què entra a la interfície web, és molt probable que rebés un rebuig del tipus Support for password authentication was removed.
Aquest mur atura molta gent en el seu primer contacte amb un repositori remot, i és una llàstima, perquè el problema no té res a veure amb Git: és un problema d'identitat. Registrar un URL no dona permís per escriure-hi. Algú ha de demostrar al servidor que és qui diu ser.
Aquesta lliçó resol aquest mur d'una vegada i per sempre. Veurem per què el clone d'un repositori públic no demana res i el push sí, els dos mecanismes d'autenticació que es fan servir avui —testimonis sobre HTTPS i claus SSH—, com generar una clau amb ssh-keygen, i com fer que el sistema operatiu recordi les credencials per no haver-les de teclejar quaranta vegades al dia. És la lliçó que la Carla necessita abans d'escriure la seva primera línia, perquè entra des de Windows 11 i allà el gestor de credencials funciona d'una manera diferent.
Contingut
- Per què el
clonepúblic no demana res i elpushsí - Autenticació davant d'autorització
- HTTPS amb testimoni personal d'accés
- SSH: el parell de claus
- Generar la clau amb
ssh-keygen -t ed25519 - Pujar la pública, provar la connexió i fer servir l'agent
~/.ssh/config: diverses identitats a la mateixa màquina- HTTPS davant de SSH: taula comparativa
- Gestors de credencials per sistema operatiu
- Errors típics i com diagnosticar-los
- Per què el
clone públic no demana res i el push sí
clone públic no demana res i el push síLa resposta és senzilla i aclareix molta confusió: són operacions amb requisits de permís diferents.
| Operació | Què fa | Repositori públic | Repositori privat |
|---|---|---|---|
git clone, git fetch, git pull |
Llegir objectes i referències | Sense credencials | Credencials |
git push |
Escriure: modificar referències del servidor | Credencials sempre | Credencials |
Un repositori públic és, per definició, llegible per qualsevol. Descarregar el codi d'un projecte obert no requereix identificar-se, igual que llegir una pàgina web no requereix compte.
Escriure és una altra història. Quan envies, li estàs demanant al servidor que modifiqui les seves referències: que refs/heads/main passi a apuntar a un altre commit. Això canvia el que tothom veurà en clonar a partir d'aquell moment. Cap servidor assenyat no permet això a un desconegut.
I hi ha un matís que sorprèn molta gent: la identitat de Git i la identitat del servidor són coses diferents.
Ana Ferrer [email protected]
Això que vas configurar a la lliçó 01-06 és metadada del commit: text que es grava dins de l'objecte i que apareix a git log. No autentica res. Qualsevol pot posar qualsevol nom i qualsevol correu als seus commits; Git no ho verifica.
L'autenticació passa en una altra capa: al transport, quan el teu Git parla amb el servidor. Són dues identitats independents que convé no barrejar:
user.name / user.email |
Credencials d'accés | |
|---|---|---|
| On viu | A la configuració de Git | Al gestor de credencials o a ~/.ssh/ |
| Per a què serveix | Signar l'autoria del commit | Demostrar qui ets davant del servidor |
| Ho verifica algú | No | Sí, el servidor, a cada connexió |
| Quan intervé | En fer git commit |
En fer fetch, pull o push |
(Existeix una manera de vincular totes dues coses de debò, signant els commits criptogràficament. És un tema de seguretat i es tracta a la lliçó 08-05.)
- Autenticació davant d'autorització
Dues paraules que es confonen cada dia i que produeixen errors molt diferents:
- Autenticació: qui ets. Demostrar la teva identitat davant del servidor.
- Autorització: què pots fer. Els permisos que aquesta identitat té sobre aquell repositori concret.
Pots estar perfectament autenticat i tot i així rebre un rebuig:
remote: Permission to equip/gestor-tasques.git denied to carla. fatal: unable to access 'https://git.exemple.cat/equip/gestor-tasques.git/': The requested URL returned error: 403
Fixa't en el missatge: el servidor sap que ets la Carla. L'autenticació ha funcionat. El que falla és l'autorització: a la Carla no li han donat permís d'escriptura en aquell repositori, o el seu testimoni no té l'àmbit necessari.
Distingir els dos casos estalvia molt de temps:
| Símptoma | Capa que falla | Què revisar |
|---|---|---|
Permission denied (publickey) |
Autenticació (SSH) | La clau: si existeix, si està carregada, si està pujada al servidor |
Authentication failed (HTTPS) |
Autenticació | El testimoni: si és vàlid, si ha caducat, si està ben desat |
403 Forbidden, Permission to … denied to <usuari> |
Autorització | Els permisos del teu compte al repositori; els àmbits del testimoni |
Repository not found |
Totes dues, ambiguament | Moltes plataformes retornen això per a repositoris privats als quals no tens accés, per no revelar que existeixen |
Aquest darrer cas és especialment traïdor: Repository not found no significa necessàriament que hagis escrit malament l'URL. Pot voler dir «existeix, però per a tu no».
- HTTPS amb testimoni personal d'accés
Què és un PAT i per què va substituir la contrasenya
Un testimoni personal d'accés (Personal Access Token, PAT) és una cadena llarga generada per la plataforma que funciona com una contrasenya per a un ús concret. Té un aspecte semblant a aquest (fictici, evidentment):
Durant anys, l'autenticació per HTTPS es feia amb l'usuari i la contrasenya del compte. GitHub va retirar aquesta possibilitat l'agost de 2021 i la resta de plataformes va seguir el mateix camí. Les raons són sòlides:
- Àmbit limitat. La teva contrasenya obre tot el compte: repositoris, ajustos, facturació, esborrat. Un testimoni pot donar només lectura d'un repositori concret.
- Revocable individualment. Si un testimoni es filtra, l'elimines i només es trenca el que el feia servir. Canviar la contrasenya t'obliga a reconfigurar-ho tot.
- Compatible amb doble factor. Si el teu compte té segon factor, no hi ha manera d'introduir-lo en un indicatiu de Git. El testimoni resol aquest carreró sense sortida.
- Caducitat. Un testimoni pot expirar en 30, 60 o 90 dies; una contrasenya viu fins que algú se'n recorda de canviar-la.
- Auditable. La plataforma registra quin testimoni ha fet què i quan es va fer servir per darrera vegada.
Com es crea i amb quins àmbits
El procediment concret varia per plataforma, però l'esquema és sempre el mateix: ajustos del compte → testimonis d'accés → crear → triar nom, caducitat i àmbits.
Els àmbits són la part important. Concedeix el mínim imprescindible:
| Necessitat | Àmbit típic | Què permet |
|---|---|---|
Clonar i fer fetch de repositoris privats |
read_repository / repo:read |
Només lectura |
Fer push |
write_repository / repo |
Lectura i escriptura de codi |
| Només un repositori concret | Testimoni amb àmbit de projecte | Accés acotat a aquell repositori |
| Integració contínua | El mínim que necessiti la tasca | Vegeu el mòdul 7 |
El que gairebé mai no necessites: àmbits d'administració, de gestió d'usuaris, d'esborrat de repositoris o d'accés als ajustos de l'organització. Un testimoni de desplegament que només ha de clonar no hauria de poder esborrar res.
Un consell operatiu: crea un testimoni per màquina, no un que comparteixis entre el teu portàtil, l'ordinador de casa i el servidor d'integració contínua. Si perds el portàtil, revoques aquell testimoni i la resta continua funcionant.
Com es fa servir
El testimoni s'introdueix al lloc de la contrasenya:
Username for 'https://git.exemple.cat': ana.ferrer Password for 'https://[email protected]':
En aquest segon indicatiu hi va el testimoni, no la contrasenya del compte. Com que no es veu mentre s'escriu, és còmode enganxar-lo des del porta-retalls.
El que no has de fer mai és incrustar-lo a l'URL:
# MALAMENT: no facis això
git remote add origin https://ana:[email protected]/equip/gestor-tasques.gitAquest testimoni acaba escrit en text pla a .git/config, apareix a l'historial del teu shell, es cola en captures de pantalla i surt en qualsevol git remote -v que executis davant d'algú. Per a això existeixen els gestors de credencials de l'apartat 9.
- SSH: el parell de claus
L'alternativa a HTTPS és SSH, i es basa en un concepte diferent: en lloc d'un secret compartit, es fa servir un parell de claus asimètriques.
- La clau privada (
~/.ssh/id_ed25519) es queda a la teva màquina i no en surt mai. És l'equivalent a la teva clau física. - La clau pública (
~/.ssh/id_ed25519.pub) es puja al servidor. És l'equivalent al pany: es pot repartir sense risc.
La propietat matemàtica que ho fa funcionar és que el que es verifica amb la pública només ho ha pogut produir la privada, i la privada no es pot deduir de la pública.
sequenceDiagram
participant C as Portàtil de la Carla
participant S as git.exemple.cat
C->>S: Vull connectar-me com a usuari "git"
S->>C: Repte: signa aquesta dada aleatòria
Note over C: Signa amb la clau PRIVADA<br/>(que no surt mai del disc)
C->>S: Aquí tens la signatura
Note over S: Verifica amb la clau PÚBLICA<br/>que la Carla va pujar abans
S->>C: Verificada. Accés concedit
L'avantatge sobre el testimoni és evident: el secret no viatja mai per la xarxa. Ni tan sols xifrat. L'única cosa que es transmet és una signatura d'una dada aleatòria diferent a cada connexió, inútil per a un atacant que la capturi.
Els tipus de clau
| Tipus | Estat | Comentari |
|---|---|---|
| Ed25519 | Recomanat | Modern, ràpid, claus curtes (68 caràcters), seguretat excel·lent |
| RSA 4096 | Acceptable | Segur, però claus llargues i més lent; útil en sistemes antics que no admeten Ed25519 |
| RSA 2048 | Desaconsellat | Ja no es considera suficient |
| ECDSA | Desaconsellat | Dubtes sobre les corbes estàndard; Ed25519 el supera en tot |
| DSA | Prohibit | Obsolet i eliminat d'OpenSSH |
Fes servir Ed25519 llevat que et trobis amb un servidor antic que el rebutgi, cas en què rsa amb 4096 bits.
- Generar la clau amb
ssh-keygen -t ed25519
ssh-keygen -t ed25519La Carla, des del seu Windows 11, obre el Git Bash (que va instal·lar a la lliçó 01-02 i que porta totes les eines d'OpenSSH). Les ordres són idèntiques a Linux, macOS i Git Bash:
ssh-keygen -t ed25519 -C "[email protected]"Desglossament de les opcions:
-t ed25519: el tipus de clau. És l'argument important.-C "…": un comentari que s'afegeix al final de la clau pública. Serveix per identificar-la a la llista del servidor quan tinguis quatre claus de quatre màquines. Pot ser el correu, però encara és millor una cosa com ara"carla-portatil-windows", perquè el que vols saber és de quina màquina és aquella clau.
El diàleg:
Generating public/private ed25519 key pair. Enter file in which to save the key (/c/Users/carla/.ssh/id_ed25519):
Prem Retorn per acceptar la ruta per defecte. Canvia-la només si tindràs diverses claus, cas que veurem a l'apartat 7.
Aquí cal aturar-se. La passphrase xifra la clau privada al disc. Si algú et roba el portàtil o copia el fitxer, sense ella la clau no serveix de res.
| Amb passphrase | Sense passphrase | |
|---|---|---|
| Seguretat si et roben el fitxer | La clau és inútil sense la frase | Accés immediat als teus repositoris |
| Comoditat diària | Es teclega una vegada per sessió (amb ssh-agent) |
No es teclegen mai |
| Ús en automatització sense supervisió | Complicat | És l'habitual, amb la clau molt restringida |
| Recomanació | Posa-la sempre en màquines personals | Només en claus de desplegament de només lectura |
Posa-la. Amb ssh-agent, el cost real és teclejar-la una vegada en engegar l'ordinador.
El resultat:
Your identification has been saved in /c/Users/carla/.ssh/id_ed25519 Your public key has been saved in /c/Users/carla/.ssh/id_ed25519.pub The key fingerprint is: SHA256:9xK2mQ7RtVb3Ln8ZwYcF4dJ6hP1sT5uA2eB9gN0kM3o [email protected]
Dos fitxers. Vegem què contenen:
-rw------- 1 carla carla 464 ago 1 09:12 id_ed25519 -rw-r--r-- 1 carla carla 103 ago 1 09:12 id_ed25519.pub
Fixa't en els permisos, que són part del mecanisme de seguretat:
- La privada és
-rw-------(600): només tu la pots llegir. Si tingués permisos més oberts, OpenSSH es negaria a fer-la servir. - La pública és
-rw-r--r--(644): llegible per qualsevol, i no passa res.
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK7Rt2mQx9VbLn8ZwYcF4dJ6hP1sT5uA2eB9gN0kM3o [email protected]
Tres parts: el tipus, la clau pròpiament dita i el comentari. Aquesta línia és la que es puja al servidor, i es pot publicar sense cap risc.
I la privada, amb l'advertiment obvi:
-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDl...
Aquest contingut no s'ensenya, no es copia i no s'envia a ningú. Mai. Ni a un company, ni a suport tècnic, ni enganxat en un xat. Si algun cop tens el dubte de quin dels dos fitxers cal pujar, la regla és infal·lible: el que acaba en .pub.
- Pujar la pública, provar la connexió i fer servir l'agent
Pujar la clau pública
Es copia el contingut del .pub i s'enganxa a la plataforma (ajustos del compte → claus SSH → clau nova). Per copiar-lo al porta-retalls:
# Linux (amb xclip instal·lat)
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# macOS
pbcopy < ~/.ssh/id_ed25519.pub
# Windows amb Git Bash
clip < ~/.ssh/id_ed25519.pubUn avís freqüent: en enganxar, no hi ha de quedar cap salt de línia al mig. La clau és una sola línia llarga; si l'editor la parteix, no funcionarà.
Provar la connexió amb ssh -T
Abans d'intentar cap ordre de Git, comprova que el canal funciona:
ssh -T [email protected]L'opció -T significa «no vull terminal interactiu»: només estic comprovant l'autenticació.
La primera vegada apareix això:
The authenticity of host 'git.exemple.cat (192.0.2.42)' can't be established. ED25519 key fingerprint is SHA256:p2Q9xL4mR7tVc3Nb8ZwYeF6dJ1sK5uA0eB7gN2kM9o. Are you sure you want to continue connecting (yes/no/[fingerprint])?
No responguis yes per inèrcia. Aquest missatge diu que el teu ordinador encara no coneix aquell servidor i et demana que confirmis que és l'autèntic. Les plataformes publiquen les seves empremtes a la documentació; compara-la abans d'acceptar. És l'única defensa contra un atac d'intermediari en aquella primera connexió.
En acceptar, l'empremta es desa a ~/.ssh/known_hosts i no ho tornarà a preguntar.
Si tot va bé:
Aquest missatge és un èxit complet, encara que digui que no dona accés al shell. Això és exactament el que ha de passar: l'usuari git d'un servidor de repositoris no serveix per obrir una sessió, només per parlar Git.
ssh-agent: teclejar la passphrase una sola vegada
Amb passphrase, cada operació demanaria la frase. L'agent la desa a la memòria durant la sessió i respon per tu.
Enter passphrase for /home/carla/.ssh/id_ed25519: Identity added: /home/carla/.ssh/id_ed25519 ([email protected])
256 SHA256:9xK2mQ7RtVb3Ln8ZwYcF4dJ6hP1sT5uA2eB9gN0kM3o [email protected] (ED25519)
A partir d'aquí, tots els push i pull funcionen sense teclejar res.
Cada sistema té la seva manera de deixar-ho automatitzat:
# Linux: afegir al final de ~/.bashrc o ~/.zshrc
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi# macOS: desa la passphrase al Clauer i la carrega sola
ssh-add --apple-use-keychain ~/.ssh/id_ed25519# macOS: i perquè es carregui a cada sessió, a ~/.ssh/config
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519A Windows 11, el servei ssh-agent ve amb el sistema però arrenca desactivat. Des del PowerShell com a administrador:
I després, ja des del Git Bash:
Un detall per a la Carla: si fa servir l'ssh del Git Bash i l'agent del sistema, poden no veure's entre ells. La solució senzilla és fer servir el bloc de ~/.bashrc de més amunt, que engega un agent propi del Git Bash.
~/.ssh/config: diverses identitats a la mateixa màquina
~/.ssh/config: diverses identitats a la mateixa màquinaSituació molt real, i precisament la de la Carla: a la lliçó 01-05 vam veure que treballa en dos contextos, el d'exemple.cat i el d'una altra empresa, amb correus diferents. Si a més cadascun exigeix un compte i una clau diferents, cal dir-li a SSH quina fer servir en cada cas.
Això es resol a ~/.ssh/config:
# Compte de la feina
Host git.exemple.cat
HostName git.exemple.cat
User git
IdentityFile ~/.ssh/id_ed25519_feina
IdentitiesOnly yes
AddKeysToAgent yes
# Compte de l'altra empresa: àlies inventat
Host git-altraempresa
HostName git.altraempresa.cat
User git
IdentityFile ~/.ssh/id_ed25519_altraempresa
IdentitiesOnly yes
AddKeysToAgent yesExplicació de cada directiva:
| Directiva | Què fa |
|---|---|
Host |
L'àlies que escrius a l'URL. Pot ser inventat |
HostName |
El servidor real al qual connectar-se |
User |
L'usuari SSH: a les plataformes de Git és gairebé sempre git |
IdentityFile |
Quina clau privada fer servir per a aquesta destinació |
IdentitiesOnly yes |
Fes servir només aquesta clau, no totes les que tinguis carregades |
AddKeysToAgent yes |
Carrega la clau a l'agent al primer ús |
IdentitiesOnly yes mereix un comentari, perquè evita una errada desconcertant. Sense ell, SSH ofereix totes les teves claus una rere l'altra fins que alguna funcioni; si en tens cinc, el servidor pot tallar la connexió per excés d'intents i obtindràs un Too many authentication failures que no sembla tenir res a veure amb la causa real.
El truc de l'àlies inventat és el que fa potent aquest fitxer. Fixa't en Host git-altraempresa: aquest nom no existeix a cap DNS. Però ara la Carla pot escriure:
I SSH tradueix git-altraempresa a git.altraempresa.cat amb la clau correcta. El mateix mecanisme serveix per a dos comptes a la mateixa plataforma, que és el cas clàssic de tenir un compte personal i un altre d'empresa al mateix GitHub:
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
Host github-empresa
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_empresa
IdentitiesOnly yes# Repositori personal
git clone git@github-personal:carla/el-meu-blog.git
# Repositori de l'empresa
git clone git@github-empresa:exemple-sl/gestor-tasques.gitMateix servidor real, dues identitats, sense cap ambigüitat.
I per comprovar quina clau es farà servir realment:
ssh -T -v [email protected] 2>&1 | grep -i "offering\|identity file"debug1: identity file /home/carla/.ssh/id_ed25519_feina type 3 debug1: Offering public key: /home/carla/.ssh/id_ed25519_feina ED25519
L'opció -v (verbose) és l'eina de diagnòstic definitiva per a qualsevol problema d'SSH.
Permisos del fitxer, que també són estrictes:
- HTTPS davant de SSH: taula comparativa
Les dues opcions són vàlides i totes dues es fan servir massivament. L'elecció depèn del context:
| Criteri | HTTPS + testimoni | SSH |
|---|---|---|
| Facilitat inicial | Alta: enganxar un testimoni i llestos | Mitjana: generar clau, pujar-la, provar |
| Tallafocs corporatius | Excel·lent: fa servir el port 443, obert a tot arreu | Problemàtica: el port 22 sol estar tancat |
| Ús diari | Transparent amb gestor de credencials | Transparent amb ssh-agent |
| El secret viatja per la xarxa | Sí (dins del xifratge TLS) | No, mai |
| Caducitat | Sí: cal renovar el testimoni cada 30-90 dies | No caduca |
| Granularitat de permisos | Alta: àmbits per testimoni | Baixa: la clau dona el que dona el teu compte |
| Diverses identitats | Complicat: el gestor en desa una per servidor | Senzill amb ~/.ssh/config |
| Automatització i CI | Preferit: testimonis amb àmbit mínim i caducitat | Possible amb claus de desplegament |
| Revocació | Immediata des del web | Immediata esborrant la clau |
| Repositoris públics de només lectura | Ideal: sense credencials | Innecessari |
| Darrere d'un proxy | Es configura fàcilment a Git | Requereix configuració addicional d'SSH |
Recomanació pràctica
- Màquina de treball diari, mateix compte sempre → SSH. Es configura una vegada i s'oblida: no caduca, no es renova i no interromp.
- Xarxa corporativa amb el port 22 tancat → HTTPS + testimoni. (Algunes plataformes ofereixen SSH pel port 443 com a alternativa.)
- Integració contínua, contenidors, servidors → Testimoni amb l'àmbit mínim i caducitat curta, o una clau de desplegament de només lectura.
- Clonar un projecte públic per llegir-lo → HTTPS sense credencials.
- Diversos comptes a la mateixa màquina → SSH amb
~/.ssh/config.
I una dada tranquil·litzadora: canviar d'una a l'altra és un set-url, com vam veure a la lliçó anterior:
# D'HTTPS a SSH
git remote set-url origin [email protected]:equip/gestor-tasques.git
# De SSH a HTTPS
git remote set-url origin https://git.exemple.cat/equip/gestor-tasques.gitNo hi perds res: els commits són els mateixos, les referències són les mateixes i només canvia el camí.
- Gestors de credencials per sistema operatiu
Amb HTTPS queda un problema pràctic: ningú no teclejarà un testimoni de 40 caràcters a cada push. Per a això existeix credential.helper, que ja va treure el nas a la lliçó 01-06 i que ara podem entendre del tot.
Un credential helper és un programa extern al qual Git li pregunta «tens credencials per a aquest servidor?» abans de mostrar l'indicatiu, i al qual li diu «desa't aquestes» quan l'accés funciona.
sequenceDiagram
participant G as git push
participant H as credential.helper
participant A as Magatzem del sistema
participant S as Servidor
G->>H: Credencials per a git.exemple.cat?
H->>A: Consulta (xifrada)
A-->>H: usuari + testimoni
H-->>G: Aquí les tens
G->>S: Autenticació
S-->>G: Correcte
Note over G,A: Si fallen, Git ho pregunta a l'usuari<br/>i demana al helper que desi les noves
El de cada sistema
Linux (Ana, Ubuntu) — libsecret
S'integra amb el clauer de l'escriptori (GNOME Keyring, KWallet), que desa els secrets xifrats i es desbloqueja amb la sessió:
sudo apt install libsecret-1-0 libsecret-1-dev
# Compilar l'ajudant que ve amb Git
sudo make --directory=/usr/share/doc/git/contrib/credential/libsecret
git config --global credential.helper \
/usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecretEn algunes distribucions ve ja compilat i n'hi ha prou d'instal·lar el paquet corresponent.
macOS (Bruno) — osxkeychain
Ve inclòs amb Git a macOS; una sola línia:
Les credencials es desen al Clauer, xifrades i visibles a l'aplicació Accés a Clauers, on es poden revisar i esborrar.
Windows 11 (Carla) — Git Credential Manager
És el cas més interessant, i per això el deixem per al final. GCM s'instal·la juntament amb Git per a Windows i queda configurat per defecte:
El que fa GCM va més enllà de desar una cadena:
- Desa les credencials a l'Administrador de credencials de Windows, xifrades amb el compte d'usuari del sistema.
- Obre una finestra de navegador per autenticar-se contra GitHub, GitLab o Azure DevOps, amb suport per a doble factor.
- Pot generar i renovar testimonis per si mateix, de manera que la Carla no n'ha de crear cap a mà.
- És multiplataforma: existeix també per a Linux i macOS, encara que en aquests sistemes els natius solen ser suficients.
Per a la Carla, això significa que el seu primer git clone d'un repositori privat obrirà una finestra del navegador, ella hi entrarà amb el seu compte i el seu segon factor, i a partir d'aquí no tornarà a veure cap indicatiu. És, amb diferència, l'experiència més còmoda de les tres.
Si vol comprovar què hi ha desat, ho pot obrir des del Git Bash:
Les entrades de Git apareixen a la secció «Credencials genèriques» amb el prefix git:.
Resum i store, el que no has de fer servir
| Ajudant | Sistema | On desa | Xifrat | Recomanació |
|---|---|---|---|---|
manager |
Windows (i multiplataforma) | Administrador de credencials de Windows | Sí | L'opció a Windows |
osxkeychain |
macOS | Clauer del sistema | Sí | L'opció a macOS |
libsecret |
Linux | Clauer de l'escriptori | Sí | L'opció a Linux |
cache |
Qualsevol | Memòria RAM, temporalment | No s'aplica: no toca el disc | Acceptable: segur però oblidadís |
store |
Qualsevol | ~/.git-credentials, text pla |
NO | Evita'l |
Per què store desa en text pla i quan (no) fer-lo servir
És temptador pel que és de fàcil:
I funciona a la primera. El problema es veu en mirar el fitxer que crea:
https://ana.ferrer:[email protected]
El teu testimoni, llegible, en un fitxer de la teva carpeta personal. Sense xifrar, sense contrasenya mestra, sense caducitat. Els permisos són 600, cosa que protegeix d'altres usuaris de la mateixa màquina, però no de:
- Qualsevol programa que s'executi amb el teu usuari, inclosa una dependència maliciosa del teu projecte.
- Una còpia de seguretat de la teva carpeta personal que acabi en un disc extern o al núvol.
- Algú que engegui l'ordinador des d'un USB o extregui el disc.
- Un fitxer de configuració sincronitzat per error entre màquines.
Quan no fer-lo servir: al teu portàtil, al teu ordinador de sobretaula, en qualsevol màquina amb accés a repositoris que importin.
Quan podria tenir sentit: en un contenidor efímer o una màquina virtual descartable, aïllada, amb un testimoni de només lectura i caducitat d'hores, on no hi ha cap clauer disponible i el cicle de vida de la màquina és més curt que el del testimoni. Fins i tot allà, gairebé sempre hi ha una opció millor.
L'alternativa raonable quan no hi ha clauer és cache, que manté les credencials a la memòria durant un temps limitat:
Una hora sense tornar a teclejar, i res tocant el disc. En apagar, desapareix.
Tot el relatiu a la gestió de secrets, la signatura de commits i el tractament de credencials filtrades a l'historial es desenvolupa a la lliçó 08-05. Aquí ens hem ocupat del que és operatiu: poder treballar còmodament sense deixar secrets escampats.
- Errors típics i com diagnosticar-los
Permission denied (publickey)
[email protected]: Permission denied (publickey). fatal: Could not read from remote repository.
És l'error d'SSH més habitual. Significa: «El servidor no ha acceptat cap de les claus que li has ofert.» Les causes, en ordre de freqüència:
Si respon Could not open a connection to your authentication agent, l'agent no està en marxa:
Si respon The agent has no identities, està en marxa però buit: falta l'ssh-add.
# 3. La clau pública pujada al servidor és la mateixa que tens?
ssh-keygen -lf ~/.ssh/id_ed25519.pub256 SHA256:9xK2mQ7RtVb3Ln8ZwYcF4dJ6hP1sT5uA2eB9gN0kM3o [email protected] (ED25519)
Compara aquesta empremta amb la que mostra la plataforma a la llista de claus. Si no coincideix, en vas pujar una altra.
# 4. Els permisos són correctes?
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pubOpenSSH ignora en silenci les claus privades amb permisos massa oberts, cosa que produeix aquest error sense cap pista.
# 5. El diagnòstic definitiu
ssh -vT [email protected]A la sortida veuràs quines claus ofereix (Offering public key:) i com respon el servidor. És la manera més ràpida de descobrir que estàs oferint la clau equivocada.
Host key verification failed
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Significa que la clau del servidor no coincideix amb la que tenies desada a ~/.ssh/known_hosts. Hi ha dues explicacions possibles:
- Legítima: el servidor s'ha reinstal·lat, s'ha migrat o la plataforma ha rotat les seves claus (passa de tant en tant i sempre s'anuncia públicament).
- Atac d'intermediari: algú s'està fent passar pel servidor.
No esborris l'entrada sense comprovar-ho. El procediment correcte:
# 1. Veure quina empremta està presentant el servidor ara
ssh-keyscan git.exemple.cat 2>/dev/null | ssh-keygen -lf -# 2. Comparar amb l'empremta oficial publicada per la plataforma.
# Si i només si coincideix, eliminar l'entrada antiga:
ssh-keygen -R git.exemple.cat
# 3. Reconnectar i acceptar la nova
ssh -T [email protected]La variant suau del mateix avís —The authenticity of host … can't be established— és la primera connexió: encara no hi ha res desat. També allà convé comparar l'empremta abans d'acceptar.
Altres errors freqüents
| Missatge | Causa habitual | Solució |
|---|---|---|
Support for password authentication was removed |
Estàs fent servir la contrasenya del compte | Genera un testimoni i fes-lo servir en lloc seu |
Authentication failed for 'https://…' |
Testimoni caducat, revocat o mal desat | Esborra la credencial del gestor i torna't a autenticar |
403 Forbidden / Permission to … denied |
Autorització, no autenticació | Revisa permisos al repositori i àmbits del testimoni |
Repository not found |
Repositori privat sense accés, o URL erroni | Verifica l'URL i els teus permisos |
Connection timed out (port 22) |
Tallafocs bloquejant SSH | Fes servir HTTPS, o SSH pel port 443 si la plataforma l'ofereix |
Too many authentication failures |
SSH ofereix massa claus | IdentitiesOnly yes a ~/.ssh/config |
Load key … bad permissions |
Permisos massa oberts a la privada | chmod 600 ~/.ssh/id_ed25519 |
I una ordre que resol el «no sé quina credencial està fent servir Git»:
Mostra el procés complet, inclòs quin ajudant de credencials s'invoca. Fes-lo servir només per depurar i no comparteixis la seva sortida sense revisar-la, perquè pot incloure capçaleres sensibles.
Errors Habituals i Consells
Error 1: pujar la clau privada en lloc de la pública. Passa més del que sembla. La regla és simple: es puja el fitxer que acaba en .pub. Si has pujat la privada per error, esborra-la del servidor, elimina el parell sencer del teu disc i genera'n un de nou: aquella clau està compromesa per sempre.
Error 2: incrustar el testimoni a l'URL del remot. Acaba a .git/config, a l'historial del shell i en qualsevol captura de pantalla. Fes servir un gestor de credencials.
Error 3: crear la clau sense passphrase «per anar de pressa». El robatori del portàtil passa de ser un problema de maquinari a ser un problema d'accés a tots els teus repositoris. Amb ssh-agent, la passphrase es teclega una vegada per sessió.
Error 4: confondre user.email amb la identitat d'accés. Canviar user.email no arregla cap problema d'autenticació: només canvia el text que apareix als commits. Són capes diferents.
Error 5: acceptar l'empremta del servidor sense mirar-la. Aquest indicatiu de la primera connexió és l'única oportunitat de detectar una suplantació. Les plataformes publiquen les seves empremtes; comparar-les costa deu segons.
Error 6: fer servir el mateix testimoni en cinc màquines. Quan s'hagi de revocar, es trencaran les cinc alhora i no sabràs quina es va filtrar. Un testimoni per màquina i per propòsit.
Error 7: fer servir credential.helper store per defecte. Deixa el testimoni en text pla a la teva carpeta personal. Fes servir el gestor natiu del teu sistema, o cache si no n'hi ha cap de disponible.
Consell 1: prova sempre amb ssh -T abans de culpar Git. Si ssh -T git@servidor funciona, el problema no és a SSH. Si no funciona, ssh -vT et diu exactament en quin pas falla.
Consell 2: posa un comentari útil a la clau. -C "carla-portatil-windows" és infinitament més pràctic que el correu quan d'aquí a un any vegis quatre claus a la llista del servidor i hagis de decidir quina revocar.
Consell 3: apunta la caducitat dels teus testimonis. Un testimoni que expira un dilluns al matí genera mitja hora de desconcert. Posa't un recordatori uns dies abans.
Consell 4: IdentitiesOnly yes sempre que tinguis més d'una clau. Evita el Too many authentication failures, que és dels errors més difícils de relacionar amb la seva causa.
Consell 5: per a automatització, àmbit mínim i caducitat curta. Un testimoni d'integració contínua que només ha de clonar no necessita permís d'escriptura ni d'administració.
Exercicis
Exercici 1: generar i auditar un parell de claus
Sense pujar res a cap servidor:
- Genera un parell Ed25519 en una ruta específica:
~/.ssh/practica_curs, amb un comentari descriptiu. - Mostra els permisos dels dos fitxers i explica per què són diferents.
- Mostra l'empremta de la clau pública.
- Carrega-la a
ssh-agenti verifica que apareix llistada. - Comprova que l'empremta de la clau privada i la de la pública coincideixen. Explica per què.
- Descarrega-la de l'agent i elimina els fitxers.
Exercici 2: configurar dues identitats
La Carla necessita treballar amb dos comptes: el de l'equip (git.exemple.cat) i el d'una altra empresa (git.altraempresa.cat).
- Escriu el
~/.ssh/configcomplet per a tots dos, amb claus separades. - Explica què fa cada directiva.
- Escriu l'URL de clonatge que faria servir per a cada repositori.
- Indica l'ordre que li permetria comprovar quina clau concreta s'ofereix a cada servidor.
- Explica què passaria si ometés
IdentitiesOnly yesi tingués sis claus carregades.
Exercici 3: diagnòstic
Per a cadascun d'aquests missatges, indica: (a) si l'errada és d'autenticació o d'autorització, (b) les dues causes més probables i (c) l'ordre o comprovació amb què començaries.
[email protected]: Permission denied (publickey).remote: Permission to equip/gestor-tasques.git denied to carla.remote: Support for password authentication was removed.WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!ssh: connect to host git.exemple.cat port 22: Connection timed out
Solucions
Solució 1:
# 1. Generar amb ruta i comentari
ssh-keygen -t ed25519 -f ~/.ssh/practica_curs -C "practica-curs-git"Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/carla/.ssh/practica_curs Your public key has been saved in /home/carla/.ssh/practica_curs.pub The key fingerprint is: SHA256:4tR8mK2nQ7xVb3Lc9ZwYeF6dJ1sP5uA0eB7gN2kM3o practica-curs-git
L'opció -f fixa la ruta i evita el diàleg d'«on desar».
-rw------- 1 carla carla 464 ago 1 10:22 /home/carla/.ssh/practica_curs -rw-r--r-- 1 carla carla 103 ago 1 10:22 /home/carla/.ssh/practica_curs.pub
La privada és 600: només el seu propietari la pot llegir, i OpenSSH es nega a fer-la servir si tingués permisos més laxos, perquè qualsevol altre usuari del sistema la podria copiar. La pública és 644 perquè està dissenyada per repartir-se: no revela res explotable.
Agent pid 6120 Enter passphrase for /home/carla/.ssh/practica_curs: Identity added: /home/carla/.ssh/practica_curs (practica-curs-git) 256 SHA256:4tR8mK2nQ7xVb3Lc9ZwYeF6dJ1sP5uA0eB7gN2kM3o practica-curs-git (ED25519)
256 SHA256:4tR8mK2nQ7xVb3Lc9ZwYeF6dJ1sP5uA0eB7gN2kM3o practica-curs-git (ED25519) 256 SHA256:4tR8mK2nQ7xVb3Lc9ZwYeF6dJ1sP5uA0eB7gN2kM3o practica-curs-git (ED25519)
Idèntiques, i no és casualitat. L'empremta és un hash de la clau pública, i la pública es pot derivar de la privada (el contrari, no). Quan ssh-keygen -lf rep una clau privada, n'extreu la pública i en calcula l'empremta. Per això l'empremta serveix per emparellar sense ambigüitat quina privada del teu disc correspon a quina pública pujada al servidor: és exactament la comprovació de l'apartat 10.
Solució 2:
# Primer, les dues claus
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_feina -C "carla-feina-exemple"
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_altraempresa -C "carla-altraempresa"1. El fitxer ~/.ssh/config:
# Identitat de l'equip de gestor-tasques
Host git.exemple.cat
HostName git.exemple.cat
User git
IdentityFile ~/.ssh/id_ed25519_feina
IdentitiesOnly yes
AddKeysToAgent yes
# Identitat de l'altra empresa (àlies inventat)
Host git-altraempresa
HostName git.altraempresa.cat
User git
IdentityFile ~/.ssh/id_ed25519_altraempresa
IdentitiesOnly yes
AddKeysToAgent yes2. Què fa cada directiva:
Host: el nom que la Carla escriu a l'URL. Al primer bloc coincideix amb el servidor real; al segon és un àlies inventat que no existeix a cap DNS.HostName: el servidor real al qual cal connectar-se. És el que resol l'àlies.User git: l'usuari SSH. A les plataformes de repositoris és sempregit; l'usuari real es dedueix de la clau que presentes.IdentityFile: quina clau privada fer servir amb aquesta destinació.IdentitiesOnly yes: fer servir només aquesta clau, sense oferir les altres.AddKeysToAgent yes: carregar-la a l'agent al primer ús, per no repetir la passphrase.
3. Els URL de clonatge:
# Repositori de l'equip
git clone [email protected]:equip/gestor-tasques.git
# Repositori de l'altra empresa: es fa servir l'ÀLIES
git clone git@git-altraempresa:projectes/facturacio.git4. Comprovar quina clau s'ofereix:
ssh -T -v [email protected] 2>&1 | grep "Offering public key"Cada destinació rep exactament una clau, la seva.
5. Sense IdentitiesOnly yes: SSH oferiria totes les claus carregades a l'agent, una per una, en un ordre que no controles. Amb sis claus i un servidor amb el MaxAuthTries a 6 (el valor habitual), és molt probable que exhaureixi els intents abans d'arribar a la correcta:
Un error especialment traïdor, perquè la clau correcta existeix i està carregada: simplement no li ha donat temps de provar-la. A més, oferir totes les teves claus a qualsevol servidor amb qui parlis és una fuita d'informació innecessària: li reveles quantes identitats tens.
Solució 3:
1. Permission denied (publickey)
- (a) Autenticació. El servidor no ha acceptat cap clau: ni tan sols sap qui ets.
- (b) La clau no està carregada a l'agent, o la que tens al disc no és la que està pujada al servidor. Menys freqüent però molt desconcertant: permisos massa oberts a la privada, que fan que OpenSSH la ignori en silenci.
- (c)
ssh-add -lper veure què hi ha carregat i, si això no aclareix res,ssh -vT [email protected]per veure quina clau s'ofereix i com respon el servidor.
2. Permission to equip/gestor-tasques.git denied to carla
- (a) Autorització. El missatge anomena la Carla, així que l'autenticació ha funcionat perfectament.
- (b) El seu compte no té permís d'escriptura en aquell repositori, o —si va per HTTPS amb testimoni— el testimoni no té l'àmbit d'escriptura.
- (c) Revisar els permisos del compte a la configuració del repositori i els àmbits del testimoni a la plataforma. No hi ha cap ordre de Git que arregli això: és un canvi al servidor.
3. Support for password authentication was removed
- (a) Autenticació. S'està enviant un mètode que el servidor ja no admet.
- (b) S'ha teclejat la contrasenya del compte en lloc d'un testimoni; o hi ha una credencial antiga desada al gestor, amb la contrasenya d'abans de la migració.
- (c) Generar un testimoni amb l'àmbit necessari i, molt important, esborrar la credencial desada abans de tornar-ho a provar, o el gestor tornarà a enviar la vella:
# Eliminar la credencial emmagatzemada per a aquell servidor
printf "protocol=https\nhost=git.exemple.cat\n\n" | git credential reject4. REMOTE HOST IDENTIFICATION HAS CHANGED!
- (a) Autenticació, però en el sentit invers: és el servidor qui no aconsegueix demostrar la seva identitat davant teu.
- (b) El servidor s'ha reinstal·lat o la plataforma ha rotat les seves claus (el normal); o algú està interceptant la connexió (el greu).
- (c) Obtenir l'empremta actual i comparar-la amb la publicada oficialment abans de tocar res:
Només si coincideix amb l'oficial: ssh-keygen -R git.exemple.cat i reconnectar.
5. connect to host … port 22: Connection timed out
- (a) Cap de les dues: és un problema de xarxa. La connexió no arriba a establir-se, així que no hi ha ni autenticació ni autorització.
- (b) Un tallafocs corporatiu amb el port 22 tancat (el més habitual amb diferència), o el servidor caigut.
- (c) Comprovar la connectivitat i, si és el tallafocs, canviar de via:
# Arriba res al port 22?
nc -zv git.exemple.cat 22
# Solució pràctica: passar a HTTPS
git remote set-url origin https://git.exemple.cat/equip/gestor-tasques.gitAlgunes plataformes ofereixen a més SSH pel port 443, que travessa aquests tallafocs:
Conclusió
Amb aquesta lliçó l'equip pot per fi parlar amb el servidor. L'essencial:
- Llegir un repositori públic no requereix credencials; escriure sempre sí, perquè
pushmodifica les referències del servidor. user.nameiuser.emailno autentiquen res: són metadades del commit. La identitat d'accés viu en una altra capa.- Autenticació (qui ets) i autorització (què pots fer) són diferents.
Permission denied (publickey)és el primer;403 Forbiddenés el segon. Distingir-les dirigeix el diagnòstic. - HTTPS s'autentica amb un testimoni personal d'accés, que va substituir la contrasenya per ser d'àmbit limitat, revocable, caducable, auditable i compatible amb doble factor. Concedeix sempre l'àmbit mínim i fes servir un testimoni per màquina.
- SSH s'autentica amb un parell de claus: la privada no surt mai del teu disc, la pública es puja al servidor. Genera amb
ssh-keygen -t ed25519 -C "descripció", posa-hi passphrase, puja el fitxer.pub, prova ambssh -Ti fes servirssh-agentper teclejar-la una sola vegada. ~/.ssh/configresol el cas de diverses identitats, fins i tot dos comptes al mateix servidor, mitjançant àlies inventats.IdentitiesOnly yesevita elToo many authentication failures.- HTTPS davant de SSH: HTTPS guanya en tallafocs corporatius i en granularitat de permisos; SSH guanya en comoditat diària, en no caducar i en manejar diverses identitats. Canviar d'un a l'altre és un
git remote set-url. - Cada sistema té el seu gestor de credencials:
libsecreta Linux,osxkeychaina macOS i Git Credential Manager a Windows, que a més obre el navegador i gestiona els testimonis per tu: el camí de la Carla. credential.helper storedesa el testimoni en text pla a~/.git-credentials. Evita'l en màquines reals; si no hi ha clauer,cacheamb temps d'espera és millor opció.- Per a la resta —signatura de commits, gestió de secrets, credencials filtrades a l'historial— la lliçó 08-05.
El que ve
L'Ana, en Bruno i la Carla ja es poden autenticar. El canal està obert en els dos sentits i, per primera vegada al curs, els objectes poden viatjar d'un .git/ a un altre.
A la lliçó 04-04: Obtenint i Baixant Canvis comencem a fer-lo servir en el sentit de la recepció, i ataquem de front la confusió més estesa de Git: la diferència entre git fetch i git pull. Veurem per què fetch no toca mai el teu directori de treball, què és FETCH_HEAD, com inspeccionar el que ha arribat abans d'integrar-ho, i les diferents maneres de git pull. I per fi la Carla clona gestor-tasques i es posa al dia amb la feina dels seus companys.
Dominant Git: De Principiant a Avançat
Mòdul 1: Introducció a Git
- Què és Git?
- Instal·lant Git
- Terminologia Bàsica de Git
- El Model de Dades de Git
- Configurant Git
- Configuració Inicial
Mòdul 2: Operacions Bàsiques de Git
- Creant un Repositori
- Clonant un Repositori
- Flux de Treball Bàsic de Git
- Preparant i Confirmant Canvis
- Inspeccionant Canvis amb git diff
- Visualitzant l'Historial de Confirmacions
Mòdul 3: Branques i Fusió
- Entenent les Branques
- Creant i Canviant Branques
- Fusionant Branques
- Estratègies de Fusió
- Resolent Conflictes de Fusió
- Gestió de Branques
Mòdul 4: Treballant amb Repositoris Remots
- Entenent els Repositoris Remots
- Afegint un Repositori Remot
- Autenticació amb Repositoris Remots
- Obtenint i Baixant Canvis
- Enviant Canvis
- Rastrejant Branques
Mòdul 5: Operacions Avançades de Git
- Rebase
- Rebase Interactiu
- Cherry-Picking de Confirmacions
- Desant Canvis Temporals
- Etiquetant Confirmacions
- Revertint Confirmacions
Mòdul 6: Eines i Tècniques de Git
- Usant Git Hooks
- Git Bisect
- Git Blame
- Git Log i Àlies
- Submòduls de Git
- Múltiples Còpies de Treball amb git worktree
Mòdul 7: Estratègies de Col·laboració i Flux de Treball
- Forks i Pull Requests
- Revisions de Codi amb Git
- Flux de Treball Git Flow
- GitHub Flow
- Trunk Based Development
- Integració Contínua amb Git
Mòdul 8: Bones Pràctiques i Consells de Git
- Escrivint Bons Missatges de Confirmació
- Mantenint un Historial Net
- Ignorant Fitxers amb .gitignore
- Atributs de Fitxer amb .gitattributes
- Bones Pràctiques de Seguretat
- Consells de Rendiment
Mòdul 9: Resolució de Problemes i Depuració
- Problemes Habituals de Git
- Desfent Canvis
- Resolent Divergències amb el Remot
- Recuperant Confirmacions Perdudes
- Tractant amb Repositoris Corruptes
- Tècniques Avançades de Depuració
