dev-sec.ssh-hardening
SSH Hardening (Ansible Role)
Notice: This role has moved to our hardening-collection:
Please report any issues or pull requests there!
Requirements
- Ansible version: > 2.5
Role Variables
network_ipv6_enable
- Default: false
- Description: Set to true if IPv6 is needed. The
ssh_listen_to
must also be configured for IPv6 (e.g.,[::]
).
ssh_server_ports
- Default: ['22']
- Description: Ports where the SSH server should listen.
ssh_client_port
- Default: '22'
- Description: Port the SSH client should connect to.
ssh_listen_to
- Default: ['0.0.0.0']
- Description: One or more IP addresses for the SSH server to listen to. Default is all IPv4 addresses; for security, specify particular addresses!
ssh_host_key_files
- Default: []
- Description: Host keys for SSH daemon. If empty, defaults will be used based on the installed version of SSH.
ssh_host_key_algorithms
- Default: []
- Description: Algorithms for host keys offered by the server. Defaults will be used if empty.
ssh_client_alive_interval
- Default: 600
- Description: Interval for sending keepalive messages.
ssh_client_alive_count
- Default: 3
- Description: Number of keepalive messages sent.
ssh_permit_tunnel
- Default: false
- Description: Set to true if SSH Port Tunneling is required.
ssh_remote_hosts
- Default: []
- Description: List of remote hosts and custom options for the SSH client.
ssh_permit_root_login
- Default: no
- Description: Disables root-login. Set to
without-password
oryes
to enable root-login.
ssh_allow_tcp_forwarding
- Default: no
- Description: Set to 'no' to disable TCP forwarding, 'yes' to allow it. For OpenSSH >= 6.2, can specify 'yes', 'no', 'all', or 'local'. (Note: Use quotes for 'yes' and 'no'.)
ssh_gateway_ports
- Default: false
- Description: Set false to disable binding forwarded ports to non-loopback addresses. Set true for wildcard binding or 'clientspecified' for client-specified binding.
ssh_allow_agent_forwarding
- Default: false
- Description: Set to true to allow Agent Forwarding.
ssh_x11_forwarding
- Default: false
- Description: Set to true to allow X11 Forwarding.
ssh_pam_support
- Default: true
- Description: Set to true if SSH supports PAM (Pluggable Authentication Module).
ssh_use_pam
- Default: true
- Description: Set to false to disable PAM authentication.
ssh_gssapi_support
- Default: false
- Description: Set to true if SSH includes GSSAPI support.
ssh_kerberos_support
- Default: true
- Description: Set to true if SSH supports Kerberos.
ssh_deny_users
- Default: ''
- Description: User names that are not allowed to log in, if specified.
ssh_allow_users
- Default: ''
- Description: User names that are allowed to log in, if specified.
ssh_deny_groups
- Default: ''
- Description: Groups that are disallowed from logging in, if specified.
ssh_allow_groups
- Default: ''
- Description: Groups that are allowed to log in, if specified.
ssh_authorized_keys_file
- Default: ''
- Description: Use a different file for public keys used for user authentication.
ssh_trusted_user_ca_keys_file
- Default: ''
- Description: File containing public keys for trusted certificate authorities to sign user certificates.
ssh_trusted_user_ca_keys
- Default: []
- Description: Specific public keys for trusted certificate authorities. Only used if the previous file is set.
ssh_authorized_principals_file
- Default: ''
- Description: File containing allowed principals. Only used if the previous file is set.
ssh_authorized_principals
- Default: []
- Description: List of paths and authorized principals. Check
default_custom.yml
for options.
ssh_print_motd
- Default: false
- Description: Set false to disable printing the Message of the Day (MOTD).
ssh_print_pam_motd
- Default: false
- Description: Set false to disable MOTD printing via PAM (Debian and Ubuntu).
ssh_print_last_log
- Default: false
- Description: Set false to disable displaying last login info.
sftp_enabled
- Default: false
- Description: Set true to enable SFTP configuration.
sftp_umask
- Default: '0027'
- Description: Specifies the umask for SFTP.
sftp_chroot
- Default: true
- Description: Set false to disable chroot for SFTP.
sftp_chroot_dir
- Default: /home/%u
- Description: Change the default SFTP chroot location.
ssh_client_roaming
- Default: false
- Description: Enable experimental client roaming.
sshd_moduli_file
- Default: '/etc/ssh/moduli'
- Description: Path to the SSH moduli file.
sshd_moduli_minimum
- Default: 2048
- Description: Remove Diffie-Hellman parameters smaller than this size for security.
ssh_challengeresponseauthentication
- Default: false
- Description: Whether challenge-response authentication is allowed (like via PAM).
ssh_client_password_login
- Default: false
- Description: Set true to allow password-based authentication for the SSH client.
ssh_server_password_login
- Default: false
- Description: Set true to allow password-based authentication for the SSH server.
ssh_banner
- Default: false
- Description: Set true to show a banner upon login.
ssh_banner_path
- Default: '/etc/sshd/banner.txt'
- Description: Path to the SSH banner file.
ssh_client_hardening
- Default: true
- Description: Set false to stop hardening the client.
ssh_client_compression
- Default: false
- Description: Allow the client to request compression.
ssh_compression
- Default: false
- Description: Enable server-side compression after successful user authentication.
ssh_login_grace_time
- Default: '30s'
- Description: Time allowed for successful SSH server authentication.
ssh_max_auth_retries
- Default: 2
- Description: Maximum authentication attempts allowed per connection.
ssh_max_sessions
- Default: 10
- Description: Maximum number of open sessions allowed from one connection.
ssh_print_debian_banner
- Default: false
- Description: Set true to show a Debian-specific banner.
ssh_server_enabled
- Default: true
- Description: Set false to disable the OpenSSH server.
ssh_server_hardening
- Default: true
- Description: Set false to stop hardening the server.
ssh_server_match_address
- Default: ''
- Description: Begin a block where configurations depend on matched criteria (address).
ssh_server_match_group
- Default: ''
- Description: Begin a block where configurations depend on matched criteria (group).
ssh_server_match_user
- Default: ''
- Description: Begin a block where configurations depend on matched criteria (user).
ssh_server_match_local_port
- Default: ''
- Description: Begin a block where configurations depend on matched criteria (local port).
ssh_server_permit_environment_vars
- Default: no
- Description: Set yes to allow environment variables from
~/.ssh/environment
and authorized keys.
ssh_server_accept_env_vars
- Default: ''
- Description: List of environment variables sent by the client to copy into the session environment.
ssh_use_dns
- Default: false
- Description: Whether sshd should check the remote host name against the IP address.
ssh_server_revoked_keys
- Default: []
- Description: List of revoked public keys that will always be rejected by the SSH server.
ssh_max_startups
- Default: '10:30:100'
- Description: Maximum number of unauthenticated connections to the SSH daemon.
ssh_macs
- Default: []
- Description: Customize the list of Message Authentication Codes (MACs).
ssh_kex
- Default: []
- Description: Customize the list of Key Exchange (KEX) algorithms.
ssh_ciphers
- Default: []
- Description: Customize the list of encryption algorithms (ciphers).
ssh_custom_options
- Default: []
- Description: Custom lines for SSH client configuration.
sshd_custom_options
- Default: []
- Description: Custom lines for SSH daemon configuration.
sshd_syslog_facility
- Default: 'AUTH'
- Description: Facility code for logging messages from sshd.
sshd_log_level
- Default: 'VERBOSE'
- Description: Verbosity level for logging messages from sshd.
sshd_strict_modes
- Default: true
- Description: Check file modes and ownership before accepting login.
sshd_authenticationmethods
- Default: 'publickey'
- Description: Authentication methods that must be successful for user access.
Configuring Additional Settings
If you want to add SSH options not listed, use ssh_custom_options
(for /etc/ssh/ssh_config
) or sshd_custom_options
(for /etc/ssh/sshd_config
). These options will be at the beginning of the file, allowing you to override later entries.
Example playbook:
- hosts: localhost
roles:
- dev-sec.ssh-hardening
vars:
ssh_custom_options:
- "Include /etc/ssh/ssh_config.d/*"
sshd_custom_options:
- "AcceptEnv LANG"
Changing the Default Port
This role usually connects over port 22. If you change the SSH port via ssh_server_ports
, remember to update your inventory with the new SSH port after restarting the server.
If idempotency matters, consider using the ssh-hardening-fallback
role which defaults back to port 22 if the configured port is unreachable.
Example Playbook
- hosts: localhost
roles:
- dev-sec.ssh-hardening
Local Testing
The easiest way to test this role locally is by using Docker. You need to install Docker on your system—see Get started for the right Docker package for your system.
You can also use Vagrant and VirtualBox or VMware to conduct local tests. You’ll need to install VirtualBox and Vagrant on your system. See Vagrant Downloads for a suitable package. For testing, we use test-kitchen
. Check out the test-kitchen guide for more details.
To install test-kitchen, run:
# Install dependencies
gem install bundler
bundle install
Testing with Docker
# Fast test on one machine
bundle exec kitchen test ssh-ubuntu1804-ansible-latest
# Test on all machines
bundle exec kitchen test
# For development
bundle exec kitchen create ssh-ubuntu1804-ansible-latest
bundle exec kitchen converge ssh-ubuntu1804-ansible-latest
bundle exec kitchen verify ssh-ubuntu1804-ansible-latest
# Clean up
bundle exec kitchen destroy ssh-ubuntu1804-ansible-latest
Testing with VirtualBox
# Fast test on one machine
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test ssh-ubuntu-1804
# Test on all machines
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test
# For development
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen create ssh-ubuntu-1804
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen converge ssh-ubuntu-1804
For more information, check the test-kitchen documentation.
FAQ / Troubleshooting
Can't log into my account, even with the client key?
Check if your account is locked by looking for an !
in the password hash with:
sudo grep myuser /etc/shadow
To unlock it, use:
passwd -u myuser
If no password, unlock using:
usermod -p "*" myuser
If using PAM, set ssh_use_pam: true
to allow key access for locked users.
Why can't my application connect via SSH anymore?
First check log files and the communication between your client and server. You may have compatibility issues if your application uses outdated security settings, which this hardening role modifies for better security.
Why do file transfer modules in Ansible stop working?
This role disables SFTP by default. Ansible uses SFTP to transfer files; you may need to set scp_if_ssh = True
in your ansible.cfg
for it to use SCP instead. Alternatively, you can enable SFTP by setting sftp_enabled
to true.
Can't restart the sshd service due to permission issues?
Run your playbook as root
(without become: yes
) or add become: yes
to the handler.
Contributing
License and Author
- Author: Sebastian Gumprich
- Author: Christoph Hartmann chris@lollyrock.com
This software is licensed under the Apache License, Version 2.0 (the "License"). You can’t use this file without compliance with the License. A copy of the License can be found at:
http://www.apache.org/licenses/LICENSE-2.0
Software distributed under this license is provided "as is", without warranties or conditions of any kind. Check the License for more details.
This Ansible role provides numerous security-related ssh configurations, providing all-round base protection.
ansible-galaxy install dev-sec.ssh-hardening