Practical Security

Controls you can verify beat controls you assume are working.

5guides Feed

Security coverage here is scoped to systems a small team actually operates: a rented Linux host, containers, a database, a CI pipeline and a CDN in front. No threat modelling frameworks, no compliance checklists.

The organising principle is verification. A firewall rule you have not tested from outside the host is a belief. A backup you have not restored is a hypothesis. A permission you assume is narrow is worth checking, because the gap between intended and actual configuration is where nearly every self-hosted compromise lives.

The single most under-appreciated issue in this stack is that Docker manipulates iptables directly. Its rules are evaluated before the ones UFW manages, which means a container published with -p 5432:5432 is on the public internet even though the firewall shows a default-deny policy. People discover this from a compromised database, not from a scan.

After that, in rough order of value: key-only SSH with root login disabled; secrets in files with restrictive permissions rather than in images or workflow YAML; application database roles that cannot alter their own schema; and container settings that drop capabilities and block privilege escalation.

The supply chain deserves its own attention. A pipeline runs with production credentials, third-party actions run with access to those credentials, and a mutable version tag can point at new code tomorrow. Pinning to commit hashes and scoping tokens per job costs nothing and removes an entire category of risk.

Every article here includes the command that proves the control works, not just the command that configures it.

Start here

How to Secure a VPS That Runs Docker Containers

SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.

Intermediate · 4 min read

Beginner to advanced

A reading order that builds Security knowledge in the sequence it is actually needed.

  1. Start How to Point a Cloudflare Domain at Your VPS 4 min
  2. Build How to Secure a VPS That Runs Docker Containers 4 min
  3. Operate How to Run Cloudflare Tunnel in Front of Traefik 4 min
  • intermediate

    How to Secure a VPS That Runs Docker Containers

    SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.

    4 min

Common problems

Failure modes that come up repeatedly with Security, and where each one is solved.

The firewall does not cover container ports
Docker writes iptables rules evaluated before UFW's. A published port is reachable regardless of what `ufw status` reports.
Secrets are readable by everything on the host
Environment files with default permissions, secrets baked into images, and credentials in workflow files are the three usual leaks.
The application connects to its database as a superuser
Turns a SQL injection from a data leak into a host compromise. Separate the schema owner from the login role.
The origin is still reachable by IP address
A stale DNS-only record, or an allowlist that was never applied. Move inbound access behind a tunnel and confirm with an external scan.

Latest Security guides

Browse the archive
  • advanced

    How to Run PostgreSQL Securely on a VPS

    Keep the listener off the public internet, get pg_hba.conf right, require TLS for remote connections, and give the application a role that cannot drop your tables — on PostgreSQL 17 and Ubuntu 24.04.

    4 min
  • intermediate

    How to Run Meilisearch in Production with Docker

    A Meilisearch deployment that survives a real workload — master key handling, scoped API keys, the index settings you must set before loading data, snapshots, and what its memory usage actually means.

    4 min AI-assisted
  • advanced

    How to Run Cloudflare Tunnel in Front of Traefik

    Expose Docker services through Cloudflare with no inbound ports open — cloudflared plus Traefik, the forwarded-header setting that trips people up, and how to verify the firewall is closed.

    4 min
  • intermediate

    How to Secure a VPS That Runs Docker Containers

    SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.

    4 min
  • beginner

    How to Point a Cloudflare Domain at Your VPS

    Create the A record, pick the right proxy status, set the SSL mode to Full (strict) and lock the origin so only Cloudflare can reach it — plus what errors 521, 522, 525 and 526 actually mean.

    4 min

Recently updated

  • intermediate

    How to Secure a VPS That Runs Docker Containers

    SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.

    4 min

Frequently asked questions

What is the highest-value hardening step on a new server?

Key-only SSH authentication with root login disabled, followed immediately by checking whether published container ports are bypassing the firewall. Those two cover the overwhelming majority of opportunistic compromise.

How do I verify a firewall is actually working?

Scan from a different machine. Checking `ss -tlnp` on the host tells you what is listening, which is a different question from what the internet can reach.

Is changing the SSH port a security measure?

It reduces log noise from automated scanners and nothing else. Treat it as housekeeping, not as a control, and do not let it substitute for disabling password authentication.

Sources

  1. Docker packet filtering and firewalls Docker Primary source
  2. sshd_config manual page OpenBSD Primary source
  3. OWASP Top Ten OWASP Primary source
  4. Security hardening for GitHub Actions GitHub Primary source