Skip to content

Instantly share code, notes, and snippets.

@psycho0verload
Last active May 22, 2022 21:01
Show Gist options
  • Save psycho0verload/38d0a9ebf06b16776f741a7801244397 to your computer and use it in GitHub Desktop.
Save psycho0verload/38d0a9ebf06b16776f741a7801244397 to your computer and use it in GitHub Desktop.
Multiple SSH keys for different github accounts on macOS 12 Monterey | Mehrere SSH-Schlüssel für verschiedene Github-Konten unter macOS 12 Monterey
American Flag English Version

Multiple SSH keys for different github accounts on macOS 12 Monterey

Table of contents

Requirements

  • Own key pair for each account (see article)
  • macOS Monterey (so far only tested here)
  • Basic knowledge iTerm2 or Terminal

Instructions

Cleanup of ssh directory & SSH agents (optional)

Sometimes it makes sense to clean up everything so far. This is optional for me. Since I have already paid attention to which key I generate and use, this is not necessary for me. Nevertheless I want to describe the steps here. Navigate to the ssh location:

cd ~/.ssh

Now I clean up the existing configuration by deleting the config, known_hosts and other ssh files with public and private keys using rm filename. Now I still need to clean the SSH agent with:

ssh-add -D

The SSH key

First, I have a single location for SSH keys on my Macbook: ~/.ssh. Here I also find the default key id_rsa. I create a separate key pair for each account on GitHub (and GitLab) (see article).

# Key for my private GitHub account:
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/ed25519_privat-github -C "[email protected]"

# Key for my company GitHub account:
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/ed25519_firma-github -C "[email protected]"

With this I created two new key pairs named ed25519_privat-github and ed25519_firma-github.

The public and private key can now be found in ~/.ssh. Next, I copy the public key into the respective GitHub or GitLab account. The new key can be added at https://github.com/settings/keys or https://gitlab.com/-/profile/keys.

# Copy public key from private GitHub to clipboard
pbcopy < ~/.ssh/ed25519_privat-github.pub

Now the account trusts the particular .pub key, but my Macbook still sends the id_rsa key when I run an ssh git command. My Macbook does not know that there is a new key with a different name, and even if it knew, it would not try all the keys found in ~/.ssh.

Customize configuration file for SSH key

The solution is a configuration file in '~/.ssh`. To create this, I run nano config in the .ssh directory:

nano ~/.ssh/config

Here I now define all the keys I need.

# private GitHub account
Host github.com-privat
  HostName github.com
  AddKeysToAgent yes
  UseKeyChain yes
  IdentityFile ~/.ssh/ed25519_privat-github
  ServerAliveInterval 600
  TCPKeepAlive yes
  IPQoS=throughput
# company GitHub account
Host github.com-firma
  HostName github.com
  AddKeysToAgent yes
  UseKeyChain yes
  IdentityFile ~/.ssh/ed25519_firma-github
  ServerAliveInterval 600
  TCPKeepAlive yes
  IPQoS=throughput

Note: I have added additional lines to the configuration here to maintain the server connection and to avoid disconnections. This helps with the following errors:

Broken pipe fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.

This configuration file now causes my Macbook to use the private SSH key to access the host github.com-private and to use the company SSH key now for the host github.com-company.

Add SSH key to SSH agent

First I start the SSH agent in my iTerm2:

eval "$(ssh-agent -s)"

Add key to SSH agent:

ssh-add --apple-use-keychain ~/.ssh/ed25519_privat-github
ssh-add --apple-use-keychain ~/.ssh/ed25519_firma-github-ad

Verify that the keys are stored in the SSH agent:

ssh-add -l

Note: The SSH agent on the Mac loses the keys on reboot. I can work around this by simply running this command when I restart my Macbook:

ssh-add --apple-load-keychain

Verify login via SSH key

I enter the following command in iTerm2:

ssh -T [email protected]

Now when I am asked to add the hosts to my know_hosts file, I confirm this with yes.

The authenticity of host 'github.com (140.82.121.3)' can't be established.
ED25519 key fingerprint is <key>.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

I should now see a confirmation that I am connected:

Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.

I now perform these steps for all accounts or assigned SSH keys.

Customize Git-Projects

The next step is to customize my Git project.

Clone Git-Project

Before: [email protected]:username/projekt.git
After: [email protected]:username/projekt.git
# Clone private git project
git clone [email protected]:username/projekt.git
# Companies Git project clone
git clone [email protected]:username/projekt.git

Customize Git-Project on hand

I switch to the existing Git project and edit the configuration with

nano .git/config
[core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
      ignorecase = true
      precomposeunicode = true
[remote "origin"]
      url = [email protected]:username/project.git
      fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
      remote = origin
      merge = refs/heads/main

I update the remote URL to the newly created account reference:

[core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
      ignorecase = true
      precomposeunicode = true
[remote "origin"]
      url = [email protected]:username/project.git
      fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
      remote = origin
      merge = refs/heads/main

Give Git project the name & email

Now I should give the respective Git project a name and an email address. There are several possibilities for this.

Simplest method

Change to the Git project directory

cd Git-Project

Now I add the name and the email address belonging to the account

git config user.name "My Name"
git config user.email "[email protected]"

This means that locally in the Git project the email and the name are now set.

More elaborate method

I change back to my user directory

cd

Now I create a Git configuration file for myself:

nano .gitconfig

In this I define an explicit .gitconfig file for each explicit path, in which name and email address is then stored:

[includeIf "gitdir:~/Developer/GitLab.com/Firma/"]
  path = ~/Developer/GitLab.com/Firma/.gitconfig
[includeIf "gitdir:~/Developer/GitHub.com/Privat/"]
  path = ~/Developer/GitHub.com/Privat/.gitconfig
[core]
  excludesfile = ~/.gitignore_global

In this case I have mapped my personal development environment. Under the folder ~/Developer/GitLab.com/Firma/ are all my Git projects from my company account. Under ~/Developer/GitHub.com/Privat/ are my Git projects from my private account. Nun lege ich in jedem Ordner noch die oben definierte .gitconfig an

cd ~/Developer/GitLab.com/Firma/
nano .gitconfig

There I now store the configurations for the company Git projects:

[user]
        # Insert GitHub deposited email
        email = [email protected]
        # Insert name
        name = Max Mustermann
        # Insert GitHub username
        username = myusername
[github]
        # Insert GitHub username
        user = "myusername"

Now I check if all configurations are available. To do this, I switch to an already cloned project and check the configuration:

cd ~/Developer/GitLab.com/Firma/project
git config --list

The result should look like this:

credential.helper=osxkeychain
includeif.gitdir:~/Developer/GitHub.com/Privat/.path=~/Developer/GitHub.com/Privat/.gitconfig
[email protected]
user.name=Max Mustermann
user.username=meinusername
github.user=meinusername
includeif.gitdir:~/Developer/GitHub.com/Firma/.path=~/Developer/GitHub.com/Firma/.gitconfig
core.excludesfile=~/.gitignore_global
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
[email protected]:firma/project.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

This way, when cloning a git repository, I save myself from always having to add email and username to the .git/config (as with the simple method).

Source

This is a copy of my German post I wrote on my blog: https://psycho0verload.it/2022/05/22/mehrere-ssh-schluessel-fuer-verschiedene-github-konten-auf-macos-monterey-12-4/

Deutsche Flagge Deutsche Version

Mehrere SSH-Schlüssel für verschiedene Github-Konten unter macOS 12 Monterey

Inhaltsverzeichnis

Vorraussetzungen

  • Eigenes Schlüsselpaar für jeden Account (siehe Artikel)
  • macOS Monterey (bisher nur hier getestet)
  • Grundlagenwissen iTerm2 bzw. Terminal

Anleitung

Bereinigen von ssh-Verzeichnis & SSH-Agenten (optional)

Manchmal macht es Sinn alles bisherige aufzuräumen. Dies ist für mich optional. Da ich selbst vorher schon darauf geachtet habe welchen Schlüssel ich generiere und benutze fällt das für mich weg. Trotzdem möchte ich die Schritte hier kurz beschreiben. Navigieren zum ssh-Speicherort:

cd ~/.ssh

Nun bereinige ich die bestehende Konfiguration, indem ich die config, known_hosts und andere ssh-Dateien mit öffentlichen und privaten Schlüsseln mittels rm dateiname löschen. Nun muss ich noch den SSH-Agenten reinigen mit:

ssh-add -D

Der SSH-Schlüssel

Zunächst habe ich auf meinem Macbook einen einzigen Speicherort für SSH-Schlüssel: ~/.ssh. Hier find ich auch den Standardschlüssel id_rsa. Ich lege für jeden Account auf GitHub (und GitLab) einen eigenes Schlüsselpaar an (siehe Artikel).

# Schlüssel für mein privaten GitHub-Account:
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/ed25519_privat-github -C "[email protected]"

# Schlüssel für mein firmen GitHub-Account:
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/ed25519_firma-github -C "[email protected]"

Damit habe ich zwei neue Schlüsselpaare mit den Namen ed25519_privat-github und ed25519_firma-github angelegt.

Der öffentliche und der private Schlüssel ist nun unter ~/.ssh zu finden. Als nächstes kopiere ich den öffentlichen Schlüssel in den jeweiligen GitHub- oder GitLab-Account. Der neue Schlüssel kann unter https://github.com/settings/keys bzw. https://gitlab.com/-/profile/keys hinzugefügt werden.

# Öffentlichen Schlüssel vom privaten GitHub in die Zwischenablage kopieren
pbcopy < ~/.ssh/ed25519_privat-github.pub

Jetzt vertraut der Account dem jeweiligen .pub-Schlüssel, aber mein Macbook sendet immer noch den id_rsa-Schlüssel, wenn ich einen ssh-Git-Befehl ausführe. Mein Macbook weiß nicht, dass es einen neuen Schlüssel mit anderem Namen gibt, und selbst wenn er es wüsste, würde er nicht alle Schlüssel, die unter ~/.ssh zufinden sind, durchprobieren.

Konfigurationsdatei für SSH-Schlüssel anpassen

Die Lösung ist eine Konfigurationsdatei in '~/.ssh`. Um diese zu erstellen, führe ich nano config im .ssh-Verzeichnis aus:

nano ~/.ssh/config

Hier definiere ich nun alle Schlüssel, die ich benötige.

# privater GitHub-Account
Host github.com-privat
  HostName github.com
  AddKeysToAgent yes
  UseKeyChain yes
  IdentityFile ~/.ssh/ed25519_privat-github
  ServerAliveInterval 600
  TCPKeepAlive yes
  IPQoS=throughput
# firmen GitHub-Account
Host github.com-firma
  HostName github.com
  AddKeysToAgent yes
  UseKeyChain yes
  IdentityFile ~/.ssh/ed25519_firma-github
  ServerAliveInterval 600
  TCPKeepAlive yes
  IPQoS=throughput

Hinweis: Ich habe hier zusätzliche Zeilen zur Konfiguration hinzugefügt, um die Serververbindung aufrechtzuerhalten und um Verbindungsabbrüche zu vermeiden. Dies hilft bei folgende Fehler:

Broken pipe fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.

Diese Konfigurationsdatei bewirkt nun, dass meinem Macbook den privaten SSH-Schlüssel für den Zugriff auf den Host github.com-privat verwendet und den firmen SSH-Schlüssel nun für den Host github.com-firma verwendet.

SSH-Schlüssel zum SSH-Agenten hinzufügen

Als erstes starte ich den SSH-Agenten in meinem iTerm2:

eval "$(ssh-agent -s)"

Schlüssel zum SSH-Agenten hinzufügen:

ssh-add --apple-use-keychain ~/.ssh/ed25519_privat-github
ssh-add --apple-use-keychain ~/.ssh/ed25519_firma-github-ad

Überprüfen, dass die Schlüssel im SSH-Agent gespeichert sind:

ssh-add -l

Hinweis: Der SSH-Agent auf dem Mac verliert die Schlüssel beim Neustart. Ich kann das umgehen, indem ich beim Neustart meines Macbooks einfach diesen Befehl ausführe:

ssh-add --apple-load-keychain

Login via SSH-Schlüssel überprüfen

Ich gebe folgenden Befehl in iTerm2 ein:

ssh -T [email protected]

Wenn ich nun aufgefordert werde, die Hosts zu meiner know_hosts-Datei hinzuzufügen, bestätige ich das mit yes

The authenticity of host 'github.com (140.82.121.3)' can't be established.
ED25519 key fingerprint is <key>.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Ich sollte nun eine Bestätigung sehen, dass ich verbunden bin:

Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.

Diese Schritte führe ich nun für alles Accounts bzw. zugeordnete SSH-Schlüssel durch.

Git-Projekte anpassen

Im nächsten Schritt muss ich mein Git-Projekt anpassen.

Git-Projekt clonen

Vorher: [email protected]:username/projekt.git
Nachher: [email protected]:username/projekt.git
# Privates Git-Projekt clonen
git clone [email protected]:username/projekt.git
# Firmen Git-Projekt clonen
git clone [email protected]:username/projekt.git

Vorhandes Git-Projekt anpassen

Ich wechsel zum vorhandenen Git-Projekt und bearbeite die Konfiguration mit

nano .git/config
[core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
      ignorecase = true
      precomposeunicode = true
[remote "origin"]
      url = [email protected]:username/project.git
      fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
      remote = origin
      merge = refs/heads/main

Ich aktualisiere den Remote-URL auf die neu erstellte Konto-Referenz:

[core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
      ignorecase = true
      precomposeunicode = true
[remote "origin"]
      url = [email protected]:username/project.git
      fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
      remote = origin
      merge = refs/heads/main

Git-Projekt den Name & Email mitgeben

Nun sollte ich dem jeweiligen Git-Projekt noch einen Namen und eine Email-Adresse mitgeben. Hierfür gibt es mehrere Möglichkeiten.

Einfachste Methode

In das Git-Projekt-Verzeichnis wechseln

cd Git-Projekt

Nun füge ich den Name und die zum Account gehörende Email-Adresse hinzu

git config user.name "Mein Name"
git config user.email "[email protected]"

Damit ist lokal im Git-Projekt nun die Email und der Name gesetzt.

Aufwendigere Methode

Ich wechsele wieder in mein User-Verzeichnis

cd

Nun lege ich mir eine Git-Konfigurationsdatei an:

nano .gitconfig

In dieser definiere ich für einen expliziten Pfad jeweils eine explizite .gitconfig-Datei in welcher Name und Email-Adresse dann hinterlegt wird:

[includeIf "gitdir:~/Developer/GitLab.com/Firma/"]
  path = ~/Developer/GitLab.com/Firma/.gitconfig
[includeIf "gitdir:~/Developer/GitHub.com/Privat/"]
  path = ~/Developer/GitHub.com/Privat/.gitconfig
[core]
  excludesfile = ~/.gitignore_global

In diesem Fall habe ich meine persönliche Entwicklungsumgebung abgebildet. Unter dem Ordner ~/Developer/GitLab.com/Firma/ befinden sich bei mir alle Git-Projekte meines Firmen-Accounts. Unter ~/Developer/GitHub.com/Privat/ dementsprechen meine Git-Projekt von meinem Privaten-Account. Nun lege ich in jedem Ordner noch die oben definierte .gitconfig an

cd ~/Developer/GitLab.com/Firma/
nano .gitconfig

Dort hinterlege ich nun die Konfiguartionen für die Firmen-Git-Projekte:

[user]
        # GitHub hinterlege Email einfügen
        email = [email protected]
        # Name einfügen
        name = Max Mustermann
        # GitHub Username einfügen
        username = meinusername
[github]
        # GitHub Username einfügen
        user = "meinusername"

Nun kontrolliere ich noch ob alle Konfigurationen verfügbar sind. Dafür wechsele ich in ein bereits geclontes Projekt und überprüfe die Konfiguration:

cd ~/Developer/GitLab.com/Firma/project
git config --list

Das Ergebnis sollte so aussehen:

credential.helper=osxkeychain
includeif.gitdir:~/Developer/GitHub.com/Privat/.path=~/Developer/GitHub.com/Privat/.gitconfig
[email protected]
user.name=Max Mustermann
user.username=meinusername
github.user=meinusername
includeif.gitdir:~/Developer/GitHub.com/Firma/.path=~/Developer/GitHub.com/Firma/.gitconfig
core.excludesfile=~/.gitignore_global
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
[email protected]:firma/project.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

So erspare ich mir beim clonen eines Git-Repositories, dass ich immer die .git/config um Email und Benutzername ergänzen muss (wie bei der einfachen Methode).

Quelle

Dies ist eine Kopie meines deutschen Beitrages den ich in meinem Blog geschrieben habe: https://psycho0verload.it/2022/05/22/mehrere-ssh-schluessel-fuer-verschiedene-github-konten-auf-macos-monterey-12-4/

Copyrights

Flagge Icons erstellt von Freepik - Flaticon

  • American Flag
  • Deutsche Flagge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment