Sorting out the ordering of OpenSSH configuration directives
As I discovered recently, OpenSSH makes some unusual choices for the ordering of configuration directives in its configuration files, both sshd_config and ssh_config (and files they include). Today I want to write down what I know about the result (which is partly things I've learned researching this entry).
For sshd_config, the situation is relatively straightforward.
There are what we could call 'global options' (things you set
normally, outside of 'Match' blocks) and 'matching Match
options' (things set
in Match blocks that actually matched). Both of them are 'first
mention wins', but Match options take priority over global options
regardless of where the Match option block is in the (aggregate)
configuration file. Sshd makes 'first mention win' work in the
presence of including files from /etc/ssh/sshd_config.d/ by
doing the inclusion at the start of /etc/ssh/sshd_config.
So here's an example with a Match statement:
PasswordAuthentication no Match Address 127.0.0.0/8,192.168.0.0/16 PasswordAuthentication yes
Password authentication is turned off as a global option but then overridden in the address-based Match block to enable it for connections from the local network. If we had a (Unix) group for logins that we wanted to never use passwords even if they were coming from the local network, I believe that we would have to write it like this, which looks somewhat odd:
PasswordAuthentication no Match Group neverpassword PasswordAuthentication no Match Address 127.0.0.0/8,192.168.0.0/16 PasswordAuthentication yes
Then a 'neverpassword' person logging in from the local network would match both Match blocks, and the first block (the group block) would have 'PasswordAuthentication no' win over the second block's 'PasswordAuthentication yes'. Equivalently, you could put the global 'PasswordAuthentication no' after both Match blocks, which might be clearer.
The situation with ssh and ssh_config is one that I find more confusing and harder to follow. The ssh_config manual page says:
Unless noted otherwise, for each parameter, the first obtained value will be used.
It's pretty clear how this works for the various sources of configurations; options on the command line take priority over everything else, and ~/.ssh/config options take priority over the global options from /etc/ssh/ssh_config and its included files. But within a file (such as ~/.ssh/config), I get a little confused.
What I believe this means for any specific option that you want to
give a default value to for all hosts but then override for specific
hosts is that you must put your Host *
directive for it at the
end of your configuration file, and the more specific Host
or Match
directives first. I'm
not sure how this works for matches like 'Match canonical
' or
'Match final
' that happen 'late' in the processing of your
configuration; the natural reading would be that you have to make
sure that nothing earlier conflicts with them. If this is so, a
natural use for 'Match final
' would then be options that you want
to be true defaults that only apply if nothing has overridden them.
Some ssh_config options are special in that you can provide
them multiple times and they'll be merged together; one example is
IdentityFile
.
I think this applies even across multiple Host and Match blocks,
and also that there's no way to remove an IdentityFile once you've
added it (which might be an issue if
you have a lot of identity files, because SSH servers only let
you offer so many). Some options let you
modify the default state to, for example, add a non-default key
exchange algorithm;
I haven't tested to see if you can do this multiple times in Host
blocks or if you can only do it once.
(These days you can make things somewhat simpler with 'Match tagged
...' and 'Tag
'; one handy
and clear explanation of what you can do with this is OpenSSH
Config Tags How To.)
Typically your /etc/ssh/ssh_config has no active options set
in it and includes /etc/ssh/ssh_config.d/* at the end. On
Debian-derived systems, it does have some options specified (for
'Host *
', ie making them defaults), but the inclusion of
/etc/ssh/ssh_config.d/* has been moved to the start so you can
override them.
My own personal ~/.ssh/config setup starts with a 'Host *
'
block, but as far as I can tell I don't try to override any of its
settings later in more specific Host blocks. I do have a final
'Host *
' block with comments about how I want to do some things
by default if they haven't been set earlier, along with comments in
the file that I was finding all of this confusing. I may at some
point try to redo it into a 'Match tagged' / 'Tag' form to see if
that makes it clearer.
Comments on this page:
|
|