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:
Dedicated terminal-user
Root login is disabled
Host-based authentication is disabled
Empty passwords are disabled
Public-Key Authentication is enabled
Max-auth attempts is set to 5
Idle-Timeout is set to 5 minutes
X11 Forwarding is disabled
Port Forwarding is disabled
Max concurrent sessions is set to 5
Log level is set to verbose (audit trail)
Warning banner is set to scare-of threat-actors
First Steps
Before applying the config file mentioned below, make sure to take the followings steps to prevent getting locked out from the Server:
Create a ‘terminaluser’ with a home directory and shell access
sudo useradd -m -s /bin/bash terminaluser
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
Create a
.ssh
directory in the terminaluser’s home directory and add anauthorized_keys
file.
mkdir /home/terminaluser/.ssh
touch /home/terminaluser/.ssh/authorized_keys
Set the appropriate permissions for the
.ssh
directory and theauthorized_keys
file:
chmod 700 /home/terminaluser/.ssh
chmod 600 /home/terminaluser/.ssh/authorized_keys
Make sure the ownership of the
.ssh
directory is set up correctly:
chown -R terminaluser:terminaluser /home/terminaluser
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:
Generate a new SSH-key:
ssh-keygen -t rsa -b 4096
Press enter to save the keys in the default location '~/.ssh’
Enter a strong and unique passphrase when prompted. Save it in Keeper.
Make sure the permissions are set correctly:
chmod 600 ~/.ssh/id_rsa #Private Key
chmod 644 ~/.ssh/id_rsa.pub #Public Key
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
Post a Comment