DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
FREEDOM251

Freedom251 › Blog › Fail2ban

VPS Security Hardening: Firewall, SSH Keys and Fail2Ban Setup

By Freedom251 Team · · 13 min read

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A secure VPS starts with four controls working together: a least-privilege administrator using SSH keys, a firewall that exposes only required ports, a patched operating system, and Fail2Ban watching authentication logs for repeated attacks. Keep an existing console or SSH session open, test every change from a second session, and only then disable direct root and password logins.

UFW is the simplest choice for a small Ubuntu rule set; direct nftables is better when you need custom chains or packet conditions. Fail2Ban is not a firewall: it reacts to repeated log-detected failures after traffic reaches the host.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What a secure VPS baseline includes

VPS security is layered rather than a single setting. Use each layer for the problem it solves:

  • Account control: a named administrator with sudo instead of routine root use.
  • Authentication: public-key SSH authentication, with a FIDO2/U2F hardware key where the SSH client and account policy support it.
  • Network exposure: a default-deny inbound firewall with explicit rules for the real SSH port and the application ports you intentionally publish.
  • Reaction: Fail2Ban watching the host’s actual authentication log source and temporarily banning addresses that generate repeated failures.
  • Maintenance: security updates, key lifecycle management, log review, and a tested recovery path.

A firewall reduces the number of reachable services. It does not make weak passwords safe, install updates, or prove that an account is legitimate. Fail2Ban can slow repeated attempts, but it depends on logs and can miss attacks that never produce a matching event.

Prepare a safe change window

Remote hardening can lock you out if a rule or SSH change is wrong. Start from a provider console, serial console, or a working SSH connection that you will not close until a new login has succeeded.

Inventory the access path

  • Record the SSH daemon’s actual listening port and address. Do not assume it is port 22 if the image or an administrator changed it.
  • List the source networks that should administer the VPS. A fixed office or VPN address can be restricted; a changing home address may require a different recovery plan.
  • List application ports that must be public. A typical web server needs TCP 80 and 443; a database or private API usually should not be exposed to the whole internet.
  • Confirm that you have provider recovery access before changing root or password policy.

Use a second terminal for verification. The first session is your safety net, not proof that the new configuration works.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Apply operating-system updates

Update before hardening so the SSH daemon, kernel, firewall tooling, and log components are at the versions supplied by your distribution. On Ubuntu, review pending updates with the normal package-management workflow and reboot when a kernel or other update requires it. Schedule this step so a reboot cannot interrupt an untested firewall change.

Create a named administrator and install a key

Create and authorize the account

Use a personal, named account rather than sharing root credentials. On Ubuntu, an example is:

sudo adduser adminname
sudo usermod -aG sudo adminname

Replace adminname with the account you will actually use. Confirm that the account can run a harmless command with sudo before changing SSH policy:

su - adminname
sudo -v
sudo id

The account should receive only the administrative rights it needs. If a service does not need shell access, do not create a login account for it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install a public key

Generate or select a key on your administration computer, then install its public half in the new account’s ~/.ssh/authorized_keys. The private key must remain on the client and should be protected by a passphrase. Set ownership and permissions on the server if you create the file manually:

sudo install -d -m 700 -o adminname -g adminname /home/adminname/.ssh
sudo install -m 600 -o adminname -g adminname /tmp/adminname-authorized_keys /home/adminname/.ssh/authorized_keys

Use your provider’s console or an already authenticated session to transfer the public key; never paste a private key onto the VPS.

Test the key before changing policy

From a second terminal, open a fresh connection using the new account and key. Test the exact hostname, address, port, and identity file that you will use after hardening. Verify that sudo works in that session. Keep both sessions open while you continue.

Choose the firewall layer

Ubuntu describes UFW as a firewall framework that acts as a frontend for both iptables and nftables. It is initially disabled on Ubuntu Server and provides a readable command interface for common host rules. Direct nftables exposes more of the packet-filtering model and is appropriate when you need custom chains or granular conditions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Decision point UFW Direct nftables
Rule complexity Best for a short allow/deny list and straightforward source restrictions. Best for custom chains, sets, packet metadata, or more detailed conditions.
IPv4 and IPv6 Manages both when IPv6 is enabled in the host configuration; verify the generated rules. Use an inet table or deliberately separate families, then inspect both protocols.
Stateful behavior Provides common stateful behavior through its backend without requiring you to write connection-tracking rules. You define connection-tracking and protocol rules explicitly.
Auditability sudo ufw status numbered is easy to read. sudo nft list ruleset shows the complete active ruleset but requires nftables knowledge.
Operator familiarity Usually easier for a small Ubuntu VPS. More powerful, but mistakes in a hand-written ruleset can cut off access.

Choose one tool as the authority for the host firewall. Do not maintain overlapping, independently managed rule sets unless you understand exactly how they interact.

Configure UFW safely

Add the SSH rule first

Substitute the real SSH port. If it is 22 and you want all source addresses to reach it, the minimal rule is:

sudo ufw allow 22/tcp

If administration should come only from a trusted address or network, restrict the source instead:

sudo ufw allow proto tcp from 192.0.2.10 to any port 22

The address 192.0.2.10 is an example documentation address. Replace it with a stable address or network that you control. If your SSH daemon listens on port 2222, use port 2222 in every firewall and Fail2Ban setting.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set conservative defaults and add application ports

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Only add 80 and 443 when this VPS actually serves HTTP or HTTPS. A mail server, private database, monitoring endpoint, or container host needs a different allow list. Do not copy a web-server rule set to another role without checking each listener.

Enable and inspect

sudo ufw enable
sudo ufw status numbered

Answer the enable prompt only after the SSH allow rule is present. The numbered status should show the intended SSH rule and only the application ports you chose. Review both IPv4 and IPv6 entries when the host has IPv6 connectivity.

Restrict administrative traffic when practical

Source restrictions reduce exposure, but they can also lock out an administrator whose address changes. If access comes through a VPN with stable egress addresses, allow the VPN range and remove broad SSH rules. If you cannot guarantee a stable source, keep a documented recovery route and rely on key authentication, patching, and monitoring rather than guessing at an allowlist.

Use nftables when you need direct control

Direct nftables is useful for custom chains, sets, and packet conditions. Ubuntu’s nftables service loads /etc/nftables.conf when enabled. Test a ruleset before applying it and keep the existing session open.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Review a minimal stateful ruleset

The following is an illustrative starting point for a web VPS with SSH on port 22. Adapt it to the host’s interfaces, address restrictions, and required services:

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0;
        policy drop;

        iif lo accept
        ct state established,related accept
        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept
        tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority 0;
        policy drop;
    }

    chain output {
        type filter hook output priority 0;
        policy accept;
    }
}

This example permits loopback, established and related traffic, basic ICMP, SSH, and web traffic, then drops other inbound and forwarded traffic. A source-restricted SSH rule, additional service, or container networking requirement must be added deliberately; do not assume this file fits every VPS.

Check, load, and persist

sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
sudo systemctl enable --now nftables

The check command validates syntax without loading the file. After loading, inspect the complete ruleset and open a second SSH connection. If your distribution uses a different service layout, follow its nftables unit and persistence conventions rather than running two competing managers.

Harden OpenSSH without losing access

Use a drop-in file

OpenSSH reads /etc/ssh/sshd_config and, on Ubuntu, modular files under /etc/ssh/sshd_config.d/. A drop-in keeps local policy separate from the vendor file and makes package updates easier to review. Create a file such as /etc/ssh/sshd_config.d/60-hardening.conf:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Apply these lines only after the named administrator’s key login succeeds. Some distributions or existing drop-ins may set related directives such as keyboard-interactive authentication; inspect the effective configuration and your recovery requirements before disabling another method.

Validate before reloading

sudo sshd -t
sudo systemctl reload ssh

If the test reports an error, fix the file and run it again. A reload preserves existing sessions, while a new connection tests the policy. Do not close the original session until the second terminal logs in with the key and can use sudo.

Changing the port is optional

A nonstandard SSH port can reduce automated background noise, but it is not an authentication control. If you change it, update the firewall rule, the Fail2Ban port value, client configuration, monitoring, and your documentation before reloading SSH. Key authentication, source restrictions, patching, and log review still matter on any port.

Add hardware-backed authentication where supported

Ubuntu’s OpenSSH documentation notes that U2F/FIDO devices can add a layer of security to key-based authentication. A FIDO2 security key for SSH can provide phishing-resistant, hardware-backed authentication when the SSH client, server version, and account policy support the required method.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
FIDO2 planning question What to verify
Protocol support Confirm that the OpenSSH client and server support the FIDO-backed key type you plan to use.
Connector type Choose a connector that is usable on every administration device, such as USB or a supported wireless interface.
PIN and resident-key behavior Decide whether the key requires a PIN and whether a resident credential is appropriate for your account policy.
Durability and spares Keep a documented second key or another tested recovery method; a lost sole key can become an outage.
Client compatibility Test the complete login flow from each workstation before disabling other recovery methods.

Install and configure Fail2Ban

Understand its role

Fail2Ban reads authentication or service logs, counts matching failures, and adds a temporary firewall ban. The firewall decides whether traffic can reach the host; Fail2Ban reacts after an event has been logged. Running both gives you a network filter and a response to repeated abuse, not two interchangeable firewalls.

Install the package and preserve local changes

sudo apt update
sudo apt install fail2ban

Do not edit the packaged jail.conf. The project’s configuration directs local changes to jail.local or files under jail.d/, so upgrades can replace the vendor file without overwriting your policy.

Select the correct log backend

First determine where this host records SSH authentication events. A systemd-journal host should use the systemd backend. A host writing traditional authentication files should use the appropriate file path. A missing or incorrect log path can prevent a jail from starting or leave it blind to attacks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a journal-based host, create /etc/fail2ban/jail.local with:

[DEFAULT]
bantime = 10m
findtime = 10m
maxretry = 5
backend = systemd

[sshd]
enabled = true
port = 22

For a file-log host, use the corresponding SSH log path and a compatible backend instead:

[DEFAULT]
bantime = 10m
findtime = 10m
maxretry = 5
backend = auto

[sshd]
enabled = true
port = 22
logpath = %(sshd_log)s

Use one backend arrangement that matches the host; do not blindly combine a journal-only setup with a nonexistent file. Replace 22 with the actual SSH port.

Understand the three core settings

Setting Meaning Operational trade-off
bantime How long an address remains banned. A longer period suppresses more repeated noise but increases the cost of a mistaken ban.
findtime The interval in which failures are counted. A shorter window focuses on bursts; a longer one catches slower attempts but can include unrelated mistakes.
maxretry The number of matching failures within findtime that triggers a ban. A lower value reacts sooner but raises false-positive risk for users who mistype credentials.

The Fail2Ban project configuration documents starting defaults of bantime = 10m, findtime = 10m, and maxretry = 5. They are software defaults, not measured attack outcomes. Use longer or progressive bans only after checking false positives, the availability of console recovery, and the effect on legitimate administrators.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start the jail and inspect it

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

The status output should list the sshd jail, its backend, the monitored log source, current failure counts, and any active bans. If the jail is absent or fails to start, inspect the service log and correct the backend or path before relying on it.

Whitelist only addresses that are genuinely trusted and stable. An overly broad ignore list defeats the jail. If a legitimate administrator is banned, remove the address after confirming the request is genuine:

sudo fail2ban-client set sshd unbanip 192.0.2.10

Replace the example address with the real one and document who may perform an unban.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Verify the complete system

Perform these checks from the provider console or your still-open session, then repeat the access test from a second terminal:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Firewall state: run sudo ufw status numbered for UFW or sudo nft list ruleset for nftables. Confirm the firewall is active and inbound rules contain only intended ports.
  2. SSH listener: verify that the daemon listens on the expected address and port. A firewall rule for the wrong port cannot permit the real service.
  3. Key login: establish a new session as the named administrator using the intended key, then run a sudo command.
  4. Root and password policy: confirm the effective SSH configuration reflects your chosen settings after the reload; do not infer it from the drop-in file alone.
  5. Fail2Ban jail: run both general and sshd-specific status commands and confirm that the jail is loaded.
  6. Backend visibility: generate or review a known authentication event and confirm that Fail2Ban’s selected backend can see the host’s actual event source.
  7. Log behavior: review recent SSH and firewall logs for expected accepts, rejected connections, and configuration errors.
  8. Protocol coverage: inspect IPv4 and IPv6 behavior separately if the VPS has both. An IPv6 listener can remain exposed even when only IPv4 rules were reviewed.
  9. Recovery: keep console or provider recovery access available and test the documented unban and rollback procedures.

Recover from common failures

The new SSH session fails

Keep the original session open. Use the provider console to check the listening port, firewall rule, account’s authorized_keys ownership and permissions, and the SSH configuration test result. Roll back only the last change that caused the failure, then retest from a second terminal.

Enabling UFW cuts off administration

Use the console to add an allow rule for the real SSH port and source network, then inspect numbered status. If the rule was added for a guessed port, remove it and add the actual one. Do not repeatedly enable and disable firewalls from an unverified remote session.

Fail2Ban will not start

Check the service status and recent service logs. Typical causes are a nonexistent logpath, a backend that does not match the host’s journal or files, an invalid jail option, or a port value that differs from SSH. Correct the local file, restart the service, and confirm the jail with fail2ban-client status sshd.

A legitimate administrator is banned

Use the console or another trusted address to inspect the jail’s ban list and unban the verified address. Then determine whether the threshold is too aggressive, a monitoring job is retrying stale credentials, or the source address is shared. Do not solve recurring false positives by adding a broad permanent ignore rule.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The application becomes unreachable

Compare the service’s listening port with the firewall rules and check whether it binds only to localhost or a private address. Add an allow rule only for the intended protocol and source. A database or management interface should normally be reachable through a private network or restricted administrator range, not opened globally for convenience.

An IPv6 path bypasses the policy

Review IPv6 listeners and firewall entries independently. Mirror only the rules that the service genuinely needs, and disable an unused public IPv6 path according to your provider and operating-system design rather than assuming an IPv4-only review is sufficient.

Maintain the hardening over time

  • Patch on a schedule: apply security updates and reboot when required, with console access available.
  • Rotate access deliberately: remove departed administrators’ keys, add replacement keys, and test the replacement before deleting the old one.
  • Review exposure after changes: new packages, containers, control panels, and monitoring agents can open listeners or require new firewall rules.
  • Watch logs: review SSH accepts and failures, firewall rejects, and Fail2Ban actions. A quiet jail can mean either a quiet service or a broken backend.
  • Keep documentation current: record the administrator account, key ownership, SSH port, allowed source networks, public services, firewall authority, log backend, and unban procedure.
  • Test recovery: periodically verify that console access, a spare authentication method, and rollback instructions still work.

A practical decision guide

Situation Recommended approach Reason
Small Ubuntu VPS with SSH and a few public services UFW with explicit SSH and application rules, plus Fail2Ban for SSH. Readable rules and simple status output reduce operator error.
Custom packet filtering, multiple chains, or complex address sets Direct nftables, with a tested persistent ruleset and documented rollback. Granular control is worth the additional syntax and review burden.
SSH access from a stable corporate or VPN address Restrict the SSH rule to that source range and keep console recovery. It reduces exposed attack surface without relying only on a port change.
Administrators need phishing-resistant authentication Add a compatible FIDO2/U2F hardware key and maintain a tested spare or recovery route. Hardware-backed authentication strengthens the key-based login path.
Fail2Ban reports no events Check the jail’s backend, log path, SSH port, and recent authentication records. A reaction layer is useful only when it can observe the host’s real events.

The reliable sequence is consistent: preserve a working session, create and test the named administrator’s key, allow the real SSH path before activating a firewall, expose only required services, validate and reload SSH, align Fail2Ban with the host’s log backend, and verify everything from a second session before closing the first.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fail2banLinux administrationnftablesSSH hardeningUFWVPS security

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.