OpenSSH is also known as OpenBSD Secure Shell, released under simplified BSD License, is used to provide secure network communications via encrypting network traffic.
Encrypting all traffic provides extra security from network sniffing and other attacks and it is available for multiple platforms.
We can also implement SSH port forwarding to provide protection to data which would otherwise be transferred insecurely.
For more details, please read More About OpenSSH.
Here are some other similar posts on security harden your Server and Applications which you should check.
- Configure AIDE-Advanced Intrusion Detection Environment to Secure your Server.
- Top 10 PHP Security best practices for Linux sys administrators.
The OpenSSH suite consists of many tools:
- ssh, scp and sftp for authentication and transferring data securely.
- ssh-add, ssh-keyscan and ssh-keygen for creating and managing keys.
- sshd, ssh-agent and sftp-server for managing services.
We use OpenSSH tools almost daily for various tasks, from logging in to the remote server to transferring data between servers.
SSH server is widely used for server authentication. It’s very secure but we can still do some tweaks to make it more secure.
Here are a few things we can tweak in order to make OpenSSH server more secure.
Installation of OpenSSH in Linux.
To install OpenSSH, run these commands with superuser permissions in the terminal.
For Ubuntu/Debian, use:
shell> apt-get install openssh-server openssh-client -y
For RHEL/Centos/Fedora, use:
Type the following yum command to install OpenSSH client and server.
shell> yum install openssh-server openssh-clients -y
Configuration File of SSH.
The SSH server configuration files are located in /etc/ssh/ directory. we can edit /etc/ssh/sshd_config file to make it more secure.
Before making any changes to the sshd_config file we will take a backup of this file.
shell> cp /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +%Y-%m-%d)
now we can start editing SSH configuration file.
Use only SSH protocol 2.
One of the most important things to do is use the secure version of SSH protocol > SSHv2.
SSHv2 is an improved version of SSHv1. SSHv2 has a number of new features like Encryption ciphers and support for public key certificates to provide more security.
To use SSHv2 we can edit /etc/ssh/sshd_config and change
# The default requires explicit activation of protocol 1
Protocol 2,1
to
# The default requires explicit activation of protocol 1
Protocol 2
Change SSH Port.
By default, SSH listens for connections on Port 22 which is the first port Attackers use to attack. We will change it to some random Private Port number from 49152 through 65535.
Edit the /etc/ssh/sshd_config file and change this line:
Port 22
to
Port 50150
Now we will configure Firewall to allow this port.
for Iptables:
shell> iptables -A INPUT -p tcp -m tcp --dport 50150 -j ACCEPT shell> /sbin/service iptables save
for Firewalld.
shell> firewall-cmd --zone=public --add-port=50150 --permanent shell> firewall-cmd --reload
If you’re using CentOS or Red hat and you have SELinux in enforcing mode then you also need to configure SELinux to allow new SSH Port.
shell> semanage port -a -t ssh_port_t -p tcp 50150
(If your server has only 512MB RAM then you need to Create at least 1GB swap space to finish this operation.)
Now restart the SSH service:
shell> /etc/init.d/ssh restart
or
shell> systemctl restart sshd.service
Try to do ssh access using new port 50150:
shell> ssh -p 50150 root@198.123.231.111
Create a custom SSH banner.
You can create a banner to convey a specific message to your users. To do this create a text file and put your message into it.
This is my favorite one which I found on the Internet. Simple and effective.
shell> vi /etc/ssh/banner.text ************************************************************************************* *The use of this SSH service is restricted to authorized user's only.* *All the acitvities on this SSH server will be logged.* *************************************************************************************
Save this file and then edit sshd_config.
shell> vi /etc/ssh/sshd_config # no default banner path #Banner none Banner /etc/ssh/banner.txt
Restrict the root account to console access only.
There’s a big debate on whether you should allow root logins via SSH or not. If you don’t want root logins via SSH then you need to change this:
shell> vi /etc/ssh/sshd_config
PermitRootLogin no
Make sure you have another user that can switch to superuser. ( make sure user is a part of wheel group )
Allow only specific users via SSH.
By default, all users can log in using SSH. But if you want to allow the only specific user’s to login via SSH then you can use AllowUsers and DenyUsers to configure that.
If you want only “mohan” and “john” to log in to the system via SSH then use:
AllowUsers root mohan john
Similarly, if you don’t want a user, say “Jingping” to access system through SSH then use:
DenyUsers jingping
Prevent Unattended SSH Sessions.
set up an idle timeout interval in seconds to avoid unattended SSH sessions.
shell> vi /etc/ssh/sshd_config ClientAliveInterval 600 # 10 minutes ClientAliveCountMax 0
After 10 mins of inactivity, the user will be logged out automatically.
Disable user’s .rhosts files.
Since we are using SSH we will disable .rhosts authentication which will prevent users from using the obsolete rsh commands such as rcp and rsh on the local system without a password.
shell> vi /etc/ssh/sshd_config
IgnoreRhosts yes
Disable Host-Based Authentication.
Host-Based authentication is a security risk and is disabled by default. If it’s not disabled by default then you can disable it by:
shell> vi /etc/ssh/sshd_config
HostbasedAuthentication no
Set a login grace timeout
We will set “LoginGraceTime” to specify how long after a connection request the SSH server will wait before disconnecting. By default, it is set to 2 minutes in SSH config file but we will change it to 60 seconds.
we can change this value by editing following line:
LoginGraceTime 60
Configure SSH logging level.
By default, SSH logs everything. Depending upon the amount of information you want, you can change the value from INFO to VERBOSE.
we can change this value by editing following line:
shell> vi /etc/ssh/sshd_config
LogLevel VERBOSE
Disable Empty Passwords.
For security reasons, we will deny login from accounts with empty (blank) passwords. By default this option is disabled, if not then we can change this value by editing following line:
PermitEmptyPasswords no
Secure SSH using TCP wrappers.
TCP wrappers are useful in providing host-based access control system which can be used to limit network access to the internet.
we can use /etc/hosts.allow or /etc/hosts.deny to allow or deny SSH from specific IP address(s).
To allow SSH only from specific IP address for e.g 192.168.231.1, 172.16.30.13 we can edit /etc/hosts.allow file as following.
shell> vi /etc/hosts.allow
sshd : 192.168.231.1 172.16.30.13
To deny access to the bad guy we can use.
shell> vi /etc/hosts.deny
ALL: 192.168.231.2
Restrict SSH logins to specific IP address(s).
If you have more than one interface on your machine and you want SSH server to listen only on a specific Interface or IP Address then you can easily do this by editing the sshd_config file.
You can also configure SSH server to listen on multiple IP addresses of the machine. We can force SSH server to listen only on a specific Ip Address of our machine, we can do this by editing the following line.
To make SSH server listen only on Ip address 192.168.111.22,
ListenAddress 192.168.111.22
To verify this use,
[root@debyum ~]# ss -plant | grep ssh
LISTEN 0 128 192.168.111.22:50150 *:* users:(("sshd",pid=28189,fd=3))
ESTAB 0 36 192.168.111.22:50150 112.211.73.45:62857 users:(("sshd",pid=28062,fd=3))
If you want to add another Ip address 192.168.111.33 in this list then just add another line like.
ListenAddress 192.168.111.22 ListenAddress 192.168.111.33
Secure SSH with the help of Firewall.
Before we make any changes in rules of firewall, You may like to save your rules;
shell> sudo iptables-save > firewall-old-rules.txt.
Now we can configure Firewall to secure SSH server by allowing only Allowed Ip address and Limit the number of attempts that can be made in a given time frame for SSH connection on a port.
If you want to allow connection only from a specific IP ADDRESS like e.g 192.168.231.21, then we can use;
shell> iptables -A INPUT -p tcp -m state --state NEW --source 192.168.231.21 --dport 50150 -j ACCEPT
If you want to allow connection only from a specific subnet like e.g 192.168.231.0/25 which allows about 62 IP addresses then we can use ;
shell> iptables -A INPUT -s 192.168.231.0/25 -m state --state NEW -p tcp --dport 50150 -j ACCEPT
where SSH Port no is 50150 and subnet we allow is 192.168.231.0/25
we can also configure Firewall to limit the number of incoming connections for SSH port within a time frame.
Here we will configure the firewall to allow only 3 connection attempts on SSH port 50150 within 30 seconds. This will drop all the incoming connections which will try to make more than 3 connection attempts on SSH port 50150 within 30 seconds.
Rate-limit the incoming SSH port connections.
We can configure firewall’s rate-limit option to control the incoming connections on SSH port.
shell> iptables -A INPUT -i eth0 -p tcp --dport 50150 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT shell> iptables -A INPUT -i eth0 -p tcp --dport 50150 -m state --state ESTABLISHED -j ACCEPT shell> iptables -A OUTPUT -o eth0 -p tcp --sport 50150 -m state --state ESTABLISHED -j ACCEPT
we can also configure iptables to allow only three connection attempts on port 50150 within 30 seconds:
shell> iptables -I INPUT -p tcp --dport 50150 -i eth0 -m state --state NEW -m recent --set shell> iptables -I INPUT -p tcp --dport 50150 -i eth0 -m state --state NEW -m recent --update --seconds 30 --hitcount 3 -j DR
To implement the same with Firewalld you need to follow these steps.
Setup a xt_recent configuration file.
we will create a file /etc/modprobe.d/xt_recent.conf.
shell> vi /etc/modprobe.d/xt_recent.conf
options xt_recent ip_pkt_list_tot=30
Now we will reinstall the xt_recent module.
sehll> sudo modprobe -r xt_recent shell> sudo modprobe xt_recent
( you need to repeat these steps everytime you want to change the xt_recent config.)
Now we can add these rules to rate-limit the incoming connection in firewall-cmd.
shell> firewall-cmd --permanent --direct --add-rule ipv4 filter Rate_limit 0 -p tcp --dport 50150 -m state --state NEW -m recent --set success shell> firewall-cmd --permanent --direct --add-rule ipv4 filter Rate_limit 1 -p tcp --dport 50150 -m state --state NEW -m recent --update --seconds 30 --hitcount 3 -j REJECT --reject-with tcp-reset success shell> firewall-cmd --reload
Hide the last login.
You can also hide last login user by editing the following line.
shell> vi /etc/ssh/sshd_config
PrintLastLog no
Configure Port forwarding.
If you don’t need Port Forwarding then it’s better to disable it.
we can disable this by setting these values:
AllowTcpForwarding no X11Forwarding no
Setting up maximum startup connections.
we can configure sshd_config file to setup a limit on concurrent connections to the SSH Daemon.
This is very useful to protect SSH server from Brute-Force Attack.
We will allow here, for this example, only 2 concurrent connections.
MaxStartups 2
Log in with SSH keys instead of a password.
Using Password for SSH authentication is not recommended and is insecure. A weak password can compromise the security of your server. Alternative is to use SSH keys for authentication.
Here’s how we can create and use SSH keys for authentication. ( we will use the simplest and fastest way)
Generate SSH keys
we will generate SSH keys on your client machine by running the following command:
[root@engy ~]$ ssh-keygen -b 2048 -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
f0:12:1f:0b:17:28:1c:e4:bc:f2:c5:54:a7:36:b9:53 root@engy
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| . |
| . + |
| . . S |
| + o + .* . +. |
| . * . + .*.* |
| . ..+ +E+.o |
| ooo .. |
+-----------------+
Copy the public key file to your remote server.
Before copying the Public key file we will first create the SSH folder on our remote server.
[debyum@server-ip-address ~]$ mkdir -p ~/.ssh/
Now we will copy the public key from host to the authorized_keys file on the destination Server e.g debyum@server-ip-address
shell> scp -p /root/.ssh/id_rsa.pub debyum@server-ip-address:/home/debyum/.ssh/authorized_keys
On server:
Now we will secure these keys by using these steps.
[debyum@server-ip-address ~]$ chmod 700 .ssh [debyum@server-ip-address ~]$ chmod 600 .ssh/authorized_keys
Now you can log into your SSH server without a password.
shell> ssh -p 50150 debyum@serverip-address
Keep OpenSSH server up-to-date.
For security purposes, it’s very important to keep your server up-to-date with latest security patches.
Conclusion
There is other software which you can use to help secure your OpenSSH server like fail2ban which once configured, automatically scans log files and bans IPs that show the malicious signs.
I have tried to cover all the basic to advance concepts with their examples. Still, if I have missed anything please update us through comment box to help your fellow readers. I will keep updating the same based on feedback’s received. Thanks.
Thanks for visiting this Page and have a Great day. 🙂