Everything you build in this course goes into a git repository on GitHub. The first push from a new machine fails for everyone: git does not know who you are, and GitHub does not know this machine. This lesson sets up both - a name for your commits, and a key that proves the machine is allowed in.
What you need to know already: 1.1 Where you are (SSH), 1.3 The tree (dotfiles, permissions like 600).
git in five words
You probably used git from an editor; here is the vocabulary from the command line.
- git - a version control tool: it records snapshots of a set of files so you can see and undo every change.
- repository (repo) - a directory whose history git tracks. The history lives in a hidden
.gitdirectory inside it. - commit - one saved snapshot, with a message and an author.
git add FILEmarks a change to go into the next commit (this is called staging);git commit -m "message"saves it. - remote - another copy of the repo, usually on a server like GitHub. The default one is named
origin.git clone URLcopies a remote repo to your machine;git pushsends your new commits to the remote. git status- what changed since the last commit;git remote -v- which remote URL the repo uses.
Git needs to know who you are
Every commit records a name and an email. Git will not guess them:
git config --global user.name "Learner"
git config --global user.email "[email protected]"
git config sets a git setting. --global writes it to ~/.gitconfig, so it applies to every repo on this box for your user. Without --global it applies only to the repo you are standing in - useful when work and personal identities differ.
Check with git config --list.
A key instead of a password
SSH can log you in with a key pair instead of a password. It is two matching files made together:
- the private key - a secret that never leaves the machine;
- the public key - safe to give to anyone. Anything signed (stamped) with the private key can be checked with the public key, but the public key cannot be used to work out the private one.
You give GitHub your public key. When you connect, GitHub asks your machine to sign a random challenge with the private key and checks the signature with the public key. No password ever travels.
ssh-keygen -t ed25519 -C "[email protected]"
ssh-keygen- creates key pairs.-t ed25519- the type (algorithm - the maths used): ed25519 is the modern choice. Short keys, fast, strong. RSA, the older type, still works, but there is no reason to choose it now.-C- a comment stored in the public key. By convention your email; it is what you see in the GitHub settings page when you have six keys and need to know which machine each belongs to.
You get two files in ~/.ssh/:
id_ed25519- the private key, mode 600 (only you may read or write it). Never pasted anywhere.id_ed25519.pub- the public key. This is the one that goes to GitHub.
ssh-keygen also asks for a passphrase: a password that encrypts the private key file itself, so a stolen copy is useless. Empty is fine on a throwaway lab VM. On anything real, set one.
Trust on first use
Keys work in both directions: the server has its own key pair too, its host key, so you can check that you reached the real server and not an impostor.
The first ssh to a host prints the host key's fingerprint and asks whether to continue. A fingerprint is a hash of the key: a short string computed from it, which changes completely if even one bit of the key changes. So comparing fingerprints is a quick way to compare keys. The question really means "is this really github.com?". Say yes, and the host key is saved in ~/.ssh/known_hosts; from then on, a different key for that host produces a loud warning instead of silently connecting you somewhere else.
"Yes" is only safe if the fingerprint is right. GitHub publishes its host key fingerprints in its docs ("GitHub's SSH key fingerprints"); the Ed25519 one is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU (SHA256 is the hash method used). Compare before you type yes.
One Ubuntu surprise: its SSH settings (/etc/ssh/ssh_config) turn on HashKnownHosts yes, so the host name in known_hosts is stored hashed too: |1|salt|hash ssh-ed25519 AAAA.... grep github.com ~/.ssh/known_hosts therefore finds nothing. Ask ssh-keygen instead:
ssh-keygen -F github.com Find: is this host in known_hosts? (prints the line)
ssh-keygen -R github.com Remove it (after a legitimate host key change)
ssh-keygen -lf ~/.ssh/id_ed25519.pub list the fingerprint of a key file
Finally, test the whole chain:
ssh -T [email protected]
[email protected] means "log in as user git on github.com" - everyone uses that same user; GitHub tells you apart by your key. -T means "no terminal, I just want to authenticate". A successful answer is GitHub greeting you by name and then refusing shell access - that refusal is the success.
What you can now do
- Set the git identity stamped on every commit.
- Make an ed25519 key pair and say which half goes where.
- Check a host's fingerprint before trusting it, and find it in known_hosts.