Extended Brain Storage

OpenBSD: OpenSSH Hardening Using Certificates

Posted on June 14, 2019

The OpenSSH daemon is targeted by brute-force attacks almost everyday. There are various ways to deal with the annoying attempts of unauthorised access, one of which is authentication based on certificates. Here are some thoughts to set this up in the realm of OpenBSD...

Introduction

Having a very complex password or long passphrase may seem to be an adequate solution to minimise the risk that a few random password guesses will be successful. Hands-on experience shows that a better solution is to replace passwords with SSH certificates.


OpenSSH Keys and Certificates

In order to improve OpenSSH keys, OpenSSH certificates can be used. The main difference is that while keys don't expire, the certificates can. Compared to the X.509 certificates used in the TLS/SSL, the OpenSSH certificates are a much simpler Public-Key Cryptography Standards (PKCS) format, originally defined in the RFC 5208.

The ssh-keygen command supports two types of certificates:

Following the Table 2: Comparable strengths from the NIST SP 800-57 Pt. 1 Rev. 4, the RSA key length should be 15360 bits in order to consider the same strength as Elliptic Curves-based Crytography (ECC) algorithms. One of them is the Edwards-curve Ed25519.


OpenSSH Configuration Using the Ed25519

On the server, the new SSH server key-pair can be generated as follows (while removing the old one):

$ rm -f /etc/ssh/ssh_host_ed25519_key*
$ ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" < /dev/null
$ cat /etc/ssh/ssh_host_rsa_key.pub
SERVER-PUBLIC-KEY

An appropriate update of the SSH daemon's configuration can be achieved as follows:

$ vi /etc/ssh/sshd_config
...
#HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
...
AuthenticationMethods password
...

Restart of the SSH daemon is necessary:

$ rcctl restart sshd

The previously displayed SERVER-PUBLIC-KEY needs to be stored into the local known_hosts file:

$ echo "SERVER.DOMAIN.TLD,IP-ADDRESS ssh-ed25519 SERVER-PUBLIC-KEY" >> ~/.ssh.known_hosts

On the client system (a computer), the following command can be used to generate a user certificate (password protected):

$ ssh-keygen -a 256 -t ed25519 -f ~/.ssh/id_ed25519
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_ed25519
Your public key has been saved in ~/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:FINGERPRINT USERNAME@CLIENT-SYSTEM
...

The generated certificate needs to be uploaded to the server, e.g. as follows:

$ ssh-copy-id -i ~/.ssh/id_ed25519.pub USERNAME@SERVER.DOMAIN.TLD
...
Number of key(s) added: 1
...

Back on the server, verification can be performed as follows:

$ cat ~/.ssh/authorized_keys
ssh-ed25519 CLIENT-PUBLIC-KEY USERNAME@CLIENT-SYSTEM

Additionally, the client system can be instructed to use the generated user certificate as follows:

$ vi ~/.ssh/config
    HostName SERVER.DOMAIN.TLD
    CertificateFile ~/.ssh/id_ed25519.pub
    User USERNAME
    IdentityFile ~/.ssh/id_ed25519

Testing the password authentication can be achieved as follows (-vv can be added for more verbosity):

$ ssh SERVER.DOMAIN.TLD -i ~/.ssh/id_ed25519 -o PasswordAuthentication=yes

In order to allow certificate-based login only, the following update of the SSH daemon's configuration needs to be applied:

$ vi /etc/ssh/sshd_config
...
AuthenticationMethods publickey
...

Restart of the SSH daemon is necessary:

$ rcctl restart sshd

Testing the certificate authentication without password can be performed as follows:

$ ssh SERVER.DOMAIN.TLD -i ~/.ssh/id_ed25519 -o PasswordAuthentication=no

OpenSSH Server Hardening

Following the OpenSSH's man page, the currently available SSH algorithms (ciphers, authentication ciphers, MACs, keys, key exchange algorithms) in a system can be displayed as follows:

$ ssh -Q cipher
$ ssh -Q cipher-auth
$ ssh -Q mac
$ ssh -Q kex
$ ssh -Q key

An example of filtering of the allowed algorithms can be found as follows:

...
# Ciphers and keying
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
HostKeyAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-ed25519
KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group-exchange-sha256
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
RekeyLimit default none
...

In order to protect the SSH server even more, the two-factor authentication can be used.


Algorithm Enumeration

SSH algorithms enumeration using the ssh2-enum-algos nmap script:

$ sudo nmap --script ssh2-enum-algos SERVER.DOMAIN.TLD
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-18 16:11 CEST
Nmap scan report for SERVER.DOMAIN.TLD (SERVER.IP.ADDRESS)
Host is up (0.0075s latency).
Not shown: 991 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
| ssh2-enum-algos:
|   kex_algorithms: (3)
|       curve25519-sha256@libssh.org
|       curve25519-sha256
|       diffie-hellman-group-exchange-sha256
|   server_host_key_algorithms: (1)
|       ssh-ed25519
|   encryption_algorithms: (3)
|       chacha20-poly1305@openssh.com
|       aes256-gcm@openssh.com
|       aes256-ctr
|   mac_algorithms: (2)
|       hmac-sha2-512-etm@openssh.com
|       hmac-sha2-256-etm@openssh.com
|   compression_algorithms: (2)
|       none
|_      zlib@openssh.com

Other useful scripts are:

Tags: #OpenBSD #security #sshd #OpenSSH #authentication #certificates #hardening

⏴ Previous Post Next Post ⏵