IPv4 & IPv6 Leasing - Any RIR, Any LocationOrder Now
Hostperl

Set Up SSH, UFW, and Fail2Ban on a Fresh VPS

By Raman Kumar

Share:

Updated on Aug 3, 2026

Set Up SSH, UFW, and Fail2Ban on a Fresh VPS

Start with the right session, not the firewall

This guide shows you how to set up SSH, UFW, and Fail2Ban on a fresh VPS without locking yourself out. It is written for a new Hostperl server, whether you run a small business site, a staging box, or a client migration on a Hostperl VPS.

Use these placeholders throughout the tutorial: SERVER_IP is your VPS address, for example 203.0.113.10. DOMAIN_NAME is the hostname you want, for example server1.example.com. ADMIN_USER is the new sudo user you will create, for example perladmin.

On your local computer, open your first SSH session with root access:

ssh root@SERVER_IP

If your provider gives you a default non-root account, use that instead. Keep this original terminal open until you finish testing the new login later.

On the VPS as root, check the operating system before you install anything:

cat /etc/os-release

You should see either Ubuntu/Debian or AlmaLinux/Rocky Linux details. The commands below are split by family so you do not mix apt and dnf, or UFW and firewalld rules.

Create a non-root admin user safely

A new admin account gives you a recovery path if SSH settings change. Hostperl support teams see fewer lockouts when customers test this step before touching root login settings, which is why it belongs near the top of the workflow. If you want a broader walkthrough of that sequence, Hostperl already documents it in Create a Non-Root Admin User on Ubuntu and AlmaLinux.

Ubuntu and Debian

On the VPS as root, create the user, set a password, and add it to sudo:

adduser ADMIN_USER
usermod -aG sudo ADMIN_USER
id ADMIN_USER

Replace ADMIN_USER with your chosen account name. The last command should show the sudo group in the user’s supplementary groups.

Now create the SSH directory and copy your key. Replace the key contents with your public key from ~/.ssh/id_ed25519.pub on your local machine:

install -d -m 700 -o ADMIN_USER -g ADMIN_USER /home/ADMIN_USER/.ssh
cat > /home/ADMIN_USER/.ssh/authorized_keys <<'EOF'
PASTE_YOUR_PUBLIC_KEY_HERE
EOF
chown ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh/authorized_keys
chmod 600 /home/ADMIN_USER/.ssh/authorized_keys

Check the permissions right away. SSH will reject loose ownership or mode settings:

ls -ld /home/ADMIN_USER /home/ADMIN_USER/.ssh /home/ADMIN_USER/.ssh/authorized_keys

On the VPS as root, open a second terminal and test the new user before changing SSH policy:

ssh ADMIN_USER@SERVER_IP
sudo -v

If sudo asks for your password and then returns without an error, the account is ready.

AlmaLinux and Rocky Linux

On the VPS as root, create the account, set its password, and add it to wheel:

useradd -m ADMIN_USER
passwd ADMIN_USER
usermod -aG wheel ADMIN_USER
id ADMIN_USER

Then install the SSH key with the correct ownership and permissions:

install -d -m 700 -o ADMIN_USER -g ADMIN_USER /home/ADMIN_USER/.ssh
cat > /home/ADMIN_USER/.ssh/authorized_keys <<'EOF'
PASTE_YOUR_PUBLIC_KEY_HERE
EOF
chown ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh/authorized_keys
chmod 600 /home/ADMIN_USER/.ssh/authorized_keys

Test the account from a second terminal:

ssh ADMIN_USER@SERVER_IP
sudo -v

Wait until this works before you tighten root access.

Update packages, time sync, and hostname

A fresh VPS should be patched before it goes live. Time sync matters too. Expired TLS certificates, broken cron jobs, and confusing log timestamps often start with a drifting clock.

Ubuntu and Debian

sudo apt update
sudo apt -y upgrade
sudo apt -y install chrony
sudo systemctl enable --now chrony
sudo timedatectl set-timezone Pacific/Auckland
sudo hostnamectl set-hostname server1.example.com
hostnamectl

Expected result: package indexes refresh, updates apply, Chrony starts, and your hostname changes immediately.

AlmaLinux and Rocky Linux

sudo dnf -y update
sudo dnf -y install chrony
sudo systemctl enable --now chronyd
sudo timedatectl set-timezone Pacific/Auckland
sudo hostnamectl set-hostname server1.example.com
hostnamectl

Hostperl customers in APAC often pair this with a quick reboot window after migrations so monitoring and mail logs line up cleanly.

Set up SSH hardening without cutting off access

Now that the new admin login works, you can harden SSH. Do not disable root or password login until you confirm the new account from a second terminal.

If you are planning a larger migration or control-panel move, Hostperl’s notes on cPanel vs Plesk for Hosting Migrations in 2026 help teams decide where this hardening belongs in the cutover plan.

Ubuntu and Debian

On the VPS as root, edit the SSH daemon config:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

Add or adjust these lines:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
AllowUsers ADMIN_USER

Save and exit, then test syntax before reloading:

sudo sshd -t
sudo systemctl reload ssh

On Ubuntu and Debian, the service name is usually ssh. The syntax test must return no output.

AlmaLinux and Rocky Linux

On the VPS as root, edit the SSH config:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

Use the same settings:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
AllowUsers ADMIN_USER

Then verify and reload:

sudo sshd -t
sudo systemctl reload sshd

On AlmaLinux and Rocky Linux, the service name is usually sshd. If you use SELinux, these SSH settings are normally allowed without extra policy changes.

From your local computer, open a fresh SSH session in a second terminal:

ssh ADMIN_USER@SERVER_IP

Leave the original root session open until this succeeds.

Open the firewall before you close anything else

Your firewall should allow SSH before you enable stricter SSH settings. That sequence prevents the classic lockout: a working SSH daemon with no reachable port.

Ubuntu and Debian with UFW

On the VPS as the non-root sudo user, allow SSH, turn on UFW, and confirm the rules:

sudo apt -y install ufw
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose

Expected result: UFW shows OpenSSH allowed and the firewall active.

AlmaLinux and Rocky Linux with firewalld

On the VPS as the non-root sudo user, enable SSH in firewalld and reload the runtime rules:

sudo dnf -y install firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Expected result: the ssh service appears in the active zone.

Install and configure Fail2Ban

Fail2Ban watches authentication logs and bans repeat offenders. It is a practical layer, not a replacement for key-based SSH. For customers who also run WordPress or panel logins, this can reduce noisy brute-force attempts on a small VPS.

Ubuntu and Debian

sudo apt -y install fail2ban
sudo systemctl enable --now fail2ban
sudo nano /etc/fail2ban/jail.local

Paste this configuration:

[sshd]
enabled = true
mode = aggressive
maxretry = 3
findtime = 10m
bantime = 1h

Save and reload the service after a quick config check:

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

You should see the sshd jail active.

AlmaLinux and Rocky Linux

sudo dnf -y install fail2ban
sudo systemctl enable --now fail2ban
sudo nano /etc/fail2ban/jail.local

Use the same jail content:

[sshd]
enabled = true
mode = aggressive
maxretry = 3
findtime = 10m
bantime = 1h

Then validate and restart:

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

If the sshd jail does not appear, check the backend and logs first.

Check logs, ports, and service health

Verification matters because customers often discover issues only after a reboot or a maintenance window. These checks confirm that SSH is listening, the firewall is active, and Fail2Ban is running.

On the VPS as the non-root sudo user, run:

sudo ss -tulpn | grep -E ':(22)\s'
sudo systemctl status ssh 2>/dev/null || sudo systemctl status sshd
sudo systemctl status fail2ban
sudo journalctl -u fail2ban -n 50 --no-pager

On Ubuntu and Debian, the SSH service should be ssh. On AlmaLinux and Rocky Linux, it should be sshd. The port check should show the SSH daemon listening on 0.0.0.0:22 or [::]:22.

From your local computer, test a real login and a sudo action:

ssh ADMIN_USER@SERVER_IP
sudo whoami

The command should print root. That confirms the new account, keys, and sudo path are all working.

Reboot test and rollback points

Reboot once before you call the job done. A restart exposes missing services, bad enable-at-boot settings, and SSH configs that only looked fine in the current session.

sudo reboot

After the server comes back, reconnect from your local computer and check the same services again. If you cannot reach the server, use your Hostperl console access or rescue path, then restore the backups you made of /etc/ssh/sshd_config and /etc/fail2ban/jail.local.

Troubleshooting the likely failures

SSH refuses the key: check ownership and modes.

ls -ld /home/ADMIN_USER /home/ADMIN_USER/.ssh /home/ADMIN_USER/.ssh/authorized_keys
sudo journalctl -u ssh -n 50 --no-pager 2>/dev/null || sudo journalctl -u sshd -n 50 --no-pager

Fix with:

sudo chown -R ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh
sudo chmod 700 /home/ADMIN_USER/.ssh
sudo chmod 600 /home/ADMIN_USER/.ssh/authorized_keys

Firewall is active but SSH still fails: confirm the service rule exists and the daemon listens.

sudo ufw status verbose
sudo firewall-cmd --list-all
sudo ss -tulpn | grep ':22'

Fail2Ban shows no jail: test the configuration again.

sudo fail2ban-client -t
sudo tail -n 50 /var/log/fail2ban.log 2>/dev/null || sudo journalctl -u fail2ban -n 50 --no-pager

For a new VPS that needs to stay reliable during launches, this baseline is a better starting point than a rushed hardening job. If you are still choosing infrastructure, compare options on Hostperl VPS and keep your migration window short.

Hostperl VPS plans give you room to set up SSH hardening, UFW or firewalld, and Fail2Ban before you move live traffic. If you want help with the migration window, our support team works with real server setups, not generic scripts.

For a clean launch path, start with Hostperl VPS and keep your SSH policy, firewall rules, and recovery access documented from day one.

FAQ

Should I disable root SSH login immediately?

No. First confirm the new sudo user works in a second terminal, then remove root access.

Do I need Fail2Ban if I already use SSH keys?

Yes, it still helps reduce repeated connection noise and protects any other exposed login services you run.

Can I use UFW on AlmaLinux or Rocky Linux?

You can install it, but firewalld is the native choice on those systems and usually fits cleaner with the rest of the stack.

What if I lose SSH access after hardening?

Use your provider console or rescue access, restore the SSH backup file, and recheck sshd -t before reloading.