Linux VPS Security Hardening: SSH, Firewall, Updates & Server Protection

Author Avatar Digital Bhatti
• September 24, 2026 • Web Hosting

Linux VPS security hardening is the process of reducing unnecessary attack surface, protecting privileged access, keeping software maintained, limiting exposed services, and ensuring that a compromise or configuration failure does not automatically become a complete server loss.

An internet-facing Ubuntu or Debian VPS should not be secured by one command, one firewall, or one intrusion-prevention tool.

A stronger workflow is:

inventory → patch → create controlled administrative access → verify SSH keys → restrict authentication → firewall exposed services → protect internal services → monitor → back up → test recovery.

This guide focuses on SSH access, sudo users, firewalls, UFW, Fail2Ban, automatic security updates, service exposure, database and Redis binding, secrets, logs, backups, monitoring, and safe validation.

Research methodology

This guide is based on current OpenSSH configuration documentation, Ubuntu Server firewall documentation, Ubuntu security-update guidance, Fail2Ban configuration practices, current Docker security/networking documentation, Linux administration practices, and implementation analysis. It is not a penetration test or controlled Digital Bhatti security benchmark. Commands and configuration examples must be adapted to the actual distribution, hosting provider, service layout, and recovery options.

Last verified: September 24, 2026. OpenSSH defaults, package versions, firewall tooling, container networking, systemd units, cloud-provider networking and distribution behavior can change. Validate the effective configuration on the actual server before applying restrictive changes.

Distribution scope: Ubuntu and Debian are similar, not identical

The package-management and systemd examples in this guide fit current Ubuntu/Debian-family servers, but firewall defaults differ. Ubuntu documents ufw as its default firewall configuration tool, while Debian uses nftables as its default/recommended firewalling framework.

Before copying firewall commands, identify the distribution, release, active firewall frontend, provider firewall, container runtime and recovery path. Do not install or enable a second firewall frontend blindly on top of an existing ruleset.

Quick Answer

Harden Access First, Then Reduce Exposure, Then Prove Recovery

For a typical Ubuntu/Debian VPS, start by confirming console recovery, patching the OS, creating a dedicated sudo user, testing SSH keys, restricting authentication, allowing only required firewall ports, keeping databases/caches private, enabling monitored security updates, and maintaining an independent backup you have actually restored.


Critical SSH Rule

Never Disable Your Existing Login Method Until the Replacement Works

Create a separate administrative account, install and test its SSH key in a second terminal session, verify sudo access, and confirm your provider's recovery console before disabling password authentication or direct root login.


1. Linux VPS Security Priority Matrix

Layer Primary Risk Priority Control
SSH Credential compromise Key-based access, controlled sudo, MFA where available
Packages Known vulnerabilities Timely security updates
Network Unnecessary service exposure Firewall and private bindings
Applications Vulnerable web software Patching, least privilege, app hardening
Detection Undetected abuse or compromise Logs, monitoring and alerts
Recovery Permanent data/service loss Independent tested backups

2. Start With an Inventory

Before changing configuration, identify what is actually running and which distribution/release the server uses.

Start with read-only identification:

cat /etc/os-release
uname -r
systemctl --version | head -n 1

Review listening sockets:

sudo ss -lntup

Review running services:

systemctl --type=service --state=running

Record which services need:

  • Public internet access.
  • Private-network access.
  • Loopback/local access only.

3. Update the System Before Hardening Around Old Software

On Ubuntu or Debian-based systems, review available updates:

sudo apt update
apt list --upgradable

Apply appropriate updates according to your deployment and maintenance policy.

For a normal manually managed server:

sudo apt upgrade

For important production systems, consider staging, maintenance windows, snapshots, application backups, and rollback requirements before high-impact upgrades.


4. Understand unattended-upgrades

Ubuntu supports automatic package updates through unattended-upgrades.

Current Ubuntu security-update documentation says unattended-upgrades is included in standard Ubuntu Server installations and automatically applies security updates daily. Do not assume every VPS image preserves those defaults, so verify the package, timers and configuration on the actual server.

Check:

dpkg -l unattended-upgrades
systemctl status apt-daily-upgrade.timer

If it is not installed:

sudo apt install unattended-upgrades

The important configuration files include:

  • /etc/apt/apt.conf.d/20auto-upgrades
  • /etc/apt/apt.conf.d/50unattended-upgrades

For custom policy, current Ubuntu security guidance recommends adding a later drop-in file under /etc/apt/apt.conf.d/ rather than modifying the packaged 50unattended-upgrades file directly. For example, a site-specific file can use a higher lexical prefix such as 60local-unattended-upgrades.

Do not assume every third-party repository is automatically included in unattended updates.

Ubuntu's documentation specifically notes that simply adding a third-party repository does not make unattended-upgrades install updates from it. Review Allowed-Origins before assuming a control panel, database repository, PHP repository or other external package source is covered.


5. Automatic Updates Still Need Monitoring

Automatic updating reduces reliance on manual patching, but it does not eliminate operational responsibility.

Review logs:

ls -lah /var/log/unattended-upgrades/

Also determine whether:

  • A reboot is required.
  • A service restart is required.
  • Third-party packages remain outdated.
  • A failed package operation needs manual intervention.

Useful checks include:

test -f /var/run/reboot-required && cat /var/run/reboot-required
systemctl --failed
journalctl -p err -b

6. Create a Dedicated Administrative User

Instead of sharing a generic root login, create an individual administrative account where appropriate.

Example:

sudo adduser adminuser
sudo usermod -aG sudo adminuser

Replace adminuser with an appropriate account name.

Before restricting existing root access, verify that the new user can:

  • Authenticate.
  • Use its SSH key.
  • Run required sudo commands.
  • Reach the system through your real network path.

7. Generate a Strong SSH Key

On the administrator's local device, generate a modern SSH key if you do not already have an appropriate one.

For example:

ssh-keygen -t ed25519

Protect the private key.

A passphrase is recommended where the operational workflow supports it.

RSA is not automatically insecure Do not describe all RSA keys as obsolete or weak. Correctly generated modern RSA keys can still be supported. Ed25519 is a strong and convenient default for many current SSH deployments.

8. Install the Public Key

A convenient method where password login currently works is:

ssh-copy-id adminuser@SERVER_IP

Then test the new session:

ssh adminuser@SERVER_IP
sudo -v

Keep the original administrative session open while testing.


9. Back Up the SSH Configuration Before Editing

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

Modern distributions can also load configuration snippets from additional directories, so inspect the effective configuration rather than assuming one file is the only source.

On systems that use /etc/ssh/sshd_config.d/, a drop-in file can override or supplement the main file. VPS images may also contain provider or cloud-init-generated SSH snippets. Review the directory before creating a new override:

sudo ls -lah /etc/ssh/sshd_config.d/
sudo grep -RniE '^(PermitRootLogin|PasswordAuthentication|KbdInteractiveAuthentication|PubkeyAuthentication|AllowUsers|AllowGroups)' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/ 2>/dev/null

Prefer a small documented drop-in when the distribution supports it, and always validate the effective result before reloading.


10. Check the Effective OpenSSH Configuration

Use:

sudo sshd -T

This helps reveal effective values after includes and defaults are processed. Remember that upstream OpenSSH defaults are not proof of the effective setting on a provider image; distribution packaging, cloud-init, included snippets and local configuration can change the result.

Useful settings to review include:

  • PermitRootLogin.
  • PasswordAuthentication.
  • KbdInteractiveAuthentication.
  • PubkeyAuthentication.
  • MaxAuthTries.
  • AllowUsers or AllowGroups, where appropriate.

11. PermitRootLogin Is Not Simply “On by Default”

Current OpenSSH documentation defines the available values as:

  • yes
  • prohibit-password
  • forced-commands-only
  • no

The current OpenSSH sshd_config documentation lists prohibit-password as the default.

That means password and keyboard-interactive authentication are disabled for root while public-key authentication can remain possible.

If your operational model does not require direct root SSH access, using a dedicated sudo account and setting:

PermitRootLogin no

can be appropriate after alternate access is confirmed.


12. Disable PasswordAuthentication Only After Key Access Works

Once key-based authentication has been confirmed in a separate session, you may choose to disable SSH password authentication:

PasswordAuthentication no
PubkeyAuthentication yes

Also review keyboard-interactive authentication if your goal is to eliminate password-style SSH login paths.

Do not disable authentication methods required by an intentionally configured MFA solution.


13. Validate SSH Configuration Before Reloading

Before changing the running daemon:

sudo sshd -t

If validation succeeds, reload the service using the appropriate unit for your distribution.

Common possibilities include:

sudo systemctl reload ssh
# or
sudo systemctl reload sshd

Test another new SSH connection before closing the existing session.

Lockout recovery precaution Keep the working SSH session open until a second fresh login succeeds. If a change blocks access, use the still-open session to revert it. If that is unavailable, use the provider console/rescue environment rather than repeatedly guessing firewall or SSH changes remotely.

14. Do You Need to Change SSH From Port 22?

Changing the SSH port can reduce some automated log noise from bots that scan only common defaults.

It does not provide strong authentication or make SSH undiscoverable.

A port scanner can still find an exposed SSH service.

Therefore, changing the port is optional—not a replacement for:

  • Key-based authentication.
  • MFA where available.
  • Firewall restrictions.
  • Updates.
  • Monitoring.

15. Restrict SSH by Source Where Practical

If administrators connect from a known office network, VPN gateway, bastion host, or another stable source, firewall rules can restrict SSH more tightly.

For example, conceptually:

Internet
   ↓
Public HTTP/HTTPS

Trusted admin source
   ↓
SSH

This may not be practical for administrators with frequently changing IP addresses.


16. A VPN Is Optional, Not Required to Make SSH Encrypted

SSH itself already provides encrypted transport.

You do not need a commercial consumer VPN simply to prevent a public Wi-Fi operator from reading an SSH session in plaintext.

A private VPN, WireGuard network, bastion host, or zero-trust access layer can still be useful for reducing direct exposure of management interfaces, but that is an architectural choice.

Do not present a commercial VPN subscription as a mandatory VPS-security control.


17. Choose the Firewall Frontend That Matches the Distribution

Do not treat UFW as a universal Linux default.

Ubuntu: Ubuntu documents ufw as its default firewall configuration tool, although UFW is initially disabled until enabled.

Debian: Debian uses nftables as its default and recommended firewalling framework. On a Debian server, first inspect the existing ruleset and service state instead of assuming UFW is present:

sudo nft list ruleset
systemctl status nftables --no-pager

If the host already uses nftables, firewalld, a provider firewall, Docker-managed rules, or another policy layer, document that architecture before adding a second firewall frontend.


18. Configure UFW on Ubuntu Based on the Services You Actually Run

UFW provides a simpler host-firewall interface on Ubuntu. Current Ubuntu Server firewall documentation notes that UFW is initially disabled by default, so creating rules does not necessarily mean the firewall is active.

First inspect existing rules:

sudo ufw status verbose

Ubuntu also supports --dry-run for previewing a UFW command without applying it. Use that where useful while designing the rule set:

sudo ufw --dry-run allow 22/tcp

A common policy for a simple server is:

sudo ufw default deny incoming
sudo ufw default allow outgoing

But the allowed services depend on the actual workload.


19. Protect SSH Before Enabling UFW Remotely

When configuring a remote VPS, make sure the firewall allows your actual SSH service before enabling it.

For a server genuinely using SSH on TCP port 22:

sudo ufw allow 22/tcp

If SSH uses another port, allow the actual port instead.

Then add only the web or application services required.

For a typical HTTPS website this may include:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

These are examples, not a universal server firewall.

Only after the real SSH path and every required service are accounted for should you enable UFW remotely:

sudo ufw enable

Keep the working SSH session open and immediately verify a second new connection.

Before and after enabling UFW, verify the rule set:

sudo ufw status numbered
sudo ufw status verbose

20. Consider UFW Rate Limiting for SSH

UFW supports a limiting rule intended for services such as SSH.

For a normal SSH service definition:

sudo ufw limit ssh/tcp

Whether this is useful depends on your access pattern and existing firewall/WAF/provider controls.


21. Cloud Firewalls and UFW Can Be Used Together

Many VPS providers offer an external firewall or security-group layer.

A useful defense-in-depth model can be:

Internet
   ↓
Provider Firewall
   ↓
Linux Firewall
   ↓
Application Services

Keep both layers documented so troubleshooting does not become a guessing exercise.


22. Do Not Expose MySQL or MariaDB Publicly Without a Requirement

For a normal application and database running on the same VPS, the database often needs only local access.

Inspect listeners:

sudo ss -lntp | grep 3306

If remote database access is required, restrict sources and secure the network path rather than exposing the service globally.


23. Do Not Expose Redis Publicly

Redis used for WordPress or application caching should generally be local or private.

Inspect:

sudo ss -lntp | grep 6379

Do not assume that a caching plugin requires a public Redis listener.


24. Remove Services You Do Not Need

Review enabled services:

systemctl list-unit-files --type=service --state=enabled

Potentially unnecessary services may include:

  • Legacy FTP services.
  • Unused mail daemons.
  • Development servers.
  • Old database instances.
  • Abandoned monitoring agents.
  • Unused control panels.

Do not disable an unfamiliar system component before confirming what depends on it.


25. Fail2Ban Is an Additional Layer

Fail2Ban monitors configured logs and can apply temporary bans when matching patterns repeatedly occur.

Install on Ubuntu/Debian where it fits your security model:

sudo apt update
sudo apt install fail2ban

Check the service:

sudo systemctl status fail2ban

26. Fail2Ban Does Not Replace Strong Authentication

Fail2Ban can reduce repeated incorrect login attempts, but it does not make a weak password safe.

Prioritize:

  • Key authentication.
  • MFA where appropriate.
  • Least privilege.
  • Firewall restrictions.

Fail2Ban then becomes an additional abuse-control layer.


27. Configure Fail2Ban in Local Overrides

Do not depend on directly editing package defaults that may change during upgrades.

Fail2Ban's upstream configuration specifically recommends leaving packaged *.conf files unchanged and placing custom settings in jail.local, fail2ban.local, or matching *.local files under the relevant .d directories. This reduces upgrade conflicts.

A minimal SSH override can look like:

[sshd]
enabled = true

Do not copy arbitrary bantime, findtime or maxretry values without considering the real login pattern.

After configuration, inspect enabled jails:

sudo fail2ban-client status

Then inspect a specific jail when configured:

sudo fail2ban-client status sshd

28. Avoid Aggressive Fail2Ban Values Without Testing

Extremely low retry counts or very long bans can block legitimate administrators when:

  • Several users share one NAT address.
  • An administrator mistypes a key or password.
  • A monitoring service authenticates incorrectly.

Use settings appropriate to the real traffic pattern.


29. Review Package and Repository Hygiene

Every additional package source expands the software supply chain you must trust and maintain.

  • Remove repositories that are no longer required.
  • Use vendor/documented signing-key mechanisms rather than copying unknown installation commands.
  • Confirm third-party repositories support the Linux release you run.
  • Check whether their packages are included in your automatic-update policy.
  • Avoid installing server tools from abandoned or unofficial repositories simply for convenience.

Review configured APT sources and package origins before assuming all software follows Ubuntu's security-update lifecycle.


30. Containers Are Not a Security Boundary by Magic

Running an application in Docker can improve process and dependency isolation, but it does not guarantee that the host cannot be compromised.

Container security still depends on:

  • Kernel security.
  • Container privileges.
  • Mounted host paths.
  • Capabilities.
  • Image provenance.
  • Secrets.
  • Docker daemon access.
  • Network exposure.

Do not describe Docker as automatically preventing host compromise.


31. Audit Docker Port Publishing Separately From UFW

Docker networking deserves its own exposure check. Current Docker documentation warns that a published container port is reachable on all host interfaces by default when no host IP is specified.

For example:

docker run -p 8080:80 nginx

publishes the host port on all host addresses by default, making it potentially reachable from outside the host when upstream networking/firewall rules permit it, while:

docker run -p 127.0.0.1:8080:80 nginx

restricts that published port to loopback on current Docker releases.

Docker firewall warning Docker's current documentation says Docker and UFW can interact in a way that causes published container traffic to be diverted before it reaches the UFW chains administrators normally expect. A host-level UFW deny rule is therefore not sufficient proof that a Docker-published port is unreachable. Audit published ports separately with docker ps, ss, provider-firewall rules and external connectivity tests.

See Docker’s current port-publishing guidance before exposing databases, dashboards or internal applications.


32. Avoid Privileged Containers Unless Required

Review whether containers need:

  • privileged.
  • Host networking.
  • Docker socket access.
  • Broad host-directory mounts.
  • Excess Linux capabilities.

Grant only what the application actually requires.


33. Protect the Docker Daemon and Socket

Docker’s daemon normally listens on the local Unix socket. Do not expose an unauthenticated Docker TCP API to the public internet.

Docker explicitly warns that access to the daemon or its socket can effectively grant root-level control over the host. If remote administration is genuinely required, use a supported secure method such as SSH or mutually authenticated TLS and tightly restrict who can reach it.

Also treat membership in the local docker group as highly privileged access rather than an ordinary convenience permission.

Use Docker’s current daemon-socket protection guidance before enabling remote Docker access.


34. Protect Public Web Services With HTTPS

For public websites, APIs and control panels, terminate HTTPS using a valid certificate and keep HTTP-to-HTTPS behavior intentional.

TLS protects traffic in transit, but it does not replace application authentication, authorization, patching or firewalling.

Also avoid exposing administrative dashboards publicly when a private management path, IP restriction or additional authentication layer is practical.


35. Protect Secrets

Never publish:

  • SSH private keys.
  • Database passwords.
  • Cloud API keys.
  • DNS tokens.
  • Backup credentials.
  • Application secrets.

If a secret is exposed, removing it from a visible file is not enough.

Rotate or revoke the credential. Then determine where it was exposed, remove it from logs/history/artifacts where feasible, update dependent services, and review access logs for unauthorized use.


36. Review File Ownership and Permissions

Application files should be writable only by the accounts and processes that actually need write access.

For web stacks, avoid broad fixes such as recursively applying world-writable permissions. Review the ownership model for:

  • Web document roots.
  • Uploads/cache directories.
  • Configuration files.
  • Private keys and certificates.
  • Backup archives.
  • Deployment credentials.

Use the application's documented ownership model rather than generic chmod 777 advice.


37. Review sudo Access

List sudo-capable users/groups according to the distribution's configuration.

Review:

sudo visudo -c

Use visudo when editing sudo configuration so syntax can be validated safely.


38. Remove Dormant Linux Accounts

Review users:

getent passwd

Do not delete service accounts simply because they are unfamiliar.

Focus on obsolete human, contractor, deployment, and test accounts whose purpose is known.


39. Keep Web Applications Patched Too

A fully patched Ubuntu server can still be compromised through an outdated WordPress plugin, CMS extension, application dependency, or control panel.

Operating-system hardening and application hardening are separate layers.

For WordPress-specific controls, continue with the WordPress Security Hardening Guide.


40. Protect Control Panels

Control panels can provide access to:

  • Sites.
  • Databases.
  • DNS.
  • Certificates.
  • Email.
  • Server configuration.

Therefore:

  • Keep the panel updated.
  • Use strong administrator authentication.
  • Restrict public access where practical.
  • Remove abandoned panel installations.
  • Monitor administrative access.

For CyberPanel, use the CyberPanel + OpenLiteSpeed Guide.


41. Maintain Useful Logs

Review relevant sources such as:

  • SSH/authentication logs.
  • systemd journal.
  • Firewall logs.
  • Fail2Ban logs.
  • Nginx/Apache/OpenLiteSpeed logs.
  • Application logs.

Examples:

sudo journalctl -p warning --since today

sudo journalctl -u ssh --since today

The SSH unit name can differ by distribution or image. Confirm the actual service before assuming ssh.service or sshd.service:

systemctl status ssh --no-pager 2>/dev/null
systemctl status sshd --no-pager 2>/dev/null

If web availability problems involve reverse-proxy or upstream failures, use the Nginx 502 & 504 Troubleshooting Guide.


42. Monitoring Should Be External Too

If the entire VPS becomes unavailable, software running only on that VPS cannot reliably notify you of the outage.

Monitor externally for:

  • HTTPS availability.
  • DNS resolution.
  • TLS expiry.
  • Important application endpoints.

For a self-hosted monitoring implementation, continue with the Uptime Kuma Monitoring Guide.

Availability monitoring is not intrusion detection. Uptime Kuma can tell you that a service is reachable or failing; it does not replace authentication-log review, host telemetry, file-integrity controls, EDR/HIDS tooling, or incident-response procedures.


43. Monitor Resource Pressure

Availability and security overlap when severe resource exhaustion causes service crashes.

Monitor:

  • CPU.
  • RAM.
  • Swap.
  • Disk space.
  • Disk I/O.
  • Process restarts.
  • OOM kills.

Check memory:

free -h

Check filesystem capacity:

df -h

44. Check for OOM Events

When memory is exhausted, Linux may terminate processes.

Review kernel logs:

dmesg -T | grep -i -E 'out of memory|oom|killed process'

Unexpected process termination can cause availability problems and may also obscure the real source of an application outage.


45. Backups Are Part of VPS Hardening

Hardening reduces risk but cannot guarantee that a server will never fail or be compromised.

Back up:

  • Application files.
  • Databases.
  • Uploads.
  • Important configuration.
  • Deployment information.

Do not treat a provider snapshot as your only recovery copy for critical systems.

For object-storage, retention and restore-design considerations, see the Cloud Storage & Backup Options for Developers.


46. Keep an Independent Recovery Copy

A useful model is:

Production VPS
     ↓
Provider snapshot

Production VPS
     ↓
Independent backup location

This reduces the chance that one provider-account or server-level incident destroys every recovery copy.


47. Test Restoration

Periodically prove that you can restore:

  • Database.
  • Application files.
  • Configuration.
  • Required secrets through a secure recovery process.

A backup job that completed successfully is not proof that restoration will work.


48. Keep Provider Recovery Access Available

Before aggressive SSH or firewall hardening, confirm whether your provider offers:

  • Web console.
  • Serial console.
  • Rescue environment.
  • Snapshot recovery.

This can be critical if a firewall or SSH configuration error locks out normal network access.


49. Do Not Invent Security Benchmarks

A claim such as:

“Fail2Ban reduced attacks by 98.5% and cut idle CPU from 18% to under 1%”

requires a documented test environment, log dataset, time period, attack definition, system specifications, methodology, and reproducible measurements.

Without that evidence, present the expected mechanism instead:

Fail2Ban can temporarily block sources that repeatedly match configured authentication-failure patterns.


50. Changing SSH Port Does Not Stop Reconnaissance

Moving SSH away from port 22 may reduce low-effort automated log noise.

It does not:

  • Prevent port scanning.
  • Replace strong authentication.
  • Fix vulnerable SSH software.
  • Prevent credential theft.

Do not present a custom port as a major cryptographic or access-control improvement.


51. Baseline VPS Hardening vs Application Hardening

Layer Examples Owner
Linux/VPS baselineSSH, sudo, firewall, patching, services, file permissions, backups, host logsThis guide
Web-server layerNginx/OpenLiteSpeed/Apache configuration, TLS, PHP-FPM, upstream accessWeb-server/application stack
WordPress layerAdmin access, plugins/themes, XML-RPC, REST permissions, file/editor settingsWordPress security hardening
Control-panel layerPanel authentication, panel updates, exposed admin ports, service defaultsPanel-specific guidance

52. Linux VPS Hardening Workflow

Inventory Services
       ↓
Update System
       ↓
Confirm Recovery Console
       ↓
Create Sudo User
       ↓
Install SSH Key
       ↓
Test New Login
       ↓
Validate SSH Config
       ↓
Restrict Root / Password Access
       ↓
Identify Active Firewall Stack
       ↓
Configure Firewall
       ↓
Restrict Database / Redis
       ↓
Configure Fail2Ban if Useful
       ↓
Review Automatic Updates
       ↓
Enable Logs / Monitoring
       ↓
Verify Backups
       ↓
Test Recovery

53. Safe First-Day VPS Hardening Checklist

  1. Confirm provider console/rescue access.
  2. Inventory open ports and running services.
  3. Install pending security updates.
  4. Create a dedicated sudo-capable administrative user.
  5. Install an SSH public key.
  6. Test key login in a second terminal.
  7. Verify sudo access.
  8. Validate sshd configuration.
  9. Restrict password/root authentication where appropriate.
  10. Identify the distribution's active firewall stack before changing rules.
  11. Configure firewall rules for actual services.
  12. Keep databases/caches private.
  13. Enable or verify update automation.
  14. Add Fail2Ban if it fits the threat model.
  15. Configure logging and monitoring.
  16. Verify an independent backup.

54. Common Linux VPS Hardening Mistakes

  • Disabling password SSH before testing keys: can lock you out.
  • Closing the original SSH session too early: removes an easy recovery path while testing.
  • Assuming root password SSH is the OpenSSH default: current OpenSSH defaults are more nuanced.
  • Treating port 22 as inherently insecure: authentication and access control matter much more.
  • Allowing only 22/80/443 blindly: real service requirements differ.
  • Enabling UFW before allowing the active SSH path: can cause remote lockout.
  • Exposing MySQL or Redis publicly: internal services should normally stay private.
  • Assuming Fail2Ban replaces authentication: it does not.
  • Assuming a VPN is required to encrypt SSH: SSH already provides encrypted transport.
  • Assuming Docker prevents host compromise: container isolation depends on configuration and kernel security.
  • Assuming UFW automatically blocks Docker-published ports: Docker manages host firewall/NAT rules and published ports must be audited separately.
  • Exposing the Docker daemon remotely without strong protection: Docker-daemon access can provide root-level control of the host.
  • Installing updates but never monitoring them: automation can fail or omit third-party repositories.
  • Keeping all backups on the VPS: one failure can affect both production and recovery.
  • Never testing restoration: a backup is useful only if it can be recovered.

55. Related Digital Bhatti Guides


Linux VPS Security Hardening Checklist

  • Inventory listening ports and running services.
  • Keep Ubuntu/Debian and packages maintained.
  • Review unattended-upgrades configuration and logs.
  • Confirm provider console or rescue access.
  • Create an individual administrative user.
  • Grant sudo only where required.
  • Use an appropriate SSH key.
  • Protect the private key with suitable controls.
  • Test the new SSH key before disabling password access.
  • Keep the existing SSH session open during changes.
  • Validate sshd configuration before reload.
  • Review PermitRootLogin based on the actual administration model.
  • Disable SSH password authentication only when a replacement path works.
  • Do not rely on changing SSH port for meaningful authentication security.
  • Restrict SSH by source network where practical.
  • Use UFW on Ubuntu or the existing documented firewall frontend; do not assume UFW is the Debian default.
  • Allow the active SSH path before enabling a firewall remotely.
  • Use provider/cloud firewalls where useful.
  • Keep MySQL/MariaDB private unless remote access is required.
  • Keep Redis private.
  • Remove unnecessary network services.
  • Use Fail2Ban only as an additional abuse-control layer.
  • Do not treat Fail2Ban as a replacement for strong authentication.
  • Audit Docker-published ports and bind internal services to loopback/private interfaces where appropriate.
  • Do not expose an unauthenticated Docker daemon/API.
  • Limit container privileges.
  • Protect API keys, SSH keys and application secrets.
  • Remove dormant accounts and credentials.
  • Review third-party APT repositories and their update coverage.
  • Keep applications and control panels patched.
  • Review file ownership and avoid world-writable permissions.
  • Use HTTPS for public web services and management interfaces.
  • Monitor authentication and system logs.
  • Monitor CPU, RAM, disk and OOM events.
  • Use external availability monitoring.
  • Maintain an independent backup.
  • Test restoration.
Next Security Layer

Running WordPress on This VPS?

After hardening Linux, SSH, services and network access, secure the WordPress application layer separately—administrator authentication, XML-RPC, REST API permissions, plugin/theme maintenance and WordPress configuration.

Open WordPress Security Guide →

Frequently Asked Questions

Should I use UFW on both Ubuntu and Debian?

Not automatically. Ubuntu documents UFW as its default firewall configuration tool, while Debian uses nftables as its default/recommended firewalling framework. Use the firewall stack already appropriate to the distribution and deployment, and avoid layering multiple frontends without understanding how their rules interact.

Is UFW enabled by default on Ubuntu Server?

No. Ubuntu documents UFW as its default firewall configuration tool, but UFW itself is initially disabled. Verify the actual state with sudo ufw status verbose before assuming firewall rules are active.

Are Ubuntu security updates installed automatically?

Standard current Ubuntu Server installations include unattended-upgrades and apply security updates automatically on a daily schedule. Verify the actual VPS image and remember that third-party repositories are not automatically included unless configured.

Should I edit Fail2Ban's jail.conf directly?

Prefer not to. Fail2Ban recommends keeping packaged .conf files unchanged and placing local overrides in jail.local or appropriate .local files under the configuration directories.

Should I disable root SSH login?

Using a dedicated sudo account and disabling direct root login is a strong option for many servers. Confirm that the sudo account, SSH key, and provider recovery console work before changing root access.

Is root password login enabled by default in OpenSSH?

Current OpenSSH documentation lists prohibit-password as the default for PermitRootLogin. Distribution packaging and local configuration can differ, so inspect the effective configuration with sshd -T.

Should I disable SSH password authentication?

Key-based SSH authentication is a strong approach, but disable password authentication only after confirming that key access works and an emergency recovery path is available.

Is Ed25519 better than RSA?

Ed25519 is a strong, compact and convenient modern default for many deployments. Correctly configured modern RSA keys are not automatically insecure, so do not rotate working RSA keys solely because a tutorial claims RSA itself is obsolete.

Should I change SSH from port 22?

You can if it reduces unwanted log noise or fits your architecture, but moving SSH to another port is not a substitute for strong authentication, firewall controls, updates or monitoring.

Do I need a VPN when using SSH from public Wi-Fi?

SSH already encrypts the SSH session. A trusted VPN or private management network can provide additional network architecture benefits, but a consumer VPN is not required simply to make SSH encrypted.

Should every VPS allow only ports 22, 80 and 443?

No. Firewall rules should reflect the actual services used by the server. Some systems need different SSH ports, DNS, mail, VPN, monitoring, control-panel, HTTP/3 or other services, while others need fewer exposed ports.

Should I expose MySQL or Redis to the internet?

Usually not for a normal single-server web application. Keep databases and caches on local or private interfaces unless remote connectivity is genuinely required and appropriately secured.

Does Fail2Ban make SSH secure?

No. Fail2Ban can reduce repeated authentication attempts from detected sources, but strong authentication, least privilege, firewalling and updates remain more fundamental controls.

Are unattended upgrades enough?

No. Automatic security updates reduce manual patching burden, but administrators should still monitor update logs, reboots, service health, unsupported packages and third-party repositories.

Does Docker prevent an attacker from reaching the host?

Not automatically. Container isolation depends on kernel security, capabilities, privileges, mounts, Docker daemon access and configuration. Highly privileged containers can significantly weaken isolation.

Do I need a VPS security plugin?

Linux VPS security is primarily handled through operating-system, SSH, firewall, service, application, backup and monitoring controls rather than one universal “security plugin.”

Can Linux VPS hardening guarantee that the server will never be hacked?

No. Hardening reduces attack surface and risk, but no configuration can guarantee that compromise or operational failure will never occur.

Abdul Shakoor, founder of Digital Bhatti
Written by

Abdul Shakoor

Founder of Digital Bhatti, an independent technical publication focused on web hosting and infrastructure, WordPress, technical SEO, web performance and automation.