Skip to main content
Guide contents
Beginner14 min

Hetzner VPS Setup

From a blank server to a secured production-ready machine. Choose how you want to set up your server.

Published:

Automatic Setup via AI

Provide your AI assistant with access to this repository. It will automatically perform all checks, configure security, and generate a file with all access credentials (credentials guide) on your computer.

Open GitHub Repository

1. Creating an SSH Key (Local)

Executed on your computer (Mac or Linux) BEFORE you connect to the server.

bash
ssh-keygen -t ed25519 -C "{username}@{nickname}" -f ~/.ssh/{nickname}_key -N "" cat ~/.ssh/{nickname}_key.pub

Copy the output of the second command (it starts with ssh-ed25519 ...). This is your public key.

2. Login as Root

Connect to the server using the password Hetzner sent to your email.

Warning

Hetzner may ask you to change the password. Enter the current password, then the new temporary one twice. If the connection drops after this — just connect again using the new password.

bash
ssh root@{SERVER_IP}

3. System Update

Updating all packages in non-interactive mode (without grub popups).

bash
apt update && DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt upgrade -y

4. Creating a User with sudo

Working as root is dangerous. We create a regular user and give them administrator privileges.

bash
useradd -m -s /bin/bash {username} echo "{username}:YOUR_SECURE_PASSWORD" | chpasswd usermod -aG sudo {username}

5. SSH Key Deployment

We will write your public key, which you copied in Step 1, to the server.

bash
mkdir -p /home/{username}/.ssh echo "{PUBLIC_KEY_CONTENT}" > /home/{username}/.ssh/authorized_keys chmod 700 /home/{username}/.ssh chmod 600 /home/{username}/.ssh/authorized_keys chown -R {username}:{username} /home/{username}/.ssh

6. Login Check

Important

MANDATORY CHECKPOINT Do not close the root session! Open a new terminal window on your PC and try to log in using the key. You can only proceed after a successful login.

Check if sudo works (the system should ask for the password you set in Step 4 and output "root"):

bash
ssh -i ~/.ssh/{nickname}_key {username}@{SERVER_IP} sudo whoami

7. Firewall (UFW)

Execute all subsequent commands as your new user (with sudo). Setting up the "deny all incoming except SSH, HTTP, and HTTPS" policy.

bash
sudo apt install -y ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw --force enable sudo ufw status

8. Kernel Protection (sysctl)

Applying parameters to protect against network attacks.

bash
sudo tee /etc/sysctl.d/99-security.conf << 'EOF' net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 EOF sudo sysctl -p /etc/sysctl.d/99-security.conf

9. Basic Packages and Time

Accurate time is critical for logs, SSL certificates, and fail2ban.

bash
sudo apt install -y chrony curl wget git unzip net-tools sudo systemctl enable chrony

10. Local SSH Config

Setting up a shortcut on your local PC to connect with a short command ssh {nickname} in the future.

bash
mkdir -p ~/.ssh && touch ~/.ssh/config && chmod 600 ~/.ssh/config cat >> ~/.ssh/config << 'EOF' Host {nickname} HostName {SERVER_IP} User {username} IdentityFile ~/.ssh/{nickname}_key IdentitiesOnly yes EOF

11. Security Check

Verify that the short command from the local PC works and that the basic protections are enabled.

bash
ssh {nickname} sudo ufw status sysctl net.ipv4.tcp_syncookies

12. Final Lockdown

We install protection against brute force (fail2ban) and permanently disable password login and root login.

bash
sudo apt install -y fail2ban sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo systemctl enable fail2ban sudo systemctl start fail2ban sudo tee /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF' PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthenticationMethods publickey EOF sudo sshd -t && sudo systemctl restart ssh
Tip

Done! The server is fully configured and secured.

This guide is completely free. If it saved you an evening, you can support the project's growth.
Support the author