Normally when you want to set options for your SSH server you would edit it's default configuration file located under /etc/ssh/sshd_config. This is the default file that's read by the sshd application. However this becomes a little more challenging when you want to use automated tooling to roll out configuration changes. Your tooling either has to know how to parse the file and edit/insert/delete lines, or the file is completely overwritten. This approach presents additional challenges when it comes time to apply operating system updates since the file has been changed in the base system. Fortunately there is an elegant solution to this problem.
Quick Start
If you just want to get this working, run the following commands to get your system setup:
mkdir -p /usr/local/etc/ssh/sshd_config.d/
cat << EOF >/usr/local/etc/ssh/sshd_config
Include /etc/ssh/sshd_config
Include /usr/local/etc/ssh/sshd_config.d/*.conf
EOF
sysrc sshd_flags="-f /usr/local/etc/ssh/sshd_config"
service sshd restart
Continue reading below to understand what the above commands did to your FreeBSD system.
Requirements
This approach should work on all modern FreeBSD versions, past and future. However as of this writing it's only been tested with version 13.2 and later. It's should work so long as the rc.d framework in your operating system supports the extra flags option.
Preparation
First step is to create a new framework for the SSH server configuration. Start by creating a new directory to store the files and directories under /usr/local/etc/. This will allow us to modify configuration without disturbing the system's base configuration too much.
As root, do:
mkdir -p /usr/local/etc/ssh/sshd_config.d/
Then proceed to create a file that we will edit later and will be utilized by the rc.d startup script.
touch /usr/local/etc/ssh/sshd_config
Unless you've changed the system wide umask, the default permissions should be what is desired. Your directory should look something like the below. In other words the permissions should be exactly like the base system's /etc/ssh/ directory.
4 drwxr-xr-x 39 root wheel 1.5K Jan 21 18:25 ../
4 drwxr-xr-x 3 root wheel 512B Jan 21 18:34 ./
4 -rw-r--r-- 1 root wheel 77B Jan 21 18:34 sshd_config
4 drwxr-xr-x 2 root wheel 512B Jan 21 18:35 sshd_config.d/
With this new framework all our custom changes will go into files located in the directory.
Install new Framework
The important piece that acts as the glue is kept in our /usr/local/etc/ssh/sshd_config file. As you recall, we created this empty file in the steps earlier. This file is completely outside the control of the base operating system.
The sshd program can be directed to load additional configuration options from multiple files using the Include directive.
Edit the custom sshd_config file we created to contain only the following:
Include /etc/ssh/sshd_config
Include /usr/local/etc/ssh/sshd_config.d/*.conf
The directives above will first load the system default sshd_config file and then later proceed to loading any files that end in ".conf" located in the /usr/local/etc/ssh/sshd_config.d/ directory.
Activate this new framework by telling the sshd service to load an alternate configuration file during startup using the "-f" flag. This can be accomplished by leveraging the FreeBSD rc.d system with the following line:
sshd_flags="-f /usr/local/etc/ssh/sshd_config"
There are multiple ways reconfigure the sshd service using the rc.d configuration framework. If your version of FreeBSD supports it, drop a new file in the "/etc/rc.conf.d/" directory containing the line above. Alternatively you could just use the sysrc command to programmatically edit the global /etc/rc.conf file.
sysrc sshd_flags="-f /usr/local/etc/ssh/sshd_config"
Let's test everything to make sure it's working. Our SSH server should continue to function unchanged, but our custom sshd_config file should be used as the daemon's entry point to load it's configuration.
Restart the sshd service and make sure there are no errors. Ensure you can still access the system with new sessions.
service sshd restart
The above command should produce no errors and you should be able to create new SSH sessions into your system as you normally have done.
Now verify that the ssh server daemon is indeed using /usr/local/etc/ssh/sshd_config as it's configuration entry point. You can check this by looking at the running process.
I like to use the pgrep command for this:
pgrep -fl sshd
The above command should print something like:
1569 sshd: /usr/sbin/sshd -f /usr/local/etc/ssh/sshd_config [listener] 0 of 10-100 startups
We can confirm that the ssh server has been started using the correct configuration file.
Add Your Own Files
Now you can add your own custom configuration options without worrying about having to manage the system's default sshd_config file. Simply create a new file in the new sshd_config.d directory and restart the SSH service.
For example, we can test this new functionality by re-configuring the SSH server to allow direct root log into our system (not recommended for production use). Create a new file named allow_root.conf in the /usr/local/etc/ssh/sshd_config.d/ directory with the corresponding directive to allow root log in and restart the service:
echo "PermitRootLogin yes" > /usr/local/etc/ssh/sshd_config.d/allow_root.conf
service sshd restart
Now, any attempts to log in as root using SSH will be permitted.
Since that's not a good security practice, let's delete the file and restart the service to disable that ability.
rm /usr/local/etc/ssh/sshd_config.d/allow_root.conf
service sshd restart
Enjoy
The obvious benefit of this whole setup is that the base system's sshd_config files remains unchanged, thus making upgrades a little smoother. It also saves you a ton of headaches with automated configuration management when provisioning.
So the next time you run freebsd-update and see the notice below, consider taking a few moments to setup your FreeBSD system to use this new approach.
The following files are affected by updates. No changes have
been downloaded, however, because the files have been modified
locally:
/etc/ssh/sshd_config
Hopefully this functionality will be available to use right out of the box in future versions of FreeBSD.
- Log in to post comments