Setup OpenBSD and Hardening OpenSSH

— 2074 words — 11 min

#openbsd  #ssh 

Table of Contents
  1. Download and Verify the OpenBSD image
  2. Updating Configuration Files
  3. Hardening the SSH Daemon

Note: I wrote this before OpenBSD 7.4 was released. You will always find the current release on this page.

Download and Verify the OpenBSD image🔗

I used a VPS from Netcup but they only offer the OpenBSD 6.8 image that was released in October 2020. Even if you install this version you cannot upgrade it to the most recent version 7.3 (as of this writing) because upgrades are only supported from one release to the release immediately following (at least officially). However, Netcup allows me upload my own images.

Head to the OpenBSD installation page and grab the most up to date ISO. (Unless you want to install it on a netcup VPS. There’s currently a bug, so you need to pick release 7.2 and then upgrade to 7.3).

Download the iso and the checksum files.

wget https://cdn.openbsd.org/pub/OpenBSD/7.3/amd64/install73.iso
wget https://cdn.openbsd.org/pub/OpenBSD/7.3/amd64/SHA256
wget https://cdn.openbsd.org/pub/OpenBSD/7.3/amd64/SHA256.sig
wget https://ftp.openbsd.org/pub/OpenBSD/7.3/openbsd-73-base.pub

Then verify the signature of the OpenBSD iso with signify1. In the directory containing the downloaded files, run

$ sha256sum --ignore-missing -c SHA256
install73.iso: OK

$ signify -Cp ./openbsd-73-base.pub -x SHA256.sig install73.iso
Signature Verified

With Netcup I can upload the custom image file via sftp. Then I select the uploaded iso file as file to boot from on the next reboot and reboot the server. You should see the install helper of OpenBSD coming up. Then I just follow the installation script of OpenBSD which is pretty straight forward.

After installation, I open a VNC connection and login as root and run the following command to show the ssh fingerprint of the host.

ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key

Edit: With OpenBSD 7.4 you’ll see the fingerprint being printed to console after the first boot. The relevant bullet point reads as follows.

Print to the console the fingerprint of a newly generated ssh(1) host key of the preferred type (currently ED25519), typically when booting for the first time. This simplifies a secure first ssh connection to a freshly installed machine.

The presented fingerprint has to match the fingerprint you see when you’re connecting via ssh the first time. If it is, then it’s all good and there is no MITM attack taking place. This is the case for me, so I can close the VNC connection and communicate with the server via ssh.

First things first. Apply all available binary patches with syspatch and upgrade all currently installed packages.

syspatch
pkg_add -u

I like to install neovim as my editor. It’s as simple as

pkg_add neovim

Then lets enable doas for your user. Actually, for anybody in the group wheel.

Change to the root user.

su - root

Add the following line in /etc/doas.conf.

permit persist keepenv :wheel

Updating Configuration Files🔗

Running sysmerge will help you to update your configuration files if you updated to a new release with sysupgrade. If you didn’t need to do an upgrade because you installed the current version of OpenBSD and did not have to fight weird bugs (as I had to as mentioned above), then you don’t need to do this 🙂.

sysmerge

Hardening the SSH Daemon🔗

Probably the most important program when administrating your remote server is SSH. This configuration is not specific to OpenBSD and you can—or should—apply these hardening steps on your Linux server as well. You may need to adjust some paths; for instance I know that Ubuntu already ships a moduli file in /etc/ssh/moduli. You can take a look at the hardening guides by ssh-audit for different operating systems, though I don’t know how up to date they are. However, ssh-audit is a great tool which I’ll use at the end to verify the configuration.

Initially, when you run ssh-audit mxzero.net the output might look like in the next code block. There are quite a few [warn] and [fail] lines and at the end suggestions for algorithms to remove. If you run that yourself, the output in the terminal is colored in green, yellow, and red.

$ ssh-audit mxzero.net
# general
(gen) banner: SSH-2.0-OpenSSH_9.3
(gen) software: OpenSSH 9.3
(gen) compatibility: OpenSSH 8.5+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)

# key exchange algorithms
(kex) sntrup761x25519-sha512@openssh.com    -- [info] available since OpenSSH 8.5
(kex) curve25519-sha256                     -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) curve25519-sha256@libssh.org          -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) ecdh-sha2-nistp256                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256 (3072-bit) -- [info] available since OpenSSH 4.4
                                                      `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 3072. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
(kex) diffie-hellman-group16-sha512         -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512         -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group14-sha256         -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
                                            `- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73

# host-key algorithms
(key) rsa-sha2-512 (4096-bit)               -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (4096-bit)               -- [info] available since OpenSSH 7.2
(key) ssh-ed25519                           -- [info] available since OpenSSH 6.5

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com         -- [info] available since OpenSSH 6.5
                                            `- [info] default cipher since OpenSSH 6.9
(enc) aes128-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr                            -- [info] available since OpenSSH 3.7
(enc) aes256-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes256-gcm@openssh.com                -- [info] available since OpenSSH 6.2

# message authentication code algorithms
(mac) umac-64-etm@openssh.com               -- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 6.2
(mac) umac-128-etm@openssh.com              -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com             -- [fail] using broken SHA-1 hash algorithm
                                            `- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com                   -- [warn] using encrypt-and-MAC mode
                                            `- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 4.7
(mac) umac-128@openssh.com                  -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1                             -- [fail] using broken SHA-1 hash algorithm
                                            `- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28

# fingerprints
(fin) ssh-ed25519: SHA256:5azTiWRUETjb3a5An7oja84Ecpz4sRS3N5rizHG5Ku4
(fin) ssh-rsa: SHA256:svf2g1jXGwYa0joXguPM9SfLFUS6hUPasJA+l4Ls7aU

# algorithm recommendations (for OpenSSH 9.3)
(rec) -ecdh-sha2-nistp256                   -- kex algorithm to remove
(rec) -ecdh-sha2-nistp384                   -- kex algorithm to remove
(rec) -ecdh-sha2-nistp521                   -- kex algorithm to remove
(rec) -hmac-sha1                            -- mac algorithm to remove
(rec) -hmac-sha1-etm@openssh.com            -- mac algorithm to remove
(rec) -diffie-hellman-group14-sha256        -- kex algorithm to remove
(rec) -hmac-sha2-256                        -- mac algorithm to remove
(rec) -hmac-sha2-512                        -- mac algorithm to remove
(rec) -umac-128@openssh.com                 -- mac algorithm to remove
(rec) -umac-64-etm@openssh.com              -- mac algorithm to remove
(rec) -umac-64@openssh.com                  -- mac algorithm to remove

# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>

Alright, so I take the following steps to lock it down.

Regenerate SSH host keys (run the following commands as root).

rm /etc/ssh/ssh_host_*
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""

Remove the 2047 bit moduli from /etc/moduli and save the result in a new file that we will use in the sshd_config.

awk '$5 >= 3071' /etc/moduli > /etc/ssh/moduli

I only allow public key authentication. The following prohibits the user root to login and disables password and keyboard-interactive authentication in /etc/ssh/sshd_config.

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no

Let’s add the new moduli file to the sshd configuration. Adjust the host key algorithms as well as the key exchange algorithms, allowed ciphers, and the algorithms to generate a message authentication code in /etc/ssh/sshd_config.

ModuliFile /etc/ssh/moduli
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# Restrict key exchange, cipher, and MAC algorithms
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com

After reloading the sshd configuration with rcctl reload sshd I can verify that everything was applied as expected with ssh-audit.

ssh-audit <domain|IP address>

Take a look at the result. If there are suggestions at the bottom of the report, you should probably apply them.

Now the output does not contain any [warn] or [fail] lines and no further suggestions for algorithms. It should be all green 🙂.

$ ssh-audit mxzero.net
# general
(gen) banner: SSH-2.0-OpenSSH_9.3
(gen) software: OpenSSH 9.3
(gen) compatibility: OpenSSH 8.5+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)

# key exchange algorithms
(kex) sntrup761x25519-sha512@openssh.com    -- [info] available since OpenSSH 8.5
(kex) curve25519-sha256                     -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) curve25519-sha256@libssh.org          -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) diffie-hellman-group16-sha512         -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512         -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group-exchange-sha256 (3072-bit) -- [info] available since OpenSSH 4.4
                                                      `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 3072. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).

# host-key algorithms
(key) rsa-sha2-512 (4096-bit)               -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (4096-bit)               -- [info] available since OpenSSH 7.2
(key) ssh-ed25519                           -- [info] available since OpenSSH 6.5

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com         -- [info] available since OpenSSH 6.5
                                            `- [info] default cipher since OpenSSH 6.9
(enc) aes256-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes128-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes256-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr                            -- [info] available since OpenSSH 3.7
(enc) aes128-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52

# message authentication code algorithms
(mac) hmac-sha2-256-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) umac-128-etm@openssh.com              -- [info] available since OpenSSH 6.2

# fingerprints
(fin) ssh-ed25519: SHA256:CKpTlJ0SSAW6V4BHhVKun3F03xw/5By8wS6qH2h5DMQ
(fin) ssh-rsa: SHA256:aDnKfi4q6ozHCe69Aucl5le3kWgOlW1f+5Mne7bkl80

If you have more suggestions, tell me!


1

On Arch Linux you can install the packge with the same name: pacman -S signify. On Debian-based systems the package is called signify-openbsd.


Articles from blogs I follow around the net

Status update, July 2024

Hi! This month wlroots 0.18.0 has been released! This new version includes a fair share of niceties: ICC profiles, GPU reset recovery, less black screens when plugging in a monitor on Intel, a whole bunch of new protocol implementations, and much more. Thanks…

via emersion July 16, 2024

Whose CIDR is it anyway?

A look at CIDR block ownership from a RIR-, country-, and organization level. Originally presented at RIPE88.

via Signs of Triviality June 12, 2024

How and why to make a /now page on your site

Background I used to wonder what my friend Benny Lewis was doing. He has a website and social media accounts, but neither gave an overview of what he’s doing now. Then I realized some people might wonder the same about me. So in 2015, I made a /now page on my…

via Derek Sivers blog May 18, 2024

Generated by openring