+++ date = "2019-02-10T21:37:32+00:00" publishdate = "2023-12-29T07:08:55+00:00" title = "Extreme SSH Hardening" slug = "extreme-ssh-hardening" author = "Thedro" tags = ["ssh","sysadmin"] type = "posts" summary = "SSH (Secure Shell) is a great tool, but if you ever expose SSH to the internet, you'll soon discover a multitude of internet bots and bad actors pummeling your server." draft = "" syntax = "1" toc = "" updated = "2020-01-14" +++ {{< image source="/images/extreme-ssh-hardening.png" >}} Results from a Mozilla SSH Observatory Scan {{< /image >}} `SSH` (Secure Shell) is a great tool, but if you ever expose `SSH` to the internet, you'll soon discover a multitude of internet bots and bad actors pummeling your server. There is a clever way of mitigating this attack vector passively. Some of you might know this already, but the idea is to configure `SSH` to maximum {{< sidenote mark="security." set="right" >}}You can audit the SSH security of a website if the standard port `22` is exposed using [The Mozilla Observatory Tool](https://observatory.mozilla.org/).{{< /sidenote >}} Warning: This will break legacy systems. Here's an example of a `/etc/ssh/sshd_config` file in a nutshell. ```text HostKey /etc/ssh/ssh_host_ed25519_key KexAlgorithms curve25519-sha256@libssh.org Ciphers chacha20-poly1305@openssh.com MACs hmac-sha2-512-etm@openssh.com LogLevel VERBOSE SyslogFacility AUTHPRIV Subsystem sftp internal-sftp -f AUTHPRIV -l INFO UsePAM yes PrintMotd no Compression no PermitRootLogin no GSSAPIAuthentication no PasswordAuthentication no AuthenticationMethods publickey ChallengeResponseAuthentication no AuthorizedKeysFile .ssh/authorized_keys ``` A configuration like this prevents almost `99%` of attackers from reaching or getting pass the negotiation stage. The most you'll see in your system log is the following. ```shell sshd: Connection from x.x.x.x port x on x.x.x.x port 22 sshd: Connection closed by x.x.x.x port x [preauth] sshd: Connection from x.x.x.x port x on x.x.x.x port 22 sshd: Connection closed by x.x.x.x port x [preauth] ``` What did we do? First we let `SSH` support the most modern cipher, key exhange algorithm, and MAC (message authentication code). This is what kills legacy systems and bots. ```text HostKey /etc/ssh/ssh_host_ed25519_key KexAlgorithms curve25519-sha256@libssh.org Ciphers chacha20-poly1305@openssh.com MACs hmac-sha2-512-etm@openssh.com ``` Let it also log everything, including every file modified when you use `SSH` to mount a remote file system. ```text LogLevel VERBOSE SyslogFacility AUTHPRIV Subsystem sftp internal-sftp -f AUTHPRIV -l INFO ``` Force public key authentication only and deny `root` login. ```text PermitRootLogin no PasswordAuthentication no AuthenticationMethods publickey ChallengeResponseAuthentication no ``` If you really need `root` login you can set `prohibit-password`. ```text PermitRootLogin prohibit-password ``` Or activate this setting more strictly using match patterns. ```text Match Address 192.168.1.*,10.0.3.1 PermitRootLogin prohibit-password ```