Skip to content

Instantly share code, notes, and snippets.

@ziritrion
Last active May 13, 2024 17:24
Show Gist options
  • Save ziritrion/9b445926fb5d8b65194946c7e2ee9074 to your computer and use it in GitHub Desktop.
Save ziritrion/9b445926fb5d8b65194946c7e2ee9074 to your computer and use it in GitHub Desktop.
SSH keys for Github and logging in to servers

How to handle SSH keys for multiple Github accounts and making it more convenient to login to servers.

Generate SSH keys

This is the first step for all other steps in this file. While using a single key per device is usually the best option, there are instances when you need to have multiple keys in order to be able to identify as separate users.

On your local computer, generate keys with the following command:

ssh-keygen -t ed25519 -C "your_email@example.com" -f "filename"
  • -t ed25519 will force the Ed25519 algorithm for the keys. If you do not use this option, ssh-keygen will default to rsa, which is considered insecure.
  • -C stands for "comment", in order to help you identify your key. Using your email is useful to identify the user associated with this key, but you may use anything else.
  • -f "filename" stand for the file name where the ssh key will be saved to. You may want to name your key according to its intended use, such as "github-username".

You will be prompted to create a passphrase for the keys. You can just press Enter to leave it blank, or you can type anything you like. Keep in mind that if you do set a passphrase, you will have to enter it everytime you use the key, which can get annoying fast depending on the usecase.

This command will create 2 files: filename (private key) and filename.pub (public key). DO NOT SHARE filename WITH ANYONE.

You may need to add the private key to your local SSH agent.

  1. (Optional) Start the SSH agent in background mode
    • eval "$(ssh-agent -s)"
  2. Add the private key to ssh-agent
    • ssh-add ~/.ssh/filename

Log in to a remote server with your SSH key

In order to login to a remote server without a password, you need to do the following:

  1. Upload the SSH public key to the server
    1. With ssh-copy-id. This will automatically do all of the required steps in the remote server. Run this locally:
      ssh-copy-id -i ~/.ssh/filename username@remote_host
    2. If ssh-copy-id doesn't work but you can log in with SSH, you can run this line to perform all of the necessary steps:
      cat ~/.ssh/filename.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
    3. If you cannot login via SSH but you have other means of logging in, you can manually copy the public key:
      1. Run cat ~/.ssh/filename.pub locally to display the public key. Copy the output.
      2. In the remote server, make sure that ~/.ssh exists with mkdir -p ~/.ssh. This will create the folder if it doesn't exist.
      3. Add the public key to the authorized keys in the remote server with echo contents_of_your_public_key >> ~/.ssh/authorized_keys
  2. Authenticate the server with the SSH key.
    • Simply login normally with ssh: ssh username@remote_host.
    • If it's your first time logging in to the server via SSH, the server's ECDSA key fingerprint will be displayed and you will be prompted to accept it and continue connecting. Type yes and press Enter.
  3. (Optional) Disable password authentication on the server.
    1. In the remote server, edit the SSH daemon's config file with sudo privileges
      sudo nano /etc/ssh/sshd_config
    2. Search for the line with PasswordAuthentication and set it to no:
      PasswordAuthentication no
    3. Restart the SSH service. On most Linux distros you may do so with the following command:
      sudo systemctl restart ssh

Add public key to Github for using git with ssh

  1. Go to https://github.com/settings/keys and click on "New SSH key"
  2. Give it any title you want. You may want to reference the device in which the private key resides.
  3. Select "Authentication Key".
  4. Copy your public key within the "Key" field. You may run cat ~/.ssh/filename.pub locally, then copy the output of the command and paste it into the Key field.

Use multiple SSH keys locally for multiple Github accounts - easy way

The easy way of handling multiple Github accounts locally makes use of .gitconfig files in separate folders, one folder per user profile, so that all project folders hosted within one of these folders will be associated with a specific account, and a global .gitconfig in your home folder.

For example purposes, it will be assumed that you are interested in handling a personal account and a work account. Your local environment will end up looking like this:

~
├── .gitconfig <-- global
└── dev_folder/
   ├── personal/
   │   ├── project_1/
   │   ├── project_2/
   │   ├── project_#/
   │   └── .gitconfig <-- personal account
   └── work/
       ├── project_1/
       ├── project_2/
       ├── project_#/
       └── .gitconfig <-- work account

It will also be assumed that you've already created 2 separate SSH key pairs (whose filenames will be ssh_key_personal and ssh_key_work) and that you've already added the public keys to your respective Github accounts. Make sure that you change paths and folder names accordingly.

  1. (Optional) If you already have a global .gitconfig file, you might want to delete all global credential and user configurations. Run git config --edit --global to open an editor and remove all [credential] and [user] configurations to do so.
  2. Create a .gitconfig file for your personal folder:
    # ~/dev_folder/personal/.gitconfig
    [credential]
        username = <github-user>
    [user]
        name = <github-user>
        email = <github-user>@users.noreply.github.com
    [core]
        sshCommand = ssh -i ~/.ssh/ssh_key_personal -F /dev/null
  3. Create a .gitconfig file for your work folder:
    # ~/dev_folder/work/.gitconfig
    [credential]
        username = <user>
    [user]
        name = <First and last names>
        email = <user>@company.org
    [core]
        sshCommand = ssh -i ~/.ssh/ssh_key_work -F /dev/null
  4. Edit your global git config by running git config --edit --global and adding the following lines:
    # ~/.gitconfig
    [includeIf "gitdir/i:~/dev_folder/personal/"]
        path = ~/dev_folder/personal/.gitconfig
    
    [includeIf "gitdir/i:~/dev_folder/work/"]
        path = ~/dev_folder/work/.gitconfig

You will now have a specific git config per path, which allows you to create or clone projects within your personal or work profile paths without dealing with manual configurations.

Use multiple SSH keys locally for multiple Github accounts - annoying way

If the folder setup above does not work for your use case, you may use a config file for SSH that will contain host aliases that will allow you to clone projects with whichever account you need regardless of the parent folder, at the expense of having to remember which host you need to use depending on the project and account.

For example purposes, it will be assumed that you've already created 2 separate SSH key pairs (whose filenames will be ssh_key_personal and ssh_key_work) and that you've already added the public keys to your respective Github accounts. Make sure that you change paths and folder names accordingly.

  1. Create or modify the ~/.ssh/config file and add the following contents below:
    # personal account
    Host github.com-personal
        HostName github.com
        User git
        IdentityFile ~/.ssh/ssh_key_personal
    
    # work account
    Host github.com-work
        HostName github.com
        User git
        IdentityFile ~/.ssh/ssh_key_work
    
  2. When cloning a project, make sure that you change the host to the one you need based on the account you want to use
    • For example, if you want to clone the https://github.com/andrewagain/calculator project with your personal account, change the github.com domain to github.com-personal
      • Original git clone command: git clone git@github.com:andrewagain/calculator.git
      • Modified command: git clone git@github.com-personal:andrewagain/calculator.git

References

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