Bug 2468 - Option to include external files to sshd_config
Summary: Option to include external files to sshd_config
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: 8.1p1
Hardware: Other Linux
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
: 2351 (view as bug list)
Depends on: 2463
Blocks:
  Show dependency treegraph
 
Reported: 2015-09-15 22:16 AEST by Jakub Jelen
Modified: 2021-06-13 11:49 AEST (History)
16 users (show)

See Also:


Attachments
proposed patch (5.01 KB, patch)
2015-09-15 22:16 AEST, Jakub Jelen
no flags Details | Diff
Include server side (with same semantics as client) (12.48 KB, patch)
2016-09-06 01:54 AEST, Jakub Jelen
no flags Details | Diff
Include server side (with same semantics as client) - updated for 7.9p1 (12.59 KB, patch)
2019-01-12 05:37 AEDT, Patrick McLean
no flags Details | Diff
Include server side with re-exec passing the include list (master, 2019) (19.39 KB, patch)
2019-03-06 01:52 AEDT, Jakub Jelen
no flags Details | Diff
sample sshd_config update command to implement behaviour on GNU Linux with systemd (4.16 KB, text/plain)
2019-10-02 00:44 AEST, Ricardo
no flags Details
revised patch (16.38 KB, patch)
2020-01-24 15:52 AEDT, Damien Miller
no flags Details | Diff
regress patch (4.41 KB, patch)
2020-01-24 15:54 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelen 2015-09-15 22:16:22 AEST
Created attachment 2706 [details]
proposed patch

This topic was discussed in few bugs (namely 1613, 2146, 1585) for client side and the last one also contains patch that can be applied to the current openssh. Having the same feature for server side makes the same sense for me so I created patch also for server side.

To understand the main reason behind this feature, it is our "system-wide crypto policy", which should allow us to enforce specific security policies in uniform way over the most crypto tools in whole system.

This feature will also allow us to have default drop-in directory, which will also improve the packaging possibilities for third party tools and will make possible to update main config without conflict with changes made by users.

All tests still passing. If you would like from me to implement also test cases to cover this feature, let me know. I see there are tests for most of the recent features.

Please note, that the prerequisite for this feature is solving the bug #2463 (openbsd compat glob), which makes sshd segfault with this patch in kerberos library.
Comment 1 Damien Miller 2016-07-08 14:32:50 AEST
IMO the desirable semantics of Include in sshd_config are even more subtle and fraught than those of ssh_config. For example, how should the following behave:

Port 22
Include /etc/ssh/config_a
PasswordAuthentication no
Include /etc/ssh/config_b

Match user djm
Banner /etc/banner
Include /etc/ssh/config_c

---

If inclusion operates just by pasting text in, then config_a could radically alter the following configuration if it includes a Match directive.

Similarly, config_c's application conditional on the previous Match succeeding?

I wish we had a brace-ful configuration language - it would make resolving these way simpler :/
Comment 2 Zdenek Sedlak 2016-08-02 05:16:45 AEST
I would propose to simply pasting the lines from the config file at the position where the Include option is placed in the sshd_config, and furthermore, it would be nice to have an Includedir option like the sudo has.
Comment 3 Jakub Jelen 2016-09-06 01:54:06 AEST
Created attachment 2869 [details]
Include server side (with same semantics as client)

(In reply to Zdenek Sedlak from comment #2)
> I would propose to simply pasting the lines from the config file at
> the position where the Include option is placed in the sshd_config

That was the initial idea and, if I am right. It is the way how it was initially implemented. But the client side config was implemented in more complex manner, that even the Include depends on the Match context so implementing server side in different way does not seem like a good idea.

> it would be nice to have an Includedir option like
> the sudo has.

Include with GLOB expansion does the same without additional complexity of another option.

Reading the implementation of the client side config include, there should be certainly some limit to the recursion and some regression sanity test to make sure it does what it is supposed to do. Introducing some more complexity would make it much harder to understand what is going on there (though the debug log level is very helpful here).

(In reply to Damien Miller from comment #1)
> If inclusion operates just by pasting text in, then config_a could
> radically alter the following configuration if it includes a Match
> directive.
> 
> Similarly, config_c's application conditional on the previous Match
> succeeding?

The other possibility would be to reset the context for each include file, but that looks even more confusing to me.

> I wish we had a brace-ful configuration language - it would make
> resolving these way simpler :/

That would be nice-to-have, but probably impossible to change now.

Attaching a new patch with a regression tests, providing the same behavior as the client side config include.

Also added a check to make sure that the Include list is not empty (missing in the client).
Comment 4 Paul Wise 2016-10-05 12:42:17 AEDT
If this is implemented, a default/implicit include of /etc/sshd_config.d/* would be much appreciated.
Comment 5 Jakub Jelen 2016-11-01 00:19:08 AEDT
(In reply to Paul Wise from comment #4)
> If this is implemented, a default/implicit include of
> /etc/sshd_config.d/* would be much appreciated.

Yes, we have this already in fedora in client configuration files. The server should go with the same approach. Incorporating this uniformly into the default configuration file would be nice.
Comment 6 online 2018-02-26 21:55:46 AEDT
*** Bug 2351 has been marked as a duplicate of this bug. ***
Comment 7 Patrick McLean 2019-01-12 05:37:46 AEDT
Created attachment 3223 [details]
Include server side (with same semantics as client) - updated for 7.9p1

Here is an updated patch that applies against 7.9p1
Comment 8 Dusty Mabe 2019-01-29 02:58:15 AEDT
For the new CoreOS initiatives (Fedora CoreOS and Red Hat CoreOS) we are looking at this functionality as we'd like to set `PasswordAuthentication no` and `PermitRootLogin prohibit-password` by default but make it easy for users to override those settings by using drop-in config file fragments.

For context see https://github.com/coreos/fedora-coreos-tracker/issues/138

Is it possible a feature such as this would be considered for inclusion in sshd?
Comment 9 Sean P. Kane 2019-02-01 10:44:26 AEDT
This would be very useful in many Linux workflows, including CoreOS.

Making the sshd_config compose-able can be vital in systems, where a default sshd_config is provided, but another team might need to add a configuration feature or two, without completely over-ridding the base config.

I don't think that we need something more than sorting the files if included using a glob and and then a simple paste on the configs (in the sorted order) exactly where the include is located.

Most of the time, I only think that two people, teams or systems) will be managing this, so while there may be edge cases, they should be reasonably easy to avoid/fix (especially if documented).
Comment 10 Damien Miller 2019-03-05 10:01:23 AEDT
I took a quick look at this patch and it seem ok wrt the configuration parsing side. However, it doesn't do the right thing wrt sshd's self-reexecution.

When sshd accepts a connection, instead of just fork(2)ing a subprocess to handle, it forks and re-executes sshd to ensure each child process gets a different memory layout, re-randomised stack cookies, etc.

Part of the re-execution shuffle is passing the entire sshd_config from the listener sshd process to the re-executed one. This ensures that the configuration used is the one that sshd was originally started with, not the one that happens to be in the filesystem at the time the connection was received.

This patch doesn't do that. I think maybe if you extended include_list to record the full text of each included file and then marshaled/demarsheled that in sshd.c:send_rexec_state()/recv_rexec_state() then you'd be close to good.
Comment 11 Jakub Jelen 2019-03-05 21:44:38 AEDT
Damien,
thank you for having a look into this patch and pointing out the gaps. The fulltext is already stored in the include_list structure as a buffer, but you are right, I missed the re-exec when I was writing the patch.

I will try to rebase it to the current master and address the re-exec part (with some minor cleanups).
Comment 12 Jakub Jelen 2019-03-06 01:52:57 AEDT
Created attachment 3250 [details]
Include server side with re-exec passing the include list (master, 2019)

The attached patch is rebased on current master with several cosmetic issues fixed. As a disadvantage, it is passing more arguments to the config processing functions.

The same code is available in my github fork:
https://github.com/Jakuje/openssh-portable/tree/sshd_include

One thing that might be missing is some cleanup of the allocated memory before exits, which might make sense also for the original cfg value, when it will no longer be needed.

Let me know if you have some more concerns to address regarding this patch.
Comment 13 Dusty Mabe 2019-03-26 09:58:02 AEDT
Hey Damien,

Any chance you could take a look at the updated patch from Jakub?
Comment 14 Thomas Leavitt 2019-03-30 04:01:47 AEDT
Sample use case:

I'm setting up nearly separate user accounts on a server as sftp only in separate chroots (each requiring a separate entry in sshd_config), and programmatically sourcing the user list from a database. Right now, every time that list is updated, I'm going to have to append the relevant per user entries (93 at the moment) separate copy of the main part of sshd_config, then overwrite /etc/ssh/sshd_config and restart sshd. If I want to update sshd_config without doing this, I'm going to have the make the edits in two places. Messy and error prone process, obviously. 

Would be much cleaner to simply add and delete entries from an included file or directory.
Comment 15 Ricardo 2019-05-10 07:35:57 AEST
Hi,

I just tested the patch this patch and it worked great. Looking for this feature since a while.

I have a similar use case as Thomas. I'm running a backup server where every user gets its own chroot and some different sshd_options. This way I can create/delete a config file per user as they come and go.

It would be great to see this feature in 8.1.

Thank you.
Comment 16 Ignaz Forster 2019-09-28 05:29:11 AEST
We are also very interested in such an option for openSUSE Kubic, for similar reasons as Fedora CoreOS.
Moreover, during a discussion at this year's "All Systems Go!" it got clear that there is a broad interest in splitting package and admin configuration into different files, both from distribution maintainers and administrators. The proposed patch would make that possible.
Comment 17 Ricardo 2019-10-02 00:44:38 AEST
Created attachment 3333 [details]
sample sshd_config update command to implement behaviour on GNU Linux with systemd
Comment 18 Ricardo 2019-10-02 00:47:06 AEST
Added script implement desired behaviour on GNU LINUX using systemd.

systemd unit drop in:

sudo mkdir -m 755 -p "/etc/systemd/system/sshd.service.d/"
cat <<EOF > /etc/systemd/system/sshd.service.d/50-compile-sshd-config.conf
[Service]
ExecStartPre=-/usr/local/bin/sshd_config_update
EOF
chmod 644 /etc/systemd/system/sshd.service.d/50-compile-sshd-config.conf
systemctl daemon-reload


Hope this workaround helps someone.
Comment 19 Jakub Jelen 2019-12-24 00:42:34 AEDT
Damien, any update on this one? Any chance to have this re-reviewed and merged? Are there still some concerns or reasons for not to implement this from your side? It looks like there is already more than enough people interested in this functionality.
Comment 20 Patrick McLean 2020-01-24 13:01:23 AEDT
Not everyone uses systemd, and this feature is useful to non-systemd users.

It might be useful to OpenBSD and FreeBSD users as well, not just us Linux people. It's nicer and less error prone to have the daemon itself be aware of the extra configuration files rather than having to run an external script.
Comment 21 Damien Miller 2020-01-24 15:52:38 AEDT
Created attachment 3350 [details]
revised patch

reworked version of the patch using the preferred sys/queue.h linked list macros and a few other stylistic tweaks
Comment 22 Damien Miller 2020-01-24 15:54:46 AEDT
Created attachment 3351 [details]
regress patch

slightly-tweaked regression test
Comment 23 Jakub Jelen 2020-01-27 22:38:20 AEDT
From fast review, I noticed only one minor issue:

> +				fatal("%s: too manu glob results", __func__);

There is a typo manu -> many

Otherwise it looks good.
Comment 24 Damien Miller 2020-02-01 10:26:43 AEDT
this has been committed and will be in openssh-8.2
Comment 25 online 2020-02-08 05:08:59 AEDT
What was decided with regards to including a file that contains a Match clause? Is the match reverted to what it was before the include once the control goes back to the including file?
Comment 26 Jakub Jelen 2020-02-10 21:52:42 AEDT
(In reply to online from comment #25)
> What was decided with regards to including a file that contains a
> Match clause? Is the match reverted to what it was before the
> include once the control goes back to the including file?

Yes. This is the same as with the client config. Included files do not affect the match context of the file including them.
Comment 27 Damien Miller 2021-04-23 15:08:19 AEST
closing resolved bugs as of 8.6p1 release
Comment 28 Paul Wise 2021-06-13 11:49:36 AEST
Woops, wrong bug, sorry for the noise!