OpenSSH/Cookbook/The Client Configuration File
SSH Client Configuration Files
editUse of the client configuration file, ssh_config(5), is perhaps the most underrated and unrecognized feature, despite its great utility and flexibility. The configuration file can be used to create shortcuts for specific systems or scenarios by applying designated settings. The client, ssh(1), prioritizes settings applied at the command-line as run-time options. Then the settings from user's own configuration file, usually ~/.ssh/config, are applied. Then, finally, global client settings are applied, usually from the system-wide configuration file, /etc/ssh/ssh_config, if it exits. So as mentioned in the chapter on Client Configuration Files, the prioritization is as follows:
- run time arguments via the shell
- user's own configuration
- system-wide configuration
Even within the user's configuration file and the system's global configuration file, the first match is applied. Therefore specific configurations must always go towards the beginning of the file and more general settings towards the end.
Basics of SSH Client Configuration
editEach stanza in the configuration file begins with either a Host or Match directive. The directives within the stanza are then applied, if relevant. More on Match later. Below two hosts are each set up with their own shortcuts using a basic Host directive. The settings for the two hosts are followed by two more general stanzas applicable to two whole domains. Lastly is a stanza with applying IdentitiesOnly to all outgoing connections.
Host www
HostName www.example.org
User fred
IdentityFile %d/.ssh/fred.www.key
Host git
HostName git.example.org
User paz
IdentityFile %d/.ssh/paz.git.key
Host *.example.org
ConnectTimeout 2
AddKeysToAgent yes
Host *.example.com
ConnectTimeout 5
Port 2022
Host *
IdentitiesOnly yes
The specific configurations are first and get more general until the end where IdentitiesOnly gets applied to all outgoing sessions. Hosts in the example.org domain use the default SSH port of 22, while that is overridden for those in the example.com domain which uses port 2022 instead. Keys are automatically added to the agent when used with the example.org domain but not with the example.com domain.
The first host can be reached with ssh www
and the second host with ssh git
. In general, it is a good idea to set IdentitiesOnly so that only the one designated key is tried when authenticating. Otherwise, the keys are tried in whatever order they might be found in the agent which can be unpredictable. The result without IdentitiesOnly can be that the connection gets blocked from having too many failed logins attempts before the right key even gets tried.
Multiple Shortcuts
editEach stanza can have multiple shortcuts.
Host w www www.example.org
HostName www.example.org
User fred
IdentityFile %d/.ssh/example.org-fred.ed25519
Above, the same host can be reached with ssh w
, ssh www
, or ssh www.example.org
.
Different Keys for Different Accounts on the Same Systems
editSometimes it is necessary to access multiple accounts on the same remote system, each with a separate key. The Match block in ssh_config(5) can pair each account with its corresponding key.
Match host www.example.org user git
IdentityFile %d/.ssh/example.org-git.ed25519
Match host www.example.org user fred
IdentityFile %d/.ssh/example.org-fred.ed25519
Match host www.example.org user backup
IdentityFile %d/.ssh/example.org-backup.ed25519
Host www.example.org
IdentitiesOnly yes
AddKeysToAgent yes
Above, different keys are applied to the same remote host depending on which of the three accounts is used.
Automatically Fire Up Local VNC After Establishing A Tunnel
editThe LocalCommand directive can launch a local program upon successful authentication. If that is combined with other directives, there are a lot of possibilities. Here once a VNC tunnel gets established, the client is connected to it.
Host make-tunnel tunnel
Hostname 198.51.100.120
User tunneler
IdentitiesOnly yes
IdentityFile %d/.ssh/tunneler-vnc-tunnel
LocalForward 5900 localhost:5900
ExitOnForwardFailure yes
PermitLocalCommand yes
LocalCommand remmina -c vnc://localhost:0
The LocalForward creates the tunnel, while the PermitLocalCommand and LocalCommand connects the client to the tunnel once the tunnel is complete. Should the tunnel fail, ExitOnForwareFailure ensures that the SSH session ends so that the failure can be properly investigated rather than the client connected to nothing.
VNC Through A Jointly Accessible External Host - Approach One
editNetworking through one or more layers of NAT can be a problem. That is especially the case as Carrier Grade NAT becomes more common in the legacy IPv4 networks provided by an increasing number of service providers. It is possible to connect two endpoints via a publicly accessible third machine on common ground. If there are three systems, A, B, and C, where A needs to connect to C, neither A nor C can connect directly to the other yet both can reach host B, then it is possible to make a tunnel via B if both A and C can reach it. Both A and C need to have working accounts on C, even if just for forwarding. Full shell access is not required.
On host B, accounts are needed for C and A.
On host C:
Host hostc
HostName server.example.com
IdentityFile %d/.ssh/test-fw6b
AddKeysToAgent yes
RemoteForward 7900 localhost:5900
RemoteForward 7901 localhost:5901
Start the VNC server and then have the system establish an SSH connection to host B with ssh hostc
. The configuration of host B really needs no modification, unless if the key for the tunnel should be locked down or other restrictions desired.
On host A:
Host tunnel
LocalForward 5900 localhost:7900
LocalForward 5901 localhost:7901
PermitLocalCommand yes
LocalCommand remmina -c vnc://localhost:0
ExitOnForwardFailure yes
Start the SSH connection by entering ssh tunnel
and Remmina will connect automatically to host C via the tunnel on Host C.
System-wide Client Defaults
editThe system-wide client configuration file, /etc/ssh/sshd_config, is a convenient way to provide what are effectively new, local default settings. As mentioned many times, configuration options are applied with a first match priority therefore any system-wide, global options should be as general as possible. System-wide defaults shine when customizing the local environment, including LAN access be means such as Kerberos authentication or even Host-based Authentication, the latter is covered in its own chapter.
Host 172.16.4.*
HostKeyAlias a.pool.example.org
ConnectTimeout 4
Host 172.16.5.*
HostKeyAlias b.pool.example.org
ConnectTimeout 2
Host 172.16.*
HostbasedAuthentication yes
Host *
IdentitiesOnly yes
The above allows host-based authentication for a specific subnet. It also sets IdentitiesOnly globally.
Host *.pool.example.org
VerifyHostKeyDNS no
GSSAPIAuthentication yes
GSSAPIKeyExchange yes
GSSPITrustDNS yes
GSSAPIRenewalForcesRekey yes
GSSAPIDelegateCredentials yes
The above sets system-wide options for all systems in the pool.example.org domain, such that Kerberos authentication is possible.
The manual page for ssh_config(5) has a section on "tokens" which can be used in the stanzas in place of system information, such as the remote host name, the remote account name, or the local account name, to name just a few. These are useful when setting the system-wide client configuration file in /etc/ssh/ssh_config or /etc/ssh/ssh_config.d/* for all local accounts.
Tokens
editSome client configuration directives can make use of tokens to stand in for certain values, as determined at run time.
LocalCommand accepts all tokens.
Hostname accepts the tokens %% and %h.
ProxyCommand and ProxyJump accept the tokens %%, %h, %n, %p, and %r.
CertificateFile, ControlPath, IdentityAgent, IdentityFile, KnownHostsCommand, LocalForward, Match exec, RemoteCommand, RemoteForward, RevokedHostKeys, and UserKnownHostsFile accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u.
KnownHostsCommand additionally accepts the tokens %%, %C, %d, %f, %H, %h, %I, %i, %j, %K, %k, %L, %l, %n, %p, %r, %t, and %u.
The client tokens are described as follows, and are somewhat different from the tokens used in server configuration:
Token | Description |
---|---|
%% | A literal ‘%’. |
%C | The hash of %l%h%p%r%j. |
%d | The local account's home directory. |
%f | The fingerprint of the remote server's host key. |
%H | The known_hosts host name or address searched for. |
%h | The remote host name. |
%I | The reason for a KnownHostsCommand execution: either ADDRESS when looking up the host by address (only when CheckHostIP is enabled), HOSTNAME when searching by host name, or ORDER when preparing the host key algorithm preference list to use for the destination host. |
%i | The local account's UID. |
%j | The contents of the ProxyJump option, or an empty string if this option is unset. |
%K | The base64-encoded remote server's host key. |
%k | The host key alias if specified, otherwise the original remote host name as given on the command line. |
%L | The local host name. |
%l | The local host name, including the domain name. |
%n | The original remote host name, as given on the command line. |
%p | The remote port. |
%r | The remote account name. |
%T | The local tun(4) or tap(4) network interface assigned if tunnel forwarding was requested, otherwise "NONE". |
%t | The type of the server host key, e.g. ssh-ed25519. |
%u | The local account name. |
As always, check ssh_config(5) on the systems in question to know what is actually supported by the installed version of OpenSSH.