SSH Security Configuration for Servers

Introduction

Secure Shell (SSH) is a crucial component for remote access to Server Instance, and its configuration should be optimized to ensure the highest level of security. Given the role SSH plays in facilitating secure communication and access to servers, it is strongly recommended to implement robust security measures to protect sensitive data and prevent unauthorized access to these Servers.

The current configuration enforces the following security measures:

Check Mark Dedicated terminal-user

Check Mark Root login is disabled

Check Mark Host-based authentication is disabled

Check Mark Empty passwords are disabled

Check Mark Public-Key Authentication is enabled

Check Mark Max-auth attempts is set to 5

Check Mark Idle-Timeout is set to 5 minutes

Check Mark X11 Forwarding is disabled

Check Mark Port Forwarding is disabled

Check Mark Max concurrent sessions is set to 5

Check Mark Log level is set to verbose (audit trail)

Check Mark Warning banner is set to scare-of threat-actors winking face

First Steps

Before applying the config file mentioned below, make sure to take the followings steps to prevent getting locked out from the Server:

  1. Create a ‘terminaluser’ with a home directory and shell access

sudo useradd -m -s /bin/bash terminaluser
  1. Set a unique strong password for this user and save it in Keeper with the following naming convention: Server  Provider - <ServerName> - terminaluser

sudo passwd terminaluser
  1. Create a .sshdirectory in the terminaluser’s home directory and add an authorized_keysfile.

mkdir /home/terminaluser/.ssh touch /home/terminaluser/.ssh/authorized_keys
  1. Set the appropriate permissions for the .ssh directory and the authorized_keys file:

chmod 700 /home/terminaluser/.ssh chmod 600 /home/terminaluser/.ssh/authorized_keys
  1. Make sure the ownership of the .ssh directory is set up correctly:

chown -R terminaluser:terminaluser /home/terminaluser
  1. Add the public-keys of all authorized devices (ZeroBit Member workstations) in the authorized_keys file. Note that these public-keys are saved in Keeper as a secured note.

Help, I don’t have an SSH public-private key pair on my workstation?

No problem, follow these steps:

  1. Generate a new SSH-key:

ssh-keygen -t rsa -b 4096
  1. Press enter to save the keys in the default location '~/.ssh’

  2. Enter a strong and unique passphrase when prompted. Save it in Keeper.

  3. Make sure the permissions are set correctly:

chmod 600 ~/.ssh/id_rsa #Private Key chmod 644 ~/.ssh/id_rsa.pub #Public Key
  1. Add your public key to the secured note in keeper (Digital Ocean - SSH - authorized_keys).

Config File

The following sshd_config file, based on the rules mentioned on this page can be used on our Servers:

# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. # This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin # The strategy used for options in the default sshd_config shipped with # OpenSSH is to specify options with their default value where # possible, but leave them commented. Uncommented options override the # default value. Include /etc/ssh/sshd_config.d/*.conf #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_ecdsa_key #HostKey /etc/ssh/ssh_host_ed25519_key # Ciphers and keying #RekeyLimit default none # Logging #SyslogFacility AUTH LogLevel VERBOSE # Authentication: AllowUsers terminaluser#LoginGraceTime 2m PermitRootLogin no #StrictModes yes MaxAuthTries 5 MaxSessions 5 PubkeyAuthentication yes # Expect .ssh/authorized_keys2 to be disregarded by default in future. #AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 #AuthorizedPrincipalsFile none #AuthorizedKeysCommand none #AuthorizedKeysCommandUser nobody # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts HostbasedAuthentication no # Change to yes if you don't trust ~/.ssh/known_hosts for # HostbasedAuthentication #IgnoreUserKnownHosts no # Don't read the user's ~/.rhosts and ~/.shosts files IgnoreRhosts yes # To disable tunneled clear text passwords, change to no here! PasswordAuthentication no PermitEmptyPasswords no # Change to yes to enable challenge-response passwords (beware issues with # some PAM modules and threads) # OpenSSH 8.7p1 renamed ChallengeResponseAuthentication option to KbdInteractiveAuthentication # ChallengeResponseAuthentication no KbdInteractiveAuthentication no # Kerberos options #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosGetAFSToken no # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes #GSSAPIStrictAcceptorCheck yes #GSSAPIKeyExchange no # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass # the setting of "PermitRootLogin yes # If you just want the PAM account and session checks to run without # PAM authentication, then enable this but set PasswordAuthentication # and ChallengeResponseAuthentication to 'no'. UsePAM yes #AllowAgentForwarding yes AllowTcpForwarding no #GatewayPorts no X11Forwarding no #X11DisplayOffset 10 #X11UseLocalhost yes #PermitTTY yes PrintMotd no #PrintLastLog yes #TCPKeepAlive yes #PermitUserEnvironment no #Compression delayed ClientAliveInterval 300 #ClientAliveCountMax 3 #UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 #PermitTunnel no #ChrootDirectory none #VersionAddendum none # no default banner path Banner /etc/ssh/banner.txt # Allow client to pass locale environment variables AcceptEnv LANG LC_* # override default of no subsystems Subsystem sftp /usr/lib/openssh/sftp-server # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no # AllowTcpForwarding no # PermitTTY no # ForceCommand cvs server ClientAliveInterval 120

Create the ‘banner.txt’ file in ‘/etc/ssh’:

********************************************************************** * NOTICE TO USERS * ********************************************************************** * This computer system is the private property of MyCompany. * * It is for authorized use only. Users have no explicit or implicit * * expectation of privacy. All activities performed on this system * * are subject to monitoring, recording, and auditing. Any * * unauthorized access or use may result in criminal and civil * * penalties. By continuing to use this system, you indicate your * * awareness of and consent to these terms and conditions of use. * **********************************************************************

Rules

SSH Best practices which should be followed on all of our servers which require remote access:

1. Disable Root Login

This setting should be set by default, this makes it to where all root logins via SSH are unallowed. System administrators would log in via their user account and escalate via su or sudo commands. To verify this setting or modify it on your own, you can run nano /etc/ssh/sshd_config and set the PermitRootLogin parameter to no if it is not already done. To make sure the setting is applied, you'll need to restart the service using systemctl restart sshd or service sshd restart.

2. Disable SSH Protocol 1

SSH Protocol 1 should be disabled by default on newer versions of SSH and Linux. However, if you run an older version of either, ensure that only Protocol 2 is being used. Use nano /etc/ssh/sshd_config to edit the configuration file and look for the Protocol parameter and set it to 2.

This is disabled by default on our Servers.

3. Disable Host-Based Authentication

Host-based authentication is one method of controlling who and how someone can authenticate to your Linux server via SSH. It’s also not recommended; consider a machine that is compromised but is allowed access to your server. Threat actors now have the ability to log in via SSH to your Linux server thanks to host-based authentication. 

The Center for Internet Security (CIS) playbook recommends to  lock down this setting in favor of using public key-based authentication. To do this, run nano /etc/ssh/sshd_config to edit the SSH configuration file. Find the parameter HostBasedAuthentication and set it to no. Keep in mind that this setting applies only to SSH using Protocol 2, so make sure you are using this protocol version as mentioned above.

You can also ensure that setting the parameter IgnoreRHosts is set to yes to require your users to authenticate via an approved method. This parameter tells your SSH configuration to ignore the .rhosts and .shosts file.

4. Disable Empty Passwords

Make sure that all users authenticating with your Linux server via SSH have to use some form of authentication rather than an empty password string. To do this, type nano /etc/ssh/sshd_config into the command line, find the parameter PermitEmptyPasswords and ensure this is set to no

5. Enable and Use Public-Key-Based Authentication

Public key-based authentication is a great method for users to authenticate to your Linux servers using SSH. You’ll need to be able to generate key pairs (public and private key pairs) and lock down or at least audit changes to the home directory in which these key pairs are saved on your server.

Ideally you should both audit and lock down said folder. By default this folder is located here ~/.ssh/. Lock the folder down to just root and wheel using chown root:wheel ~/.ssh/id_rsa and chown root:wheel ~/.ssh/id_rsa.pub. Reviewing audit logs can help you ensure that no unauthorized changes are being made.

Make sure to add a passphrase to your ssh-key, this requires a valid public key + a valid passphrase in order to connect to the server.

6. Enforce a Limit to the Maximum Number of Authentication Attempts

Enabling a limit to the maximum number of authentication attempts through SSH mitigates the risk of a successful brute force attack within your environment. This is an easy control to put in place as it is simply editing a parameter within your SSH configuration file. To do this, use nano /etc/ssh/sshd_config, find the parameter MaxAuthTries and set it to a more appropriate value. The recommendation from CIS is four attempts or less. Currently set to 5.

7. Enforce an Idle Timeout

Leaving SSH sessions logged in and idle or unattended without a control can increase your attack surface. If an attacker were to gain access to a machine where an unattended SSH session was left open, it would be too easy for them to unleash a whole host of nefarious actions against your Linux SSH server.

To mitigate this risk, use nano /etc/ssh/sshd_config to adjust the parameters for ClientAliveInterval. This value is in seconds and determines the actual length of time before a timeout. A value of 300 or less is recommended for a five-minute session timeout.

8. Restrict SSH Access to Users/Groups That Need It

Keeping in mind the principle of least privilege, you should narrow the scope of who needs to connect via SSH into your servers. Managing the groups and users who can have this ability is easily accomplished in Linux.

One way is to access the AllowUsers and AllowGroups parameters within the /etc/ssh/sshd_config file. Then, populate the parameters with a list of the users and groups that exist on the server who should have access to SSH into your server. You can also leverage the DenyUsers and DenyGroups parameters to explicitly call out who cannot connect via SSH into your server. This should be configured to allow the terminaluser to log in. Make sure to add ‘nessus’ for automated vulnerability scanning.

9. Disable X11 Forwarding

With X11 forwarding, a remote user can access a graphical application installed on a Linux server. If left unchecked, hackers can use it to monitor other users’ keystrokes or perform malicious activity by opening other X11 connections to remote clients. It’s recommended to disable this. The parameter X11Forwarding should be set to no in the SSH configuration file. You can do this by running nano /etc/ssh/sshd_config and then modify the parameter. Restart your server or at least connect via SSH to make sure your configuration changes are applied.

10. Disable Port Forwarding

Local port forwarding via SSH can be used legitimately inside of an environment. Leaving this configuration on, however, can leave you exposed to a threat actor creating their own backdoor tunnels into your environment.

It is recommended that you disable this setting, which you can do inside of the SSH configuration file at this location /etc/ssh/sshd_config. The parameter for this particular setting is called AllowTcpForwarding, and setting this to no will prevent users from being able to exploit this feature in your environment

11. Limit the Maximum Number of Concurrent Sessions

Restricting the maximum number of open SSH sessions adds an extra layer of security by further hardening your SSH configurations. This can also mitigate a denial of service attack (DoS), especially if you know how many users are expected to be on the same server at the same time. The CIS recommendation is to limit this to a maximum of four concurrent connections. You can do this by running nano /etc/ssh/sshd_config and modifying the parameter maxsessions to four or less, depending on your needs. Currently set to 5.

12. Change Log Level of SSH in Linux

Ensuring that SSH is logging appropriately can help find potential bad actors. It’s important to have just the right amount of information, as this will make it easier to find the key security information that you need.

The default log level, INFO, records only user login activity and can leave you wanting for more information, especially if you are in the middle of responding to an incident. VERBOSE is preferred as it will detail logout time in addition to login time and other pertinent information. To change this, edit the LogLevel parameter and change the value from INFO to VERBOSE. You can do this by running nano /etc/ssh/sshd_config to edit the SSH configuration file.

13. Set a Warning Banner

Banner messages can be a deterrent for threat actors, since it places a stern warning to users who connect to your machine via SSH that their access is being logged and any unauthorized use will be tracked and prosecuted (in some environments this last part is of particular import). While this may not stop all potential attackers, it could deter some who see this and decide against proceeding.

To set a warning banner, edit your SSH configuration file at /etc/ssh/sshd_config and modify the Banner parameter to show the directory where to place your banner file with your warning message. Currently stored at ‘/etc/ssh/banner.txt’.

Aliases

Consider adding the following lines in ~/.zshrc (or your preferred shell configuration file):

alias ssh-staging="ssh terminaluser@xxx.xxx.xxx.xxx" alias ssh-prod="ssh terminaluser@xxx.xxx.xx.xxx"

This will potentially save you some time when trying to remotely access a server and having to find the relevant IP-address.

Don’t forget to source this new shell configuration:

source ~/.zshrc

Create sudo user

sudo useradd -m -s /bin/bash <project>user

Set a unique strong password for this user and save it in PasswordManager with the following naming convention: Service Provider - <ServerName> - <project>user

sudo passwd <project>user

Adding the User to the sudo Group, use the usermod command to add the user to the sudo group:

usermod -aG sudo <project>user

 

Comments

Popular posts from this blog

Mount StorageBox to the server for backup

psql: error: connection to server at "localhost" (127.0.0.1), port 5433 failed: ERROR: failed to authenticate with backend using SCRAM DETAIL: valid password not found

Keeping Your SSH Connections Alive: Configuring ServerAliveInterval and ServerAliveCountMax