204 lines
8.4 KiB
Markdown
204 lines
8.4 KiB
Markdown
# 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)) *(Rivest–Shamir–Adleman)*
|
||
: `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.
|
||
|
||
---
|