Quick server setup on Hetzner

This note can help you create and configure a new Hetzner server. I want to set up a new server for my blog and personal projects, so the setup is fairly simple.

Create ssh key

Terminal window
cd .ssh
ssh-keygen -t ed25519 -C "test@example.com"

Create the server

Let’s create and configure a new server on Hetzner. I assume you already have a Hetzner account, so go to the servers page and use the website to create a new server. It’s possible to use the Hetzner CLI or Terraform, but it doesn’t make sense to use those tools if you’re only creating a single server.

I’m going to use the latest version of Fedora, a shared Arm64 vCPU, the SSH key I created above (so I don’t need a password), and enable the backup option.

Users configuration

Obtain the server’s IP address from the Hetzner panel, and log in as root:

Terminal window
ssh root@<ip-address> -i ~/.ssh/<ssh-private-key>

Add a new user and place them in the wheel group so they can use the sudo command:

Terminal window
adduser <user>
usermod -aG wheel <user>

We don’t want to continue logging in as the root user, so let’s move the SSH key to the new user’s directory:

Terminal window
mkdir /home/<user>/.ssh
chmod 700 /home/<user>/.ssh
cp /root/.ssh/authorized_keys /home/<user>/.ssh/
chown -R <user>:<user> /home/<user>/.ssh
chmod 600 /home/<user>/.ssh/authorized_keys

Let’s allow password-free sudo for all users in the wheel group. Run the visudo command and make the following changes:

## Allows people in group wheel to run all commands
## %wheel ALL=(ALL) ALL
## Same thing without a password
%wheel ALL=(ALL) NOPASSWD: ALL

Edit /etc/ssh/sshd_config and change PermitRootLogin prohibit-password to PermitRootLogin no, completely disallowing root logins over SSH:

/etc/ssh/sshd_config
PermitRootLogin prohibit-password
PermitRootLogin no

Restart the SSH service.

Terminal window
systemctl restart sshd
systemctl status sshd

It should no longer be possible to log in as root:

Terminal window
ssh root@<ip-address>
root@<ip-address>: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Logout.

Local SSH configuration (macOS)

Let’s add the server to ~/.ssh/config so you won’t have to specify the key and passphrase every time:

~/.ssh/config
Host hetzner_<user>
AddKeysToAgent yes
UseKeychain yes
HostName <ip-address>
User <user>
IdentityFile ~/.ssh/<ssh-private-key>

Add your SSH private key to the ssh-agent and store your passphrase in the keychain:

Terminal window
ssh-add --apple-use-keychain ~/.ssh/<ssh-private-key>

Now, you can log in to the server with:

Terminal window
ssh <user>@<ip-address>

fail2ban

Using SSH keys and disabling password authentication increases SSH security, but you can still use fail2ban to block suspicious connection attempts, scan activity, rate-limit connections, block IPs, etc.:

Terminal window
sudo dnf install fail2ban

Below is an example configuration. Feel free to customize it:

/etc/fail2ban/jail.conf
# "bantime" is the amount of time that a host is banned, integer in seconds or
# time abbreviation format (m - minutes, h - hours, d - days, w - weeks, mo - months, y - years).
# This is to consider as an initial time if bantime.increment gets enabled.
bantime = 10m
bantime = 1h
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 10m
findtime = 1h
# "maxretry" is the number of failures before a host get banned.
maxretry = 3
maxretry = 5

Enable fail2ban.

Terminal window
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo systemctl status fail2ban

Update system

Terminal window
sudo dnf update && sudo dnf upgrade

Firewall

Fedora includes firewalld, but I decided to use the Hetzner Firewall. In my case, I configure it to allow SSH (port 22) and HTTPS (port 443).