# OpenSSH/Client Configuration Files

Client configuration files can be per user or system wide, with the
former taking precedence over the latter and run-time arguments in the
shell overriding both. In these configuration files, one parameter per
line is allowed. The syntax is the parameter name followed by its value
or values. Empty lines and lines starting with the hash (**\#**) are
ignored. An equal sign (**=**) can be used instead of whitespace between
the parameter name and the values. Values are case-sensitive, but
parameter names are not. The first value assigned is used. For key
files, the format is different.

With either type of file, there is no substitute for reading the
relevant manual pages on the actual systems involved, especially because
they match the specific versions which are in use.

## System-wide Client Configuration Files

System-wide client files set the default configuration for all users of
OpenSSH clients on that system. These defaults can be overridden in most
cases by the user\'s own default settings in a local configuration file.
Both can be overridden, in many cases, by specifying various options or
parameters at run time. The prioritization is as follows:

1.  run time arguments via the shell
2.  user\'s own configuration
3.  system-wide configuration

The first value obtained is used. The user\'s own configuration file and
the system-wide configuration file can also point to additional
configuration files to be included using the **Include** directive
starting with OpenSSH 7.3. The **Include** directive can be specified
anywhere in the configuration file even inside a **Match** or **Host**
block. Care should be used when nesting configurations.

### */etc/ssh/ssh_config*

This file defines all the default settings for the client utilities for
all users on that system. It must be readable by all users. The
configuration options are described in detail in
ssh_config(5).

Below a shortcut is made for connecting to *arc.example.org*.

``` {.apache .numberLines}
Host arc
        Port 2022
        HostName arc.example.org
        User fred
        IdentityFile ~/.ssh/id_rsa_arc
```

So with that configuration, it is enough to enter `ssh arc` and the rest
of the information gets filled in automatically.

### */etc/ssh/ssh_known_hosts*

This contains the system-wide list of known host keys used to verify the
identity of the remote host and thus hinder impersonation or
eavesdropping. This file should be prepared by the system administrator
to contain the public host keys of all necessary hosts. It should be
world-readable.

See **\~/.ssh/known_hosts** below for more explanation or see
sshd(8) for further details of the
format of this file.

### */etc/ssh/sshrc*

This file resides on the server and programs in this file are executed
there by ssh(1) when the user logs in,
just before the user\'s shell or designated program is started. It is
not run as root, but instead as the user who is logging in. See the
sshd(8) manual page in the section
\"SSHRC\" for more information. If it sends anything to **stdout** that
will interfere with SFTP sessions, among others. So if any output is
produced at all, it should be sent to **stderr** or else a log file.

## User-specific Client Configuration Files

Users can override the default system-wide client settings and choose
their own defaults. For situations where the same change is made
repeatedly it is recommended to add it to the user\'s local
configuration.

### Client-Side Files

These files reside on the client machine.

#### *\~/.ssh/config*

The user\'s own configuration file which, where applicable, overrides
the settings in the global client configuration file,
**/etc/ssh/ssh_config**. The configuration options are described in
detail in ssh_config(5).

This file must *not* be accessible to other users in any way. Set strict
permissions: read/write for the user, and not accessible by others. It
may group-writable if and only if that user is the only member of the
group in question.

##### Local Override of Client Defaults

The file is usually named **\~/.ssh/config**. However, a different
configuration file can be specified at runtime using the **-F** option.
General options intended to apply to all hosts can be set by matching
all hosts and should be done at the end of the configuration file. The
first match takes precedence, therefore more specific definitions must
come first and more general overrides at the end of the file.

``` {.apache .numberLines}
Host server1
        ServerAliveInterval 200
        HostName    203.0.113.76

Host *
        ExitOnForwardFailure    yes
        Protocol    2
        ServerAliveInterval 400
```

Options given as runtime arguments will override even those in the
configuration file. However, not all options can be set or overriden by
the user. Those options which may not be set or overridden will be
ignored.

#### *\~/.ssh/known_hosts*

This file is local to the user account and contains the known keys for
remote hosts. Often these are collected from the hosts when connecting
for the first time, but they can be added manually. As with those keys
stored in the global file, **/etc/ssh/ssh_known_hosts**, these keys are
used to verify the identity of the remote host, thus protecting against
impersonation or man-in-the-middle attacks. With each subsequent
connection the key will be compared to the key provided by the remote
server. If there is a match, the connection will proceed. If the match
fails, ssh(1) will fail with an error
message. If there is no key at all listed for that remote host, then the
key\'s fingerprint will be displayed and there will be the option to
automatically add the key to the file. This file can be created and
edited manually, but if it does not exist it will be created
automatically by ssh(1) when it first
connects to a remote host.

The **\~/.ssh/known_hosts** file can use either hashed or clear text
host names. Even with hashed names, it can still be searched using
ssh-keygen(1) using the **-F**
option.

``` shell
$ ssh-keygen -F server3.example.com 
```

The default file to be searched will be **\~/.ssh/known_hosts** and the
key is printed if found. A different file can be searched using the
**-f** option. If a key must be removed from the file, the **-R** option
works similarly to search by host and then remove it if found even if
the host name is hashed.

``` shell
$ ssh-keygen -R server4.example.com -f ~/.ssh/known_hosts
```

When a key is removed, it will then be appended to the file
**\~/.ssh/known_hosts.old** in case it is needed later. Again, see the
manual page for sshd(8) for the format
of these **known_host** files.

If a non-default file is used with either **-F** or **-R** then the name
including the path must be specified using **-f**. But **-f** is
optional if the default file is intended.

If the global file **/etc/ssh/ssh_known_hosts** is used then it should
be prepared by the system administrator to contain the public host keys
of all necessary hosts and it should be world-readable.

##### Manually Adding Public Keys to \~/.ssh/known_hosts

Manually adding public host keys to **known_hosts** is a matter of
adding one unbroken line per key. How the key is obtained is not
important, as long as it is complete, valid, and **guaranteed to be the
real key and not a fake**. The utility
ssh-keyscan(1) can fetch a key
and ssh-keygen(1) can be used to
show the fingerprint for verification. See examples in the cookbook
chapter on  Public Key
Authentication
for methods of verification. Again, the corresponding system-wide file
is **/etc/ssh/ssh_known_hosts**

##### About the Contents of the known_hosts Files

The **known_hosts** file is for verifying the identity of other systems.
ssh(1) can automatically add keys to the
user\'s file, but they can be added manually as well. The file contains
a list of public keys for all the hosts which the user has connected to.
It can also include public keys for hosts that the user plans to log
into but are not already in the system-wide list of known host keys.
Usually when connecting to a host for the first time,
ssh(1) adds the remote host\'s public
key to the user\'s **known_hosts** file, but this behavior can be tuned.

The format is one public key or certificate per unbroken line. Each line
in contains a host name, number of bits, exponent, and modulus. At the
beginning of the line is either the host name or a hash representing the
host name. An optional comment can follow at the end of the line. These
can be preceded by an optional marker to indicate a certificate
authority, if an SSH certificate is used instead of a SSH key. These
fields are separated by spaces. It is possible to use a comma-separated
list of hosts in the host name field if a host has multiple names or if
the same key is used on multiple machines in a server pool. Here are two
examples for hosts with the basic host names:

    anoncvs.fr.openbsd.org,93.184.34.123 ssh-rsa AAAA...njvPw== 
    anoncvs.eu.openbsd.org ssh-rsa AAAAB3Nz...cTqGvaDhgtAhw==

Non-standard ports can be indicated by enclosing the host name with
square brackets and following with a colon and the port number. Here are
three examples referring to hosts listening for SSH on non-standard
ports:

       
    [ssh.example.org]:2222 ssh-rsa AAAAB3Nz...AKy2R2OE= 
    [127.0.0.2]:4922 ssh-rsa AAAAB4mV...1d6j=   
    [anga.funkfeuer.at]:2022,[78.41.115.130]:2022 ssh-rsa AAAAB...fgTHaojQ==    

Host name patterns can be created using \"**\***\" and \"**?**\" as
wildcards and \"**!**\" to indicate negation.

Up to one optional marker per line is allowed. If present it must be
either **\@cert-authority** or **\@revoked**. The former shows that the
key is a certificate authority key, the latter flags the key as revoked
and not acceptable for use.

See sshd(8) for further details on the
format of this file and
ssh-keygen(1) for managing the
keys.

### Server-Side Client Files

These client files reside on the server. By default they are kept in the
user\'s directory. However, the server can be configured to look for
them in other locations if needed.

#### *\~/.ssh/authorized_keys*

**authorized_keys** is a one-key-per-line register of public ECDSA, RSA,
and ED25519 keys that this account can use to log in with. The file\'s
contents are not highly sensitive, but the recommended permissions are
read/write for the user and not accessible by others. As always, the
whole key including options and comments must be on a single, unbroken
line.

    ssh-rsa AAAAB3NzaC1yc2EAAA...41Ev521Ei2hvz7S2QNr1zAiVaOFy5Lwc8Lo+Jk=

Lines starting with a hash (#) are ignored and can be used as comments.
Whitespace separates the key\'s fields, which are in sequence an
optional list of login options, the key type (usually ssh-rsa or better
like ecdsa-sha2-nistp256), the key itself encoded as base64, and an
optional comment.

If a key is followed by an annotation, the comment does not need to be
wrapped in quotes. It has no effect on what the key does or how it
works. Here is an annotated key, the comment having been generated with
the **-C** option ssh-keygen(1):

    ssh-rsa AAAAB3NzaC1yc2EAAA...zAiVaOFy5Lwc8Lo+Jk=  Fred @ Project FOOBAR

Keys can be preceded by a comma-separated list of options to affect what
happens upon successful login. The first key below forces the session to
launch **tinyfugue** automatically, the second forcibly sets the PATH
environment variable:

    command="/usr/bin/tinyfugue" ssh-rsa AAAAB3NzaC1yc2EAAA...OFy5Lwc8Lo+Jk=
    environment="PATH=/bin:/usr/bin/:/opt/gtm/bin" ssh-rsa AAAAB3N...4Y2t1j=

The format of **authorized_keys** is described in the
sshd(8) manual page. Old keys should be
deleted from the file when no longer needed. The server can specify
multiple locations for **authorized_keys**. See the next section,
Server-Side Client Key Login
Options, for details.

#### *\~/.ssh/authorized_principals*

By default this file does not exist. If it is specified in
sshd_config(5), it contains a
list of names which can be used in place of the username when
authorizing a certificate. This option is useful for role accounts,
disjoint account namespaces and \"user@realm\"-style naming policies in
certificates. Principals can also be specified in **authorized_keys**.

#### *\~/.ssh/environment*

If the server is configured to accept user-supplied, automatic changes
to environment variables as part of the login process, then these
changes can be set in this file.

If the server, the environment file and an authorization key all try to
change the same variable, the file **environment** takes precedence over
what a key might contain. Either one will override any environment
variables that might have been passed by
ssh(1) using **SendEnv**.

Authentication keys stored in **authorized_keys** can also be used to
set variables. See also the **AcceptEnv** and **PermitUserEnvironment**
directives in the manual page for
sshd_config(5).

#### *\~/.ssh/rc*

This is a script which is executed by
sh(1) just before the user\'s shell or
command is started. It is not run if **ForceCommand** is used. The
script is run after reading the environment variables. The corresponding
global file, **/etc/ssh/sshrc**, is not run if the user\'s **rc** script
exists.

### Local Account Public / Private Key Pairs

People might have a variety ECDSA, Ed25519, and RSA keys stored in the
file system. Since version 8.2, two new key types ECDSA-SK and
Ed25519-SK, along with corresponding certificate types are available for
keys tied to FIDO/U2F tokens. Though individual accounts can maintain
their own list of keys or certificates for authentication or to verify
the identity of remote hosts in any directory, the most common location
is in the **\~/.ssh/** directory. The naming convention for keys is only
a convention but recommended to follow anyway. Public keys usually have
the same name as the private key, but with **.pub** appended to the
name. Trouble can arise if the names of the public and private keys do
not match. If there is more than one key pair, then
ssh-keygen(1) can use the **-f**
option when generating keys to produce a useful name along with the
**-C** option which embeds a relevant comment inside the key pair.

People, programs, and scripts can authenticate using a private key
stored on the system, or even a private key fetched from a smartcard, if
the corresponding public key is stored in **authorized_keys** on the
remote system. The **authorized_keys** file is not highly sensitive, but
the recommended permissions are read/write for the user, and not
accessible by others. The private keys, however, are very sensitive and
should not be readable or even visible to other accounts. They should
never leave the client and should certainly never be put on the server.
See the chapter on  Public Key
Authentication
for more discussion and examples.

The keys can be preceded by a comma-separated list of options. The whole
key must be on a single, unbroken line. No spaces are permitted, except
within double quotes. Any text after the key itself is considered a
comment. The **authorized_keys** file is a one-key-per line register of
public RSA, Ed25519, ECDSA, Ed25519-SK, and ECDSA-SK keys that can be
used to log into a particular account. See the section above on the
**authorized_keys** file for more discussion.

DSA is considered deprecated. The time has passed for DSA keys and they
are no longer considered safe and should be replaced with better keys.

Per-account  Host-based Authentication
Configuration is
also possible using the **\~/.shosts**, **\~/.rhosts**,
**\~/.ssh/environment**, and **\~/.ssh/rc** files.

#### Public Keys: \~/.ssh/id_ecdsa.pub \~/.ssh/id_ed25519.pub \~/.ssh/id_rsa.pub \~/.ssh/id_ecdsa-sk.pub \~/.ssh/id_ed25519-sk.pub \~/.ssh/id_ecdsa-sk_rk.pub \~/.ssh/id_ed25519-sk_rk.pub

These are only the default names for the public keys. Again, it can be a
good idea to give more relevant names to keys. The **\*-sk.pub** keys
are those bound with a hardware security token and the **\*-sk_rk.pub**
keys are those generated from resident keys stored within hardware
security token.

Public keys are mainly used on the remote server for key-based
authentication. Public keys are not sensitive and are allowed to be
readable by anyone, unlike the private keys, but don\'t need to be. A
public key, minus comments and restriction options, can be regenerated
from a private key if lost. So while it can be useful to keep backups of
the public key, it is not essential unlike for private keys.

#### Private Keys: \~/.ssh/id_ecdsa \~/.ssh/id_ed25519 \~/.ssh/id_rsa \~/.ssh/id_ecdsa-sk \~/.ssh/id_ed25519-sk \~/.ssh/id_ecdsa-sk_rk \~/.ssh/id_ed25519-sk_rk

These are only the default names for private keys. Private keys are
always considered sensitive data and should be readable only by the user
and not accessible by others. In other words, they use mode 0600. The
directory they are in should also have mode 0700 or 0500. If a private
key file is accessible by others, ssh(1)
will ignore it.

It is possible to specify a passphrase when generating the key which
will be used to encrypt the sensitive part of this file using AES128.
Until version 5.3, the cipher 3DES was used to encrypt the passphrase.
Old keys using 3DES that are given new passphrases will use AES128 when
they are modified.

Private keys stored in hardware tokens as resident keys can be extracted
and automatically used to generate their corresponding public key using
ssh-keygen(1) with the **-K**
option. Such keys will default to being named **id_ecdsa-sk_rk** or
**id_ed25519-sk_rk**, depending on the key type, though the file names
can be changed after extraction. A passphrase can be assigned to the
private key upon extraction from the token to a file.

While public keys can be generated from private keys, new private keys
cannot be regenerated from public keys if the private keys are lost. Nor
can a new passphrase be set if the current one is forgotten. Gone is
gone, unlike the public keys, which can be regenerated from an existing
private key if the private key is lost or forgotten then a whole new key
pair must be generated and deployed.

### Legacy Files

These files might be encountered on very old or out of date systems but
not on up-to-date ones.

#### *\~/.shosts*

#### *\~/.rhosts*

**.rhosts** is a legacy from rsh containing a local list of trusted
host-user pairs that are allowed to log in. Login requests matching an
entry were granted access.

See also the global list of trusted host-user pairs,
**/etc/hosts.equiv**

**rhosts** can be used as part of host-based authentication. Otherwise
it is recommended not to use rhosts for authentication, there are a lot
of ways to misconfigure the **.rhosts** file.

#### Legacy DSA Keys \~/.ssh/id_dsa \~/.ssh/id_dsa.pub

Deprecated DSA keys might be found named as **id_dsa** and
**id_dsa.pub**, but regardless of the name any usage should be tracked
down. Support for DSA both on the server and client was discontinued in
OpenSSH 7.0. If DSA keys are found, the pair should be removed and
replaced with a better type of key.

#### Legacy SSH1 Protocol Keys \~/.ssh/identity \~/.ssh/identity.pub

The files **identity** and **identity.pub** were for SSH protocol
version 1, and thus deprecated. If found they should be investigated as
to what, if anything, uses them and why. Then once any remaining usage
is resolved they should be removed and replaced with newer key types.

## Mapping Client Options And Configuration Directives

Many run-time options for the SSH client have corresponding
configuration directives and vice versa. The following is a quick
overview. It is not a substitute for getting familiar with the relevant
manual pages, ssh(1) and
ssh_config(5) which are the
relevant, authoritative, up-to-date resources on the matter.

  Directive                 Option    Description
  ------------------------- --------- ----------------------------------------------------------------------------------------------------
  AddressFamily             -4 / -6   Limit connections to IPv4 or IPv6 only.
  ForwardAgent              -A / -a   Forward or block forwarding from the authentication agent.
  BindInterface             -B        Bind the outgoing connection to this network interface.
  BindAddress               -b        Bind the outgoing connection to this network address.
  Compression               -C        Specify whether to compress the data using gzip(1).
  Ciphers                   -c        Specify which cipher to use.
  DynamicForward            -D        Designate a local port to be forwarded, say for SOCKS5.
  EscapeChar                -e        Specify an escape character for PTY sessions.
  ForkAfterAuthentication   -f        Drop client to background right before command execution.
  GatewayPorts              -g        Whether other hosts are allowed to connect to local forwarded ports.
  PKCS11Provider            -I        Specify the path to the shared PKCS#11 library.
  IdentityFile              -i        Specify a particular certificate or private key to use for authentication.
  ProxyJump                 -J        Connect to the destination via this host or hosts first.
  GSSAPIAuthentication      -K / -k   Enable or disable Generic Security Services Application Program Interface (GSSAPI) authentication.
  LocalForward              -L        Specify which local port or socket to forward to the specified remote system.
  User                      -l        Designate which account on the remote system to try.
  ControlMaster             -M        Allow multiplexing of SSH sessions over a single TCP connection.
  MACs                      -m        Designate which message authentication code (MAC) algorithms to try.
  SessionType               -N / -s   Invoke a designated subsystem or even prevent any command execution at all.
  StdinNull                 -n        Prevent reading from **stdin**.
  Tag                       -P        Tag for use within **Match**.
  Port                      -p        Connect to this port on the remote system.
  LogLevel                  -q / -v   Adjust the verbosity of logging messages from the client.
  RemoteForward             -R        Specify which remote port or socket to forward to the specified local system.
  ControlPath               -S        Designate the control socket for multiplexing over this connection.
  RequestTTY                -T / -t   Prohibit or request a pseudo-TTY for the session.
  ForwardX11                -X / -x   Enable or prohibit X11 forwarding.

  : Lookup Table of OpenSSH Client Options Versus Configuration
  Directives

As of version 8.7 the **-f**, **-N**, and **-n** options also have
corresponding client configuration directives in
ssh_config(5).

## Server-Side Client Key Login Options

The login options available for use in the local user authorized keys
file might be overridden or blocked by the server\'s own settings.
However, within that constraint, the following options can be used.

**cert-authority**

Specifies that the listed key is a certification authority (CA) trusted
to validate signed certificates for user authentication. Certificates
may encode access restrictions similar to key options. If both
certificate restrictions and key restrictions are present, then the most
restrictive union of the two is applied.

**command=\"*program*\"**

Specifies a program and its options to be executed when the key is used
for authentication. This is a good way of forcing a program to restrict
a key to a single, specific operation such as a remote backup. However,
TCP and X11 forwarding are still allowed unless explicitly disabled
elsewhere.

The program is run on a PTY if the client requests it, otherwise the
default is to run without a TTY. The default, running without a TTY,
provides an 8-bit clean channel. If the default has been changed,
specify **no-pty** to get an 8-bit clean channel. If no programs are
allowed, then use an empty string \"\" to prevent anything from running.

    no-pty,command="" ssh-rsa AAAAB3NzaC1yc2EAAA...OFy5Lwc8Lo+Jk=

If only one program is allowed, with specific options, then it can be
spelled out explicitly.

    restrict,command="/usr/bin/svnserve -t --tunnel-user=fred" ssh-ed25519 AAAAC3NzaC1lZDI1NT...skSUlrRPoLyUq

Quotes provided in the program\'s options must be escaped using a
backslash. (\'\\\')

    command="sh -c \"mysqldump db1 -u fred1 -p\"" ssh-rsa AAAAB3NzaC1yc...Lwc8OFy5Lo+kU=

This option applies to execution of the shell, another program, or a
subsystem. Thus any other programs specified by the user are ignored
when **command** is present. However, the program originally specified
by the client remains available as the environment variable
**SSH_ORIGINAL_COMMAND**. That can be used by a script in a
multiple-choice case statement, for example, to allow the account to
select from a limited range of actions.

**environment=\"*NAME*=*value*\"**

Sets the value of an environment variable when this key is used to log
in. It overrides default values of the variable, if they exist. This
option can be repeated to set multiple variables up to 1024 discrete
names. First match wins in the case of repetition. This option is only
allowed if the **PermitUserEnvironment** option is set in the SSH
server\'s configuration. The default is that it is disabled. This option
used to be disabled automatically when **UseLogin** was enabled, but
**UseLogin** has been deprecated.

**expiry-time=\"*timespec*\"**

Sets a date or date-time, either as a YYYYMMDD date or a
YYYYMMDDHHMM\[SS\], after which the key will not be allowed to
authenticate. Otherwise the key will be considered valid indefinitely.
The system time zone is used.

**from=\"*pattern-list*\"**

Either the canonical name of the remote host or its IP address required
in addition to the key. Addresses and host names can be listed using a
comma-separated list of patterns, see PATTERNS in
ssh_config(5) for more
information on patterns, or use the CIDR address/masklen notation.

**no-agent-forwarding / agent-forwarding**

This option forbids the authentication agent from forwarding the key
when it is used for authentication. Alternately, it allows agent
forwarding even if it was otherwise previously disabled by the
**restrict** option.

**no-port-forwarding / port-forwarding**

Forbids TCP forwarding and any port forward requests by the client will
return an error when this key is used for authentication. Alternately,
override the **restrict** option and allow port forwarding. See also
**permitopen**.

**no-pty / pty**

TTY allocation is prohibited and any request to allocate a PTY will
fail. Alternately, TTY allocation is permitted, even if previously
disabled by the **restrict** option.

**no-touch-required**

FIDO keys which have been created with the **-O no-touch-required** can
use this method which makes the client skip the check for user presence.

**no-user-rc / user-rc**

Use the **no-user-rc** option in **authorized_keys** to disable
execution of **\~/.ssh/rc**. Alternately, use **user-rc** to override
the **restrict** option.

**no-X11-forwarding / x11-forwarding**

Prevent X11 forwarding when this key is used for authentication and
requests to forward X11 will return an error. Alternately, override the
**restrict** option and allow X11 forwarding.

*\'permitlisten=\"\[*host*:\]*port\'\'\"

**permitopen=\"*host*:*port*\"**

The **permitlisten** setting limits remote port forwarding (`ssh -R`) to
only the specified port and, optionally, host. In contrast,
**permitopen** limits local port forwarding (`ssh -L`) to only the
specified host and port. IPv6 addresses can be specified with an
alternative syntax: host/port. Multiple **permitopen** or
**permitlisten** options may be used and must be separated by commas. No
pattern matching is performed on the specified host names, they must be
literal host names or IP addresses. Can be used in conjunction with
agent-forwarding.

**principals=\"*name1*\[,*name2*,\...\]\"**

Specify a list of names that may be used in place of the username when
authorizing a certificate trusted via the **TrustedCAKeys** option
described in sshd_config(5).

**restrict**

Disable all options, such as TTY allocation, port forwarding, agent
forwarding, user-rc, and X11 forwarding all at once. Specific options
can then be explicitly allowed on an individual basis.

**tunnel=\"*n*\"**

Select a specific tun(4) device on the
server. Otherwise when a tunnel device is requested without this option
the next available device will be used.

**verify-required**

Require user-verification, such as with a PIN, with FIDO keys.

## Managing Keys

When working with keys there are some basic, hopefully common sense,
actions that should take place to prevent problems. The two most
beneficial approaches are to use sensible names for the key files and to
embed comments. The **-f** option for
ssh-keygen(1) allows a custom
name to be set. The **-C** option allows a comment to be embedded in
both the public and private keys. With the comment inside the private
key, it can be regenerated automatically if a replacement public key is
ever made using the **-y** option.

Other than that, there are three main rules of thumb for managing keys:

-   Keys should use strong passphrases. If autonomous logins are
    required, then the keys should be first loaded into an agent and
    used from there. See ssh-add(1)
    to get started there. It uses
    ssh-agent(1) which many
    systems have installed and some have running by default.

```{=html}
<!-- -->
```
-   Keys should always be stored in protected locations, even on the
    client side. This is especially important for private keys. The
    private keys should not have read permissions for any user or group
    other than their owner. They should also be kept in a directory that
    is not accessible by anyone other than the owner in order to limit
    exposure.

```{=html}
<!-- -->
```
-   Old and unused keys should be removed from the server. In
    particular, keys without a known, valid purpose should be removed
    and not allowed to accumulate. Using the comment field in the public
    key for annotation can help eliminate some of the confusion as to
    the purpose and owner once some time has passed. Along those lines,
    keys should be rotated at intervals. Rotation means generating new
    key pairs and removing the old ones. This gives a chance to remove
    old and unused keys. It is also an opportunity to review access
    needs, whether access is required and if so at what level.

Following the principle of least privilege can limit the chance for
accidents or abuse. If a key is only needed to run a specific
application or script, then its login options should be limited to just
what is needed. See sshd(8) for the
\"AUTHORIZED_KEYS FILE FORMAT\" section on key login options. For root
level access, it is important to remember to configure **/etc/sudoers**
or **/etc/doas.conf** appropriately. Access there can be granted to a
specific application and even limit that application to specific
options.

One major drawback to keys is that they never expire and are valid
indefinitely in principle. In contrast, certificates can be assigned a
validity interval with an end date, after which they can no longer be
used.

 
