When implementing a Linux server on the Internet, it generally sees many failed login activities from SSH logs. This is because a large number of automated bots exist on the Internet, they are actively brute force SSH service and break into the server. This article will discuss several ways to mitigate SSH brute force.


Change default port

    Change SSH default service port is the simplest and very effective way to mitigate brute force. Per test, after change of service port, the number of failed login reduced by more than half.

  1. Use text editor to open below file

    1. /etc/ssh/sshd_config
  2. Find line contain key word Port 22

    1. If the line commented, remove the # mark

  3. Change port number from 22 to the number you want, e.g. 26452

  4. Restart the SSH service


Restrict root login

    Some Linux distributions disabled SSH root password login by default, however there are scenarios need script remote login as root and run some commands. Thus, can either set permit root login to run specific commands or disabled root login.

    Note: key-based authentication must be enabled to support root login with running specific commands, you can refer next chapter to enable it.

  1. Use text editor to open below file

    1. /etc/ssh/sshd_config
  2. Find line contain key word PermitRootLogin

    1. If the line commented, remove the # mark

  3. If need to permit root login with running specific commands, update line as below

    1. PermitRootLogin forced-commands-only
  4. If need to disable root login, update line as below

    1. PermitRootLogin no
  5. Restart the SSH service


Enable key-based authentication

    The length of key-based authentication can be up to 4096 bits, which makes brute force more complex and difficult. The security level of 1024 bits key is equivalent to 12 characters complex password. Normally the key length is set to 2048 bits or more.

  1. Generate key pair files. Below example will create RSA key with 4096 bits, files will be saved into current user .ssh folder, private key file name is id_rsa, the public key file name is id_rsa.pub

    1. ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
    2. It will ask you to input passphrase. The passphrase is a "password" of private key file, it makes the key file can't be directly used when it is stolen. It's optional to input the passphrase, when leaves it as blank then passphrase disabled.

    3. After key pair created, you should able to see return similar as below.

    4. Generating public/private rsa key pair.
      Created directory '/home/user/.ssh'.
      Enter passphrase (empty for no passphrase): 
      Enter same passphrase again: 
      Your identification has been saved in /home/user/.ssh/id_rsa
      Your public key has been saved in /home/user/.ssh/id_rsa.pub
      The key fingerprint is:
      SHA256:tQ9k4hnHr3u0ghS3a4KfaXjO2yp4TgAIS9RQem5+804
      The key's randomart image is:
      +---[RSA 4096]----+
      |o++.             |
      |oo..     .       |
      |o...    o *      |
      |  o.   ..O.o     |
      |   o.   Soo..    |
      |  o  .  . .+.    |
      |   . +.E ..o..   |
      |    o.O.=++.o    |
      |     ooOO=oo     |
      +----[SHA256]-----+
  2. For OpenSSH server, rename public key file using below command. For other SSH server, copy public key file to a specific location

    1. mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
    2. If PermitRootLogin forced-commands-only set in SSH config, a command must be specified in the public key file. Open public key file with text editor, and add command="/bin/mycommand" before ssh-rsa

      1. command="/bin/mycommand" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC/cCccDgVZMfmSezu2bURTOlgLZLeKGHHtr2u3VYOX5baWJXQccSpU13xtbOXKKkx6G0e92F/gvMsoQdrzSRn3u4ZgyGoqgVg3lWTIe2tPPym6iZ164e6gXJzOyRsSsRdHgJv/DbNTwwPxPriYkMTFnMeinoZQhgEjGuV5X22QxAEo71NLWwMzJOfVuU0laB8JphxDvRKBWzPlR298mzE7pnVmOCgtTMEFyWvt4FXUyQno1crsG+759nmwKJVVwdRrFC0BqFVQ4e6j9A4P6FLTJGDVE/swm+fncgXAH7E9vjNHuw3M8QGdaa9wqyLnBEoV1Tl6IiI/ZgastC4SM12vqFj5lDmyl7qMm99ojii4q6Qb0T2HO2U71TkSuta0DkEgusoghXuOGYPnZBLs3M6bx/SmSJQzkjp3QwUwhJUiKwpMbxYU048Vx0EAJIMKrGf0Xn4xZJfH0UYNQuJgO/P2ktvMSgrdFpZ6/x8Gea0f7WU8ARV6tZ4Ackjp7M2nYeis9H1OAniUYxcPdJYFQo01Si4zyavJV/YNkigpu7DDfjX9z1RKiwf9fSb7FhKVD45PQlg1UgLlWnXneQbsjIIj9e/g5YsV+rZqMA6YzHxwfB57rWd+uBfejfSdh7D0OkqvuzelOgHWtGs+8nUcIr5oSHlcLyvtGiz3OWWNGGmyLQ==
  3. Copy private key file to SSH client and removes the private key files from SSH server

  4. Update SSH config to disable password login

    1. Use text editor to open below file

      1. /etc/ssh/sshd_config
    2. Find line contain key word PasswordAuthentication.

      1. If the line commented, remove the# mark

    3. Update line as below

      1. PasswordAuthentication no
    4. Restart the SSH service


Install fail2ban

    Fail2ban is a tool can dynamically block clients that fail to authenticate correctly with your services repeatedly. We could leverage it to mitigate SSH brute force.

  1. Install fail2ban with below commands on Debian/Ubuntu distribution. For other Linux distributions, you can search google to install

    1. sudo apt-get update 
      sudo apt-get install fail2ban
  2. Create a configuration file

    1. Create jail.local file on /etc/fail2ban/

      1. sudo touch /etc/fail2ban/jail.local
    2. Open jail.local with text editor, copy and paste below content into jail.local file

      1. [sshd] 
        enabled = true 
        port = 22 
        filter = sshd 
        logpath = /var/log/auth.log 
        maxretry = 5 
        findtime  = 60m 
        bantime   = 1d
      2. Change the port number to the SSH service port

      3. Logpath is the SSH login logs file, on Debian/Ubuntu distribution the default path is /var/log/auth.log, on Redhat distribution the default path is /var/log/secure

      4. Maxretry is the maximum numbers attempts of failed login from a single IP, above setting is 5 times

      5. Findtime is the time range to find failed login, above setting is 60 minutes

      6. Bantime is thetime of IP to be banned from accessing your SSH service, above setting is 1 day

    3. Save file

  3. Restart fail2ban service, you should able to see failed login and ban IP activities from file /var/log/fail2ban.log