Critical Controls to Secure OpenSSH Installation
Introduction
OpenSSH is developed by the OpenBSD project developers and made available under a BSD-style license. It is a connectivity tool and uses the SSH protocol to encrypt traffic and eliminate eavesdropping, connection hijacking, and similar attacks. OpenSSH consists of a number of utilities in it:
- ssh: A program for logging into a remote machine and for executing commands on a remote machine.
- sshd: Daemon program for ssh. sshd listens for connections from clients. It is started at boot and forks a new daemon for each incoming connection. The forked daemons handle key exchange, encryption, authentication, command execution, and data exchange.
- ssh_config: The client configuration file.
- sshd_config: The daemon configuration file.
- ssh-agent: An agent that is used to save the private keys used for public-key authentication.
- ssh-add: Tool which adds keys to in the ssh-agent.
- sftp: File transfer program, similar to ftp, which performs all operations over encrypted ssh.
- scp: Copies files between hosts on a network. It uses ssh for data transfer, and uses the same authentication and provides the same security as ssh.
- ssh-keygen: Key generation tool by OpenSSH.
- sftp-server: Program that speaks the server side of SFTP protocol to stdout and expects client requests from stdin(Starts automatically by sshd).
- ssh-keyscan: A utility for gathering the public SSH host keys of a number of hosts. Aids in building and verifying ssh_known_hosts files
- ssh-keysign: Used by ssh to access the local host keys and generate the digital signature required during host-based authentication.
Securing OpenSSH
A secure OpenSSH configuration demands for the generation of secure ssh keys, having appropriate permissions to these key files and having appropriate settings in sshd_config file.
SSH keys
OpenSSH server supports various authentication. It is recommended that you use public key-based authentication. DSA and RSA 1024 bit or lower ssh keys are considered as weak. Ideally use 4096 bit RSA ssh keys.
ssh-keygen -t rsa -b 4096
Ensure the permissions on these generated ssh private key file is set. The UID for this file should be 0/root and GID should also be 0/root. Also, permissions related to these files should be 0600.
chown root:root ~/.ssh/id_rsachmod 0600 ~/.ssh/id_rsa
Similarly, the ssh public key file should also have the appropriate permissions. The ownership should be given to root user and permissions should be 644 so that it does not allow any other user the permission to modify or execute the file.
chown root:root ~/.ssh/id_rsa.pubchmod 0644 ~/.ssh/id_rsa.pub
sshd config file
sshd_config is the file that is used for configuring the ssh daemon running on our host and that listens and handles any ssh connection. The config settings in sshd_config should be appropriate for secure and authenticated communication between systems. Once the changes are applied, sshd config should be reloaded to apply these changes.
systemctl reload sshd
File permissions for sshd_config
The file /etc/ssh/sshd_config is used for configuring ssh daemon. We want to make sure that this file is only accessible by the root and no other user has read, write or execute permissions on it.
chown root:root /etc/ssh/sshd_configchmod og-rwx /etc/ssh/sshd_config
SSH protocol version
Earlier versions of ssh support protocols ssh v1 and ssh v2. Protocol ssh v1 contained security issues(A design flaw in the SSH-1 protocol allows a malicious server to establish two concurrent sessions with the same session ID, allowing a man-in-the-middle attack) that were resolved in ssh v2 protocol. We need to make sure that our daemon uses ssh v2. Edit /etc/ssh/sshd_config file and set parameter as:
Protocol 2
Setting appropriate LogLevel
SSH provides several levels of verbosity for logging. The possible values are QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. The default is INFO. VERBOSE level specifies that login and logout activity, as well as the key fingerprint for any SSH key used for login, will be logged. So, VERBOSE logging level is recommended. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. Logging with a DEBUG level violates the privacy of users and is not recommended. Edit /etc/ssh/sshd_config file and set parameter as:
LogLevel VERBOSE
Disabling X11 forwarding
X11 forwarding is a mechanism that allows a user to start up remote applications but forward the application display to your local Windows machine. The security risk of using X11 forwarding is that the client’s X11 display server may be exposed to attack when the SSH client requests forwarding. Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own forwarders. Edit /etc/ssh/sshd_config file and set parameter as:
X11Forwarding no
Enabling max tries limit
Specifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged in the syslog file. MaxAuthTries is the parameter used to specify this. The default value of this parameter is 6. According to some standard benchmarks, it is recommended to keep this at 4. Edit /etc/ssh/sshd_config file and set parameter as:
MaxAuthTries 4
Disabling the use of .rhosts and .shosts file
The .rhosts, .shosts, hosts.equiv, and shosts.equiv files are used to configure host-based authentication for individual users or the system. Host-based authentication is not sufficient for preventing unauthorized access to the system. The IgnoreRhosts parameter specifies that .rhosts and .shosts files will not be used in RhostsRSAAuthentication or HostbasedAuthentication. Edit /etc/ssh/sshd_config file and set parameter as:
IgnoreRhosts yes
Disable HostbasedAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed (host-based authentication). Edit /etc/ssh/sshd_config file and set parameter as:
HostbasedAuthentication no
Disable direct root login
Specifies if a user can log in as root into your system. The allowed arguments are yes, prohibit-password, forced-commands-only, or no. The default is prohibit-password. If this option is set to prohibit-password (or its deprecated alias, without-password), password and keyboard-interactive authentication are disabled for root. If this option is set to forced-commands-only, root login with public key authentication will be allowed, but only if the command option has been specified (which may be useful for taking remote backups even if root login is normally not allowed). All other authentication methods are disabled for root. If this option is set to no, root is not allowed to log in. The option here to set is no. Edit /etc/ssh/sshd_config file and set parameter as:
PermitRootLogin no
Disabling empty passwords
When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The value of this parameter should be no as it is highly vulnerable for the system as an attacker can log in just by knowing someone’s username. Edit /etc/ssh/sshd_config file and set parameter as:
PermitEmptyPasswords no
Restricting ssh users from setting an environment variable
Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by ssh. Valid options are yes, no or a pattern-list specifying which environment variable names to accept (for example “LANG,LC_*”). Permitting users the ability to set environment variables through the SSH daemon could potentially allow users to bypass security controls. Edit /etc/ssh/sshd_config file and set parameter as:
PermitUserEnvironment no
Use of strong Ciphers
Multiple ciphers must be comma-separated. If the specified list begins with a ‘+’ character, then the specified ciphers will be appended to the default set instead of replacing them. If the specified list begins with a ‘-’ character, then the specified ciphers (including wildcards) will be removed from the default set instead of replacing them. If the specified list begins with a ‘^’ character, then the specified ciphers will be placed at the head of the default set.
The supported ciphers are:
- 3des-cbc
- aes128-cbc
- aes192-cbc
- aes256-cbc
- aes128-ctr
- aes192-ctr
- aes256-ctr
- aes128-gcm@openssh.com
- aes256-gcm@openssh.com
- chacha20-poly1305@openssh.com
A good explanation of weak Ciphers as mentioned in CIS benchmarks:
Weak ciphers that are used for authentication to the cryptographic module cannot be relied upon to provide confidentiality or integrity, and system data may be compromised.The DES, Triple DES, and Blowfish ciphers, as used in SSH, have a birthday bound of approximately four billion blocks, which makes it easier for remote attackers to obtain cleartext data via a birthday attack against a long-duration encrypted session, aka a "Sweet32" attack.The RC4 algorithm, as used in the TLS protocol and SSL protocol, does not properly combine state data with key data during the initialization phase, which makes it easier for remote attackers to conduct plaintext-recovery attacks against the initial bytes of a stream by sniffing network traffic that occasionally relies on keys affected by the Invariance Weakness, and then using a brute-force approach involving LSB values, aka the "Bar Mitzvah" issue.The passwords used during an SSH session encrypted with RC4 can be recovered by an attacker who is able to capture and replay the session.Error handling in the SSH protocol; Client and Server, when using a block cipher algorithm in Cipher Block Chaining (CBC) mode, makes it easier for remote attackers to recover certain plaintext data from an arbitrary block of ciphertext in an SSH session via unknown vectors.The mm_newkeys_from_blob function in monitor_wrap.c, when an AES-GCM cipher is used, does not properly initialize memory for a MAC context data structure, which allows remote authenticated users to bypass intended ForceCommand and login-shell restrictions via packet data that provides a crafted callback address.
The approved list of Ciphers according to CIS benchmarks are configured as shown below:
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128- gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
Using strong MAC(message authentication code) algorithms
The MAC algorithm is used for data integrity protection. An attacker that breaks the algorithm could take advantage of a MiTM position to decrypt the SSH tunnel and capture credentials and information.
The supported MACs are:
- hmac-md5
- hmac-md5–96
- hmac-sha1
- hmac-sha1–96
- hmac-sha2–256
- hmac-sha2–512
- umac-64@openssh.com
- umac-128@openssh.com
- hmac-md5-etm@openssh.com
- hmac-md5–96-etm@openssh.com
- hmac-sha1-etm@openssh.com
- hmac-sha1–96-etm@openssh.com
- hmac-sha2–256-etm@openssh.com
- hmac-sha2–512-etm@openssh.com
- umac-64-etm@openssh.com
- umac-128-etm@openssh.com
Below is the configuration that needs to be done for enabling secure MAC algorithms to be used as specified in CIS benchmarks:
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2- 512,hmac-sha2-256
Setting idle timeout
ClientAliveCountMax Sets the number of client alive messages which may be sent without sshd receiving any messages back from the client. If this threshold is reached while client alive messages are being sent, sshd will disconnect the client, terminating the session. It is important to note that the use of client alive messages is very different from TCPKeepAlive. The client alive messages are sent through the encrypted channel and therefore will not be spoofable. The TCP keepalive option enabled by TCPKeepAlive is spoofable. The client alive mechanism is valuable when the client or server depend on knowing when a connection has become unresponsive.
ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, sshd will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client.
Having no timeout value associated with a connection could allow an unauthorized user access to another user’s ssh session (e.g. user walks away from their computer and doesn’t lock the screen). Setting a timeout value at least reduces the risk of this happening. While the recommended setting is 300 seconds (5 minutes). The recommended setting for ClientAliveCountMax is 0. In this case, the client session will be terminated after 5 minutes of idle time and no keepalive messages will be sent. Edit /etc/ssh/sshd_config file and set parameter as:
ClientAliveInterval 300ClientAliveCountMax 0
Setting grace time for logins
The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. The default is 120 seconds. Setting the LoginGraceTime parameter to a low number will minimize the risk of successful brute force attacks to the SSH server. It will also limit the number of concurrent unauthenticated connections. The recommended value for this is 60 seconds. Edit /etc/ssh/sshd_config file and set parameter as:
LoginGraceTime 60
Limiting ssh access
There are many options that can be used to limit the users that can access the systems using ssh. It is a good practice to implement at least one of these options:
- AllowUsers
- DenyUsers
- AllowGroups
- DenyGroups
Restricting which users can remotely access the system via SSH will help ensure that only authorized users access the system.
Disabling TCP forwarding
SSH port forwarding is a mechanism in SSH for tunneling application ports from the client to the server or servers to clients. Leaving port forwarding enabled can expose the organization to security risks and back- doors. Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. Edit /etc/ssh/sshd_config file and set parameter as:
AllowTcpForwarding no
Limiting maximum ssh sessions
The maximum number of open ssh sessions that are permitted can be limited to protect the system from denial-of-service attack due to large number of concurrent sessions. The maximum number as specified by the CIS benchmarks is 4, but this may vary depending upon your organizations requirement. Edit /etc/ssh/sshd_config file and set parameter as:
MaxSessions 4
These were some of the critical controls that must be implemented for configuring a secure OpenSSH installation. Implementing these controls onto all the systems of an organization is a huge task. Configuration management tools like CHEF, Ansible help to achieve this. I have written an Ansible playbook which implements all the controls mentioned above.