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
-
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"
. -
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 keyserverx.pub
. -
Ensure the permissions are correct:
chmod 700 ~/.ssh chmod 600 ~/.ssh/serverx
-
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
Links
- http://wiki.centos.org/HowTos/Network/SecuringSSH
- http://techie-buzz.com/foss/change-default-ssh-port-in-linux.html
- https://wiki.archlinux.org/index.php/Using_SSH_Keys