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.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A secure Linux VPS starts with access control, a default-deny firewall, prompt patching and backups that you have actually restored. Create a non-root administrator, use SSH keys only, disable root and password logins, expose only required ports, enable automatic security updates, and keep tested copies of data and configuration off the server. Then verify the controls from another machine and repeat the checks on a schedule.

What to do first on a new Linux VPS

Do the initial hardening before deploying an application. A newly provisioned server may already contain packages with known vulnerabilities, and an exposed SSH service begins receiving automated login attempts quickly.

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.
  1. Open a second SSH session from your workstation and keep the original session connected. You need the existing session to undo a firewall or SSH mistake.
  2. Update the package index and install all available updates:
    sudo apt update && sudo apt full-upgrade -y
  3. Create a named administrator and grant sudo access:
    sudo adduser deployadmin
    sudo usermod -aG sudo deployadmin
  4. Install your public key for that account (use your distribution’s preferred method, or create /home/deployadmin/.ssh/authorized_keys with ownership deployadmin:deployadmin and mode 600).
  5. Test the new account in the second session before changing the SSH daemon configuration.

The commands above are Ubuntu/Debian examples. Other distributions use different package managers, service names or sudo-group conventions; follow the target distribution’s documentation.

SSH hardening: make keys the baseline

Key-only SSH with root and password login disabled is the baseline recommended across the hardening guidance. Edit /etc/ssh/sshd_config and set or confirm:

#1 Best Overall
PubkeyAuthentication yes
PermitRootLogin no
PasswordAuthentication no

Validate the configuration before reloading it:

sudo sshd -t
sudo systemctl reload ssh

From another machine, open a new connection as the named user. Do not close the known-good session until key authentication and sudo both work. If the test fails, restore the previous setting from the open session and reload SSH.

Should you move SSH off port 22?

Changing the port reduces automated scan noise but does not replace authentication controls. Keys, disabled root login and disabled password login provide the meaningful protection. If you do change the port, choose an unused port, allow it in the firewall before restarting SSH, and test a new connection while the old one remains open. Remember to update monitoring, configuration management and any provider-level firewall rule.

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

Optional second factors and network restrictions

Two-factor authentication over SSH and restricting SSH to a trusted source network can add protection, but the guides differ on implementation and on whether they are practical for every deployment. Treat them as optional layers. A network restriction that accidentally excludes your recovery address can lock you out, so test it from every administration location.

Build a default-deny firewall

Allow only traffic that the server must receive. A typical web VPS needs SSH, HTTP and HTTPS; an internal database, queue or administration panel should not be public.

UFW setup on Ubuntu

  1. Set safe defaults:
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
  2. Allow SSH before enabling the firewall. The limit rule rate-limits repeated connection attempts:
    sudo ufw limit 22/tcp
  3. Allow web traffic only when the server provides it:
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
  4. Enable and inspect the result:
    sudo ufw enable
    sudo ufw status verbose

If SSH uses a different port, substitute that port in the rule. Remove broad rules you do not need; an old temporary allow rule is a common way to leave a service exposed.

Verify from outside the VPS

A local status display shows configured rules, not necessarily the path a packet takes through provider firewalls, container networking or a load balancer. From a separate machine, scan the public address and compare the result with your intended exposure:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
nmap -Pn your.server.example

Investigate every open port. Check the listening process with sudo ss -tulpn, then either restrict the service to a private interface, add an explicit firewall policy or stop it.

Fail2ban for repeated login failures

Fail2ban watches logs and temporarily bans addresses that repeatedly fail authentication. Install it and enable its service:

sudo apt update
sudo apt install fail2ban
sudo systemctl enable --now fail2ban

Keep local changes in /etc/fail2ban/jail.local rather than editing the packaged defaults. Enable the SSH jail and set values appropriate to your risk and support requirements; a typical configuration includes enabled = true and the correct SSH port. Confirm operation with:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Fail2ban is not a substitute for key-only authentication or a firewall. Whitelist your administration network only when you understand the recovery implications, and monitor the jail so a misconfigured log path does not create false confidence.

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

Automatic security updates on Ubuntu

On Ubuntu, the unattended-upgrades package is installed by default and applies security updates automatically. Its policy is controlled primarily by /etc/apt/apt.conf.d/50unattended-upgrades and scheduling by /etc/apt/apt.conf.d/20auto-upgrades. The job runs once per day by default.

Enable and inspect the service

  1. Install the package if it is absent:
    sudo apt update
    sudo apt install unattended-upgrades
  2. Run the interactive enablement command if your image has not enabled it:
    sudo dpkg-reconfigure unattended-upgrades
  3. Review allowed origins and exclusions in /etc/apt/apt.conf.d/50unattended-upgrades.
  4. Check the daily schedule in /etc/apt/apt.conf.d/20auto-upgrades.

Do not blindly copy a setting from a guide written for another Ubuntu release. In particular, verify the current release’s reboot-related option in the installed manpage before allowing automatic reboots. Decide when a reboot is acceptable, how you will receive notifications and who will handle packages that are held back.

Test without changing packages

A dry run simulates installation and helps expose repository, pinning or dependency problems:

sudo unattended-upgrade --dry-run --debug

A dry run does not create a backup and does not apply updates. Review the real log at /var/log/unattended-upgrades/unattended-upgrades.log after the scheduled job runs. Also inspect general package logs when an update appears stuck.

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

Automatic versus manual patching

Approach Strength Operational risk Use it when
Automatic security updates Shortens the window in which a published vulnerability remains unpatched. Reboots, dependency changes or held packages can surprise an unprepared operator. The VPS has monitoring, a defined reboot policy and a tested recovery path.
Manual patching only Gives deliberate change control and maintenance windows. Updates are easy to postpone, leaving known vulnerabilities exposed. You have a reliable, frequent patch schedule and can respond quickly to advisories.

Many production systems use automatic security patches with planned reboot windows for kernels and other components that require one. Record exceptions rather than silently leaving a package unpatched.

Docker and the “UFW is open but the port is reachable” problem

Published Docker ports can bypass ordinary UFW expectations. Container traffic may be handled through forwarding and Docker-managed chains rather than the host’s INPUT path, so ufw status can look restrictive while a published container port is reachable from the internet. This behavior and the remedies below are community-sourced; verify them against the Docker documentation and your Docker release before applying rules.

Inspect mappings, not just UFW

docker ps
sudo ss -tulpn

A mapping such as 0.0.0.0:8080->80/tcp binds the host port on all interfaces. If the service is only for local reverse-proxy traffic, bind it to loopback instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
docker run -p 127.0.0.1:8080:80 image-name

With no IP address in the -p option, Docker normally binds the published port to all host interfaces. Loopback binding keeps that port off the public interface, while a reverse proxy can still reach it locally.

Other control options

  • DOCKER-USER chain rules: apply filtering in Docker’s documented user chain. Because destination NAT has already rewritten the packet, match the container-facing destination port where appropriate, not only the original host port. Test both allowed and denied source addresses.
  • UFW integration helpers: a tool such as ufw-docker can translate an intended policy into rules that account for Docker forwarding. Review what it changes before deploying it.
  • Disable Docker iptables management: guides report that this can break container networking, so it is generally avoided unless you have designed and tested a complete replacement.

Hand-added rules may disappear or become ineffective after a reboot or Docker restart. Persist them with a supported mechanism such as iptables-persistent, a systemd unit, or the chosen integration tool, and include the rule set in your configuration backup.

Backups that can recover a VPS

A copy on the same host is not a recovery plan: disk failure, account compromise, accidental deletion and ransomware can remove both the live data and its local copy. Keep backups off the VPS and test a restore. The restore test is what proves that a backup is usable.

What to back up

  • Application data and uploaded files.
  • Database exports made with the database’s dump utility, rather than copying a live database directory blindly.
  • Web-server, application and service configuration.
  • /etc/ssh/sshd_config, firewall rules and Fail2ban configuration.
  • TLS certificate material and renewal configuration, stored with appropriate permissions.
  • Deployment manifests, environment templates and package/version records needed to rebuild the host.

Do not place private keys, passwords or unencrypted environment files in a broadly readable backup location. Encrypt archives in transit and at rest, and store decryption credentials separately from the VPS.

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

A simple file-backup pattern

For a small system, create a dated archive on a different machine or backup service. The following illustrates the selection step; adapt paths and destination authentication to your environment:

sudo tar --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run 
  -czf /tmp/vps-config-$(date +%F).tar.gz /etc/ssh /etc/ufw /etc/fail2ban /srv/app

Copy the archive off-host immediately, verify its checksum after transfer and apply a retention policy that keeps several recovery points. For larger trees, an incremental tool can reduce transfer time, but it still needs periodic full-restore testing.

Database consistency

Schedule database-native dumps or snapshots at a time and frequency that match the application’s recovery-point objective. Check the dump by listing or importing it into an isolated test database. A successful file copy is not proof that an in-use database can be recovered.

Run a restore drill

  1. Provision a clean temporary VPS or isolated virtual machine with the same distribution family.
  2. Install the required packages and copy the backup without exposing the test host publicly.
  3. Restore configuration, database and application files.
  4. Start services, run health checks and verify representative user data.
  5. Measure how long the process took and record missing steps, permissions or secrets.

Repeat the drill after major architecture, distribution or backup changes. Keep the documented restore procedure with the backup metadata, not only on the server that might be lost.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Ongoing monitoring and audit

Hardening is a cycle rather than a one-time command list. Schedule a periodic audit with a tool such as Lynis, review authentication and system logs, and compare listening ports with the approved inventory.

Monthly or after major changes

  • Run an audit and review high-priority findings instead of accepting its score without context.
  • Check journalctl, SSH authentication logs, Fail2ban bans and unattended-upgrades logs.
  • Run an external scan from a separate network.
  • Confirm that backups completed, are off-server and still decrypt or restore.
  • Review user accounts, sudo membership, SSH keys and stale service credentials.
  • Check disk space; a full filesystem can stop logging, databases and package updates.

Security choices at a glance

Decision Recommended baseline Important qualification
SSH port Keep 22 or move it for noise reduction. A new port is not a security control by itself; update firewall and monitoring before switching.
Authentication SSH keys; root and password login disabled. Keep a tested recovery account and an open session during changes.
Inbound firewall Default deny; allow only required ports such as SSH, 80 and 443. Verify externally and account for provider and container networking.
Brute-force defense Fail2ban for repeated login failures. It complements, rather than replaces, strong authentication and network controls.
Patching Full update on day one, then automatic security updates where suitable. Define reboot timing and a process for held or failed packages.
Backups Encrypted, off-server copies plus a tested restore. Include databases, secrets needed for recovery and server configuration.
Containers Publish only necessary ports; bind private services to loopback. Docker forwarding can bypass UFW’s ordinary input rules; persist the effective policy.

A practical operating rhythm

On day one, update the host, create and test a sudo user, install the SSH key, disable root and password login, and establish a default-deny firewall. Before exposing an application, scan the public address and inspect every listening service. Add Fail2ban, enable and test unattended security updates, and create an encrypted off-server backup that includes data and configuration. Thereafter, review logs and ports regularly, apply or investigate updates, and perform restore drills often enough that recovery is a rehearsed procedure rather than an assumption.

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.