Skip to content
Infrastructure / Hardening

Hardening

What KamalCloud checks on a machine, and the fixes it will apply one at a time.

The Security page for a server checks the machine over SSH and lists what is wanting. Each fix is its own button and its own run. Nothing is applied because you visited the page.

One step per run is deliberate. Applying all of it at once means one long opaque job that either worked or did not; applying one thing means you can see what changed and stop.

The checks

Fix What it does
firewall Opens SSH, 80 and 443, then turns on the machine’s own firewall
web_ports Allows SSH, HTTP and HTTPS through a firewall that is already running
cloud_firewall Attaches the provider’s firewall to the machine
ssh_password_auth Turns off password logins
ssh_root_login Limits root to key logins
ssh_keepalive Keeps SSH sessions alive
fail2ban Installs fail2ban
fail2ban_aggressive Turns on fail2ban’s aggressive SSH mode
automatic_updates Turns on automatic security updates
upgrade Updates packages
swap Adds a swap file of half the machine’s memory, at least 1 GB and at most 2 GB
storage Creates /storage, mode 700, owned by 1000:1000

cloud_firewall is the one that is not on the machine at all – the firewall in front of it belongs to the provider’s API, so it does not appear for self-hosted machines.

Which machines

The fixes are written for Debian and Ubuntu (ufw, apt) and for RHEL and Fedora (firewalld, dnf). A machine already running firewalld keeps it, whatever the distribution.

They install packages and edit system files, so KamalCloud only applies them when it signs in as root. A server reached as another user is refused up front, with a sentence saying so – there is no sudo handling, because guessing at a password prompt halfway through an upgrade is worse than not starting. Point the server at root, or make the change on the machine yourself.

Applying a fix is admin only.

Running one

Press the fix. It runs over SSH and streams to the page. Most take a few seconds; upgrade is all apt or dnf and takes as long as that takes.

A run can be stopped. Stopping marks it: the worker is inside a command and cannot be interrupted from the outside, so it finds itself cancelled when the command returns. A run that goes quiet for fifteen minutes is presumed dead and marked failed, so a restarted worker never leaves a row saying “running” forever.

Order

There is no enforced order, but two things are worth knowing:

  • firewall comes first. It opens the SSH port KamalCloud uses, 80 and 443 before it turns the firewall on, so it does not lock anyone out. web_ports only adds rules to a firewall that is already running; on a machine with none it fails with “No firewall is running here, so there is nothing to open.” It is for a machine whose firewall was turned on some other way – Fedora and RHEL ship firewalld with only SSH open.
  • Apply ssh_password_auth only once a key you hold is definitely on the machine. Check the SSH key page first.

Ports your apps need

Hardening opens SSH, HTTP and HTTPS. Anything else your apps publish – mail, game servers, databases exposed on purpose – is opened per environment from its ports, and applied to the provider’s firewall at each deploy.

From the API

servers.harden takes a server_id and a step from the table above – from the CLI, kamal-cloud harden 12 firewall. Like everything else the API proposes, it waits for a person to approve it. See Change requests.