SSH Security

Use strong passwords

Strong passwords consist of a string that no hacker could guess either by chance or through a brute force attack within a few hours.

Try to choose passwords with:

  • At least 15 characters.
  • Combination of letters (uppercase and lowercase), numbers, and non-alphanumeric characters.

There are programs like pwgen, makepasswd, apg, KeePassX, and Unix commands that generate secure random passwords:

tr -dc '_A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' < /dev/urandom | head -c25
pwgen -cnsy 25 1

Options for pwgen:

  • -c: at least one uppercase letter.
  • -n: at least one numeric character.
  • -s: at least one special character.
  • -y: exclude ambiguous characters (like l, 1, I, 0, O, etc.).
  • 25: password length.
  • 1: number of passwords to generate.

The passwords generated by these programs are indeed secure. However, they are very difficult to remember, which means you will have to write them down somewhere. Therefore, I strongly recommend that you create a long passphrase that you (and only you) can memorize.

Disable root login via SSH

  • Edit the following line in the file /etc/ssh/sshd_config:

    PermitRootLogin no
    
  • Restart the daemon:

    sudo /etc/rc.d/sshd restart
    

    or, if you use systemd:

    julio@acer ~> sudo systemctl restart sshd
    

When you need root access, use the su command.

Limit who can log in via SSH

This is useful when only a few users need to access the system via SSH. Add the following line to /etc/ssh/sshd_config:

AllowUsers usr_1 usr_2 usr_3

Disable “Protocol 1”

SSH has two protocols. Since Protocol 1 is old and insecure, uncomment the line Protocol 2.

Change the port

By default, the port used for ssh is 22. Change it to some random number, preferably above 1024. Example: Port 2345

Note that from now on we will always have to inform which port to connect to:

ssh -p 2345 julio@home.juliobs.com

Here I also had to open the port (only TCP) on my router.

Use a firewall

We can configure iptables to allow only specific IPs to connect to the port used for SSH:

iptables -A INPUT -p tcp -s 201.43.81.111 --dport 22 -j ACCEPT

I cannot use the option above here, as I frequently need to connect from different IPs. Therefore, a more interesting solution is to limit the number of attempts coming from the same IP.

Logs the IP that tried to access port 22 and rejects packets if the same IP has tried to connect 4 times or more in the last minute:

iptables -A INPUT -p tcp --dport 22 -m recent --set --name ssh --rsource

iptables -A INPUT -p tcp --dport 22 -m recent ! --rcheck --seconds 60 \
         --hitcount 4 --name ssh --rsource -j ACCEPT

Cancels the connection if the same IP tries to connect more than 3 times on port 22 in the same minute:

iptables -A INPUT -p tcp --dport 22 --syn -m limit --limit 1/m --limit-burst 3 -j ACCEPT

iptables -A INPUT -p tcp --dport 22 --syn -j DROP

Use public/private keys for authentication

  1. Create a key:

    $ ssh-keygen -t rsa -b 4096 -f servidorx -C "pubkey para servidor X"
        Generating public/private rsa key pair.
        Enter passphrase (empty for no passphrase):
        Enter same passphrase again:
        Your identification has been saved in servidorx.
        Your public key has been saved in servidorx.pub.
        The key fingerprint is:
        e1:5c:44:b2:f4:48:c7:22:62:16:99:fb:44:11:23:a7 pubkey para servidor X
        The key's randomart image is:
        +--[ RSA 4096]----+
        |    o+=o+o+      |
        |    *+o+.B.      |
        |   oE+ .+.o      |
        |    . .o o       |
        |     o  S        |
        |      .          |
        |                 |
        |                 |
        |                 |
        +-----------------+
    

    The default algorithm for ssh-keygen is RSA 2048 bits, in this example I used RSA 4096 bits. It may be an overkill, but you never know.

    2020 Update: RSA 4096 is still secure, but the recommended is Ed25519: ssh-keygen -t ed25519 -f serverx -C "pubkey".

  2. Copy the key to the remote server.

    ssh-copy-id -i serverx.pub '-p 2345 julio@serverx.com'
    

    This command is equivalent to appending the ~/.ssh/authorized_keys file on the remote server with the public key serverx.pub.

  3. Ensure the permissions are correct:

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/serverx
    
  4. Create the ~/.ssh/config file, which contains some per-host configurations, shortcuts, and useful aliases:

    Host github.com
        HostName        github.com
        IdentityFile    ~/.ssh/github
        User            jbsilva
    
    Host juliobs.com
        HostName        juliobs.com
        IdentityFile    ~/.ssh/juliobs
        User            julio
    
    Host servidorx
        HostName        ssh.servidorx.com
        IdentityFile    ~/.ssh/servidorx
        User            usuariox
        Port            2345
    

This file makes our lives a little easier, as we no longer need to remember the username, the full server address, or the port.

Instead of connecting to serverX using:

ssh -i serverx -p 2345 userx@ssh.serverx.com

We can simply:

ssh serverx

Julio Batista Silva
Julio Batista Silva
Data Engineer

I’m a computer engineer passionate about science, technology, photography, and languages. Currently working as a Data Engineer in Germany.

comments powered by Disqus