# SSH Key Distribution

To support SSH authentication securely to a large set of hosts running SSH, we support distribution
of SSH public keys via the Kanidm server. Both persons and service accounts support SSH public keys
on their accounts.

## Configuring Accounts

To view the current SSH public keys on accounts, you can use:

```bash
kanidm person|service-account \
    ssh list-publickeys --name <login user> <account to view>
kanidm person|service-account \
    ssh list-publickeys --name idm_admin william
```

All users by default can self-manage their SSH public keys. To upload a key, a command like this is
the best way to do so:

```bash
kanidm person|service-account \
    ssh add-publickey --name william william 'test-key' "`cat ~/.ssh/id_ecdsa.pub`"
```

To remove (revoke) an SSH public key, delete them by the tag name:

```bash
kanidm person|service-account ssh delete-publickey --name william william 'test-key'
```

## Security Notes

As a security feature, Kanidm validates _all_ public keys to ensure they are valid SSH public keys.
Uploading a private key or other data will be rejected. For example:

```bash
kanidm person|service-account ssh add-publickey --name william william 'test-key' "invalid"
Enter password:
  ... Some(SchemaViolation(InvalidAttributeSyntax)))' ...
```

## Server Configuration

### Public Key Caching Configuration

If you have `kanidm_unixd` running, you can use it to locally cache SSH public keys. This means you
can still SSH into your machines, even if your network is down, you move away from Kanidm, or some
other interruption occurs.

The `kanidm_ssh_authorizedkeys` command is part of the `kanidm-unix-clients` package, so should be
installed on the servers. It communicates to `kanidm_unixd`, so you should have a configured
PAM/nsswitch setup as well.

You can test this is configured correctly by running:

```bash
kanidm_ssh_authorizedkeys <account name>
```

If the account has SSH public keys you should see them listed, one per line.

To configure servers to accept these keys, you must change their /etc/ssh/sshd_config to contain the
lines:

```text
PubkeyAuthentication yes
UsePAM yes
AuthorizedKeysCommand /usr/sbin/kanidm_ssh_authorizedkeys %u
AuthorizedKeysCommandUser nobody
```

Restart sshd, and then attempt to authenticate with the keys.

It's highly recommended you keep your client configuration and sshd_configuration in a configuration
management tool such as salt or ansible.

> [!NOTE]
>
> With a working SSH key setup, you should also consider adding the following `sshd_config` options
> as hardening.

```text
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
GSSAPIAuthentication no
KerberosAuthentication no
```

### Direct Communication Configuration

In this mode, the authorised keys commands will contact Kanidm directly.

> [!NOTE]
>
> As Kanidm is being contacted directly there is no SSH public key cache. Any network outage or
> communication loss may prevent you accessing your systems. You should only use this version if you
> have a requirement for it.

The `kanidm_ssh_authorizedkeys_direct` command is part of the kanidm-clients package, so should be
installed on the servers.

To configure the tool, you should edit /etc/kanidm/config, as documented in
[clients](../client_tools.md)

You can test this is configured correctly by running:

```bash
kanidm_ssh_authorizedkeys_direct -D anonymous <account name>
```

If the account has SSH public keys you should see them listed, one per line.

To configure servers to accept these keys, you must change their /etc/ssh/sshd\_config to contain
the lines:

```text
PubkeyAuthentication yes
UsePAM yes
AuthorizedKeysCommand /usr/bin/kanidm_ssh_authorizedkeys_direct -D anonymous %u
AuthorizedKeysCommandUser nobody
```

Restart sshd, and then attempt to authenticate with the keys.

It's highly recommended you keep your client configuration and sshd\_configuration in a
configuration management tool such as salt or ansible.
