- Module Description
- Breaking changes in 9.0.0
- Setup
- Usage
- Limitations
- Development
- Acceptance tests
Manages the SSH Client and Server
Version 9.0.0 drastically reduces the "blast radius" of include ssh. A bare
include ssh now installs the openssh-server/openssh-clients packages
and manages only the /etc/ssh directory — it does not manage the sshd
service, rewrite /etc/ssh/sshd_config or /etc/ssh/ssh_config, or silently
enable any simp_options::* feature. Everything that used to be automatic is
now opt-in:
- The
sshdservice (and thesshduser/group,/var/empty/sshd, host-key file management) is only managed whenssh::server::service_ensureorssh::server::service_enableis set. - Each
ssh::server::confsetting defaults toundefand only writes asshd_configentry when you set it. A bare include leaves/etc/ssh/sshd_configexactly as the package and administrator left it. ssh::client::add_default_entrynow defaults tofalse, so theHost *entry in/etc/ssh/ssh_configis no longer written automatically.- The
simp_options::*lookups are gone, along with the server-side FIPS/version cipher auto-detection and thessh::server::conf::fips,enable_fallback_ciphers, andfallback_ciphersparameters. - IPA-joined hosts: the automatic
GSSAPIAuthentication yes(driven by theipafact) is gone, and thesimp:defaultsprofile deliberately leavesGSSAPIAuthenticationunmanaged so it cannot break Kerberos SSO. If your users log in via Kerberos/GSSAPI, setssh::server::conf::gssapiauthentication: trueexplicitly. - OATH:
ssh::server::conf::oathnow defaults to unset. Enabling it still forcesPasswordAuthentication no; when you later disable it, setoath: falseexplicitly (rather than removing the key) so the module restoresPasswordAuthenticationand you are not locked out.
There are two ways to restore the previous behavior:
-
Per parameter — set the specific
ssh::*parameters you want (e.g.ssh::server::service_ensure: running,ssh::server::conf::permitrootlogin: false,ssh::client::add_default_entry: true). -
The
simp:defaultsprofile — the module ships a compliance_engine profile namedsimp:defaultsthat is a drop-in restoration of the pre-9.0.0 behavior. Enable it stack-wide with a single Hiera key:compliance_engine::enforcement: - simp:defaults
This is opinionated for SIMP sites: it manages the service, re-applies the hardening defaults and FIPS-aware crypto, and re-enables the SIMP integrations (firewall, PKI, haveged, tcpwrappers). Site Hiera outranks the profile, so to get "old behavior, but safer" enable the profile and then override the individual keys you care about (e.g.
ssh::server::conf::firewall: false) in your own Hiera.
A bare include ssh installs the SSH packages and manages the /etc/ssh
directory. The sshd service and the contents of the files in /etc/ssh are
managed only when the relevant parameters are set (or the simp:defaults
profile is enabled) — see Breaking changes in 9.0.0.
The only requirement is including the ssh module in your modulepath
include 'ssh'Including ssh will manage both the server and the client with reasonable
settings:
include 'ssh'The ssh class automatically includes both the ssh::client and ssh:server
classes. To exclude one or both of these classes, set the appropriate parameter
to false as shown:
class{ 'ssh':
enable_client => false,
enable_server => false,
}As of 9.0.0, ssh::client does not manage /etc/ssh/ssh_config by
default. Set ssh::client::add_default_entry: true to manage the Host *
entry with the module's sane defaults.
If you want to customize the default entry, leave add_default_entry at its
default of false and manage Host * directly with the defined type
ssh::client::host_config_entry:
class{ 'ssh::client': add_default_entry => false }
ssh::client::host_config_entry{ '*':
gssapiauthentication => true,
gssapikeyexchange => true,
gssapidelegatecredentials => true,
}Different settings for particular hosts can be managed by using the defined
type ssh::client::host_config_entry:
# `ancient.switch.fqdn` only understands old ciphers:
ssh::client::host_config_entry { 'ancient.switch.fqdn':
ciphers => [ 'aes128-cbc', '3des-cbc' ],
}If you need to customize a setting in /etc/ssh/ssh_config that
ssh::client::host_config_entry doesn't manage, use the
ssh_config type, provided by augeasproviders_ssh:
# RequestTTY isn't handled by ssh::client::host_config_entry
# Note: RequestTTY is not a valid ssh_config setting on OpenSSH where version < 5.9
ssh_config { 'Global RequestTTY':
ensure => present,
key => 'RequestTTY',
value => 'auto',
}include `ssh::client`You can prevent all inclusions of ssh from inadvertently managing the SSH
server by specifying ssh::enable_server: false:
class{ 'ssh':
enable_client => true,
enable_server => false,
}As of 9.0.0, ssh::server only manages the sshd service and the contents of
/etc/ssh/sshd_config when you opt in. Set ssh::server::service_ensure and
ssh::server::service_enable to manage the service, and set the individual
ssh::server::conf parameters (or enable the simp:defaults profile) for the
hardening defaults.
include 'ssh::server'
# Alternative:
# if `ssh::enable_server: true`, this will also work
include 'ssh'If you want to customize any ssh::server settings, you must edit the
parameters of ssh::server::conf using Hiera or ENC (Automatic Parameter
Lookup). These customizations cannot be made directly using a
resource-style class declaration; they must be made via APL:
---
# Note: Hiera only!
ssh::server::conf::port: 2222
ssh::server::conf::ciphers:
- 'chacha20-poly1305@openssh.com'
- 'aes256-ctr'
- 'aes256-gcm@openssh.com'
ssh::server::conf::ssh_loglevel: "verbose"
ssh::server::conf::gssapiauthentication: trueinclude 'ssh::server'
# Alternative:
# if `ssh::enable_server: true`, this will also work
include 'ssh'Users may specify any undefined global sshd settings using the
ssh::server::conf::custom_entries parameter as follows:
---
ssh::server::conf::custom_entries:
GSSAPIKeyExchange: "yes"
GSSAPICleanupCredentials: "yes"NOTE: This is parameter is not validated. Be careful to only specify options that are allowed for your particular SSH daemon. Invalid options may cause the ssh service to fail on restart. Duplicate settings will result in duplicate Puppet resources (i.e., manifest compilation failures).
On EL9+ the vendor sshd_config Includes /etc/ssh/sshd_config.d/*.conf
at the top of the file, and sshd uses the first obtained value — so a
keyword the vendor pre-sets in 50-redhat.conf (X11Forwarding,
GSSAPIAuthentication, UsePAM, …) silently overrides anything this
module writes to the main file. To control such a keyword, manage it in the
drop-in itself with ssh::server::conf::sshd_config_entries, which exposes
raw sshd_config resources (including target)
through Hiera:
---
ssh::server::conf::sshd_config_entries:
'50-redhat X11Forwarding':
key: 'X11Forwarding'
value: 'no'
target: '/etc/ssh/sshd_config.d/50-redhat.conf'Give each entry a title distinct from any module-managed keyword (module
entries use the bare keyword as the title) and set key explicitly. When
the sshd service is managed, changes trigger a restart through the
service's subscription to ssh::server::conf; with an unmanaged service
nothing is restarted. Each entry gets a require on the openssh package
merged with any require it declares itself.
Instead of editing the vendor file you may also point entries at a drop-in of
your own that sorts before it (e.g.
target: '/etc/ssh/sshd_config.d/00-simp.conf' — augeas creates the file):
that wins the same first-obtained-value race without modifying vendor content,
so the next openssh update does not leave an .rpmnew behind. Editing the
vendor file remains supported — some compliance audits check the vendor file's
own contents, which only an in-place edit satisfies.
The client has the equivalent ssh::client::ssh_config_entries for raw
ssh_config resources. Note that the vendor client drop-ins
(/etc/ssh/ssh_config.d/05-redhat.conf on EL8, 50-redhat.conf on EL9+)
wrap their settings in a Match final all block, which the ssh_config
type cannot edit (it only manages Host blocks) and which ssh applies last,
only for options nothing else has set. So on the client, do not point
entries at the vendor file — manage a drop-in of your own that ssh reads
first, e.g.:
---
ssh::client::ssh_config_entries:
'simp GSSAPIAuthentication':
key: 'GSSAPIAuthentication'
value: 'no'
target: '/etc/ssh/ssh_config.d/00-simp.conf'Prior to version 6.7.0 of the simp-ssh module, undefined sshd settings
were managed with sshd_config_ type, provided by
augeasproviders_ssh. Although this functionality has been
incorporated into ssh::server::conf::custom_entries, it is still available,
and in some cases such as Match entries, necessary to call directly.
The following examples illustrate Match entries using sshd_config:
Puppet:
include 'ssh::server'
sshd_config {
"AllowAgentForwarding":
ensure => present,
condition => "Host *.example.net",
value => "yes",
}
# Specify unique names to avoid duplicate declarations and compilation failures
sshd_config {
"X11Forwarding foo":
ensure => present,
keys => "X11Forwarding",
condition => "Host foo User root",
value => "yes",
}To delete a sshd_config entry, simply set ensure to absent as shown:
sshd_config {
"X11Forwarding foo":
ensure => absent,
}You can focus ssh on managing the SSH server by itself by specifying
ssh::enable_client: false:
class{ 'ssh':
enable_client => false,
enable_server => true,
}Note: including ssh::client directly would still manage the SSH client
As of 9.0.0, the server classes no longer auto-select ciphers: when
ssh::server::conf::ciphers, ssh::server::conf::macs, or
ssh::server::conf::kex_algorithms are unset, no corresponding sshd_config
line is managed and the OpenSSH/crypto-policy defaults apply. (The old
FIPS/version auto-detection and the ssh::server::conf::fips,
enable_fallback_ciphers, and fallback_ciphers parameters were removed —
see Breaking changes in 9.0.0.)
To manage them, either set the parameters explicitly:
ssh::server::conf::ciphers:
- aes256-gcm@openssh.com
- aes128-gcm@openssh.com
- aes256-ctr
- aes192-ctr
- aes128-ctror enable the simp:defaults profile, which supplies the strong, FIPS-aware
cipher/MAC/key-exchange sets the module used to auto-detect (the profile
selects the FIPS or non-FIPS variant based on the node's FIPS
mode via a fips_enabled confine).
When the default Host * entry is managed (ssh::client::add_default_entry: true, or any ssh::client::host_config_entry), the client ciphers in
/etc/ssh/ssh_config are configured to strong ciphers that are recommended
for use.
If you need to connect to a system that does not support these ciphers but uses older or weaker ciphers, you should either:
- Manage an entry for that specific host using an additional
ssh::client::host_config_entry, or: - Connect to the client with custom ciphers specified by the command line
option,
ssh -c- You can see a list of ciphers that your ssh client supports with
ssh -Q cipher. - See the ssh man pages for further information.
- You can see a list of ciphers that your ssh client supports with
Either of the choices above are preferable to weakening the system-wide client settings unecessarily.
You can manage users authorized_keys file using the ssh::authorized_keys
class and the ssh::authorized_keys::keys hiera value.
---
ssh::authorized_keys::keys:
kelly: ssh-rsa skjfhslkdjfs...
nick:
- ssh-rsa sajhgfsaihd...
- ssh-rsa jrklsahsgfs...
mike:
key: dlfkjsahh...
type: ssh-rsa
user: mlast
target: /home/gitlab-runner/.ssh/authorized_keysSIMP Puppet modules are generally intended to be used on a Red Hat Enterprise Linux-compatible distribution.
Please read our Contribution Guide.
If you find any issues, they can be submitted to our JIRA.
To see a list of development tasks available for this module, run
bundle exec rake -T
To run the system tests, you need Vagrant installed.
You can then run the following to execute the acceptance tests:
bundle exec rake beaker:suitesSome environment variables may be useful:
BEAKER_debug=true
BEAKER_destroy=onpass
BEAKER_provision=no
BEAKER_fips=yesBEAKER_debug: show the commands being run on the SUT and their output.BEAKER_destroy=onpassprevent the machine destruction if the tests fail.BEAKER_provision=no: prevent the machine from being recreated. This can save a lot of time while you're writing the tests.BEAKER_fips=yes: Provision the SUTs in FIPS mode.
SIMP_SSH_report_dir=/PATH/TO/DIRECTORYSIMP_SSH_report_dir: If set to a valid directory, will record the Ciphers / MACs / kexalgorithms for each SSH server during the test. This can be used to validate and update the information in the Server ciphers section.