ittavern.com/items/2022-12-14_long_ssh-how-to-use-public-key-authentication-on-linux.md
2025-10-27 20:12:00 +01:00

204 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SSH - How to use public key authentication on Linux
**Disclaimer**:
* Please read the whole post before you start. This will help you avoid a lock-out
## Generating a secure key pair
SSH keys use asymmetric cryptographic algorithms that generate a pair of separate keys (a key pair). A private and a public key.
We are using the command `ssh-keygen` to generate our secure key pair. There are 3 common algorithms to choose from.
We are going to create a private and public key with the name `nameofthekey` in the `.ssh` directory of the current user. You should choose a expressive name, which makes it easier to work with multiple keys. Please make sure that the directory `~/.ssh/` exists.
**Important**: Please do use a secure password for the key generation.
[RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) *(RivestShamirAdleman)*
: `ssh-keygen -t rsa -b 4096 -f ~/.ssh/nameofthekey`
[ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) *(Elliptic Curve Digital Signature Algorithm)*
: `ssh-keygen -t ecdsa -b 521 -f key1 ~/.ssh/nameofthekey`
[EdDSA ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519):
: `ssh-keygen -t ed25519 -f ~/.ssh/nameofthekey`
Explanation:
: `ssh-keygen` # can be run as a standard user, man ssh-keygen for more information
: `-t [dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]` *# choose Algorithm*
: `-b bits` *# number of bits to use*
: `-f /path/and/name-of-keypair` *# choose a name for the keys*
```markdown
ssh-keygen -t rsa -b 4096 -f ~/.ssh/nameofthekey
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in name
Your public key has been saved in name.pub
The key fingerprint is:
SHA256:8KkCBz2GFXusy6URXF4Z/8xVl+6dFhYV0MoDtqIqBfA kuser@pleasejustwork
The key's randomart image is:
+---[RSA 4096]----+
| o.. oo .o.B|
| . = = ... o =.|
| = B = o + + .|
| E = o o = = + |
| . = . S . + + +|
| + * o +.|
| * o . |
| . o |
| . |
+----[SHA256]-----+
```
This would give us 2 files: private key `nameofthekey`, and public key `nameofthekey.pub`.
**nameofthekey.pub** - public key
Example:
```markdown
ssh-rsa ktLfCNsABzCw9wE4U3JS8mn1t8jw2Q01wRvCaexpuE2adZYxgw4sNJfBOp3SmLEYeF3rcP1u9ffb2J8FOqFWj3egwjVvVrlDHwi6Jr1aTxOmNlGtNHfJiKuJxD3HxPFAuSImsR5IZF6Bki0LxQGxM4jx8NgDFQ5BWO0tJ0pNzSJdXOLwW0jqbdqdEHELnYZLmll6oeJ9j1LZx6GY5vjYxzeCxZTrHoFQPE2vdYsx7ajIKDzQpNdM9zhYRO10OM kuser@pleasejustwork
```
**nameofthekey** - private, password protected
Example:
```markdown
-----BEGIN OPENSSH PRIVATE KEY-----
iEnCTyTmiYVhFvUIYhlq07FZV3EaVpQalFqSRicpeaDqifcDLqdp5NAx11JT17iNhgRDMrTM7Pcs6kLFbXC8LWbhlJVTkhu9k5wIG9Ec6qBthyAzmnO7SpqFCtKAXmuG8uFJF9SeyLsXTFiIuK8UqfgG9SLvXSrhPFqSVWFVxQqmXiXL5MQ7iKOKAAAlwisfwrJ1DTNkd2C9nel7sorAU3gWQGh2beuEjzkRsYucR9lxO6jzLEejNSwyS7TNuOiEnCTyTmiYVhFvUIYhlq07FZV3EaVpQalFqSRicpeaDqifcDLqdp5NAx11JT17iNhgRDMrTM7Pcs6kLFbXC8LWbhlJVTkhu9k5wIG9Ec6qBthyAzmnO7SpqFCtKAXmuG8uFJF9SeyLsXTFiIuK8UqfgG9SLvXSrhPFqSVWFVxQqmXiXL5MQ7iKOKAAAlwisfwrJ1DTNkd2C9nel7sorAU3gWQGh2beuEjzkRsYucR9lxO6jzLEejNSwyS7TNuO
-----END OPENSSH PRIVATE KEY-----
```
## The correct permissions on the client
It is important to have the correct permissions for your key. For 2 reasons: restrict the access of other users, and some servers require it, when the 'StrictModes' is enabled. Later more.
```
sudo chmod 700 ~/.ssh
sudo chmod 644 ~/.ssh/authorized_keys
sudo chmod 644 ~/.ssh/known_hosts
sudo chmod 644 ~/.ssh/config
sudo chmod 600 ~/.ssh/nameofthekey # private key
sudo chmod 644 ~/.ssh/nameofthekey.pub # public key
```
## Get your public key on the server
You need access to the destination server in one way or another to add the newly generated **public** key. There are multiple ways.
In the end, the public key must be added to the `~/.ssh/authorized_keys` file. If it does not exist, it must be created. There can be multiple public keys in this file - one line per key, and there can be multiple `authorized_keys`, IF it is configured on the server.
#### No direct access to the server
Ask someone with access to add your public key to the `~/.ssh/authorized_keys` file.
#### Direct access via ssh and password auth
You most likely already have access to the server via ssh and normal password authentication. There are now multiple ways to add your public key to the server.
Simply use `ssh-copy-id`:
: `ssh-copy-id -i ~/.ssh/nameofthekey.pub remote-user@remote-server`
: This does everything for you, and adds your public key to the `authorized_keys` file on the remote machine.
Different way would be to copy the public key to the remote machine via `scp` / `rsync`, or something different, and redirect `>>` it to `~/.ssh/authorized_keys`. Another way would be to connect to the server, and copy-paste the content of the public key to `~/.ssh/authorized_keys`. Remember, if the path or file does not exist, just create it.
In the end, your chosen public key must be in the file `~/.ssh/authorized_keys` before you should continue.
## Configuration of the ssh server
**Important**: Some tips on how to work on the configuration file on the remote machine.
* do a backup of the configuration file before you do any changes!
* create 2 ssh sessions - 1 for working and testing, the other one as a backup.
* reload the config of the ssh server, rather than restarting the service. This does not kill the backup session.
* test the public key authentication before you turn off password authentication
---
We now have to edit the ssh server config file on the remote machine: `/etc/ssh/sshd_config` or in the config directory `/etc/ssh/sshd_conf.d`. It depends on your setup.
#### Enabling public key authentication on the server
Enable public key authentication in the config file:
: `PubkeyAuthentication yes`
Now, reload the config of the ssh server. Assuming you are using `systemd`:
: `sudo systemctl reload sshd`
Before we continue, please do try to connect to the remote machine with your ssh key:
: `ssh -i ~/.ssh/nameofthekey remote-user@remote-server` *# choose the private key!*
: enter the password for your private key, and you should be connected.
#### Enable the strict mode
Open the `sshd_config` file and add:
: `StrictModes yes`
: this makes sure, that the permissions are correct on the client side. You won't be able to connect to the server, if the permissions are not correct!
Now, reload the config of the ssh server:
: `sudo systemctl reload sshd`
**Important**: Please test the connection once more!
If you successfully connected to the remote machine, you can proceed to turn off password authentication.
#### Disable password authentication
**Last chance**: make sure that you have tested the public key authentication, and / or have another option to access the machine.
Open the `sshd_config` file and change one option:
: `PasswordAuthentication no`
This will disable the possibility to authenticate with a password, but you should still be able to log in with your public key, after reloading the config.
Reload the config of the ssh server:
: `sudo systemctl reload sshd`
**This should be it!**
[More SSH hardening options can be found here.](https://ittavern.com/ssh-server-hardening/)
## Debugging
Some debugging options on client:
: `-v` / `-vv` / `-vvv`
: `ssh -vvv -i ~/.ssh/nameofthekey remote-user@remote-server`
Some debugging options on server:
: `sudo journalctl -u ssh`
: `sudo grep ip.of.your.machine /var/log/auth.log`
You can change the log level of the server by editing the config file:
: `LogLevel INFO` *# default*
: `LogLevel DEBUG` *# enable DEBUG mode*
Don't forget to turn it off again before it fills up your storage.
## Manage private key identities with an agent
Nobody wants to enter their password for the private key every time they want to connect to a server. By using `ssh-add` - the OpenSSH auth agent - you can add your private key once for the session, and do not have to enter your private key password every time.
Check for identities:
: `ssh-add -L`
Add private key identity:
: `ssh-add ~/.ssh/nameofthekey` *# choose the private key and enter the password*
Remove all identities:
: `ssh-add -D`
#### Troubleshooting
If you run into:
: `Could not open a connection to your authentication agent.`
Just run `eval "$(ssh-agent)"` OR `` `eval ssh-agent` `` and right after `exec ssh-agent bash`. This restarts the agent and sets the correct environment variables from my understanding.
---