Overview › Security › Hardening guide

Guide · do it yourself

Harden your own site, in 16 steps

A guide for anyone who puts a website or a homelab on the internet. It follows the tactics of MITRE D3FEND®: know what you have, then harden, detect, isolate, evict and restore. The seventh tactic, Deceive, is left out on purpose: decoys and honeypots only pay off once the basics are in place. Every step ends with a self-check question. You can answer the same questions in the D3FEND cube and see where you stand.

Order matters. Short on time? Start with steps 3, 6, 7 and 16: one entry point, a second factor, updates and a rehearsed restore. Those four cover the most common causes of real damage.

Model

D3FEND tactic
01

Keep an inventory

You can only protect what you know. A list of every service, device, image and version is the basis for everything else, from updates to recovery.

  • The simplest form is a file in your Git repository, one section per service.
  • Record per service: purpose, version, public yes/no, where its data lives.
  • Update it when you add or remove a service — not "later".
Self-check: Is there a current list of every service, device and version?
Asset InventorySoftware InventoryConfiguration Inventory
02

Know your attack surface

Which subdomains, ports and services does the internet see? Often more than you think: a forgotten test service, a router panel, an open database port.

  • Check from outside, e.g. over mobile data — not from your own LAN.
  • Certificate transparency logs show which subdomains are publicly known.
  • Write down dependencies: what breaks if the database or DNS goes down?
Self-check: Do you know which services are visible from outside and what depends on what?
Network MappingService Dependency Mapping

Harden

D3FEND tactic
03

Exactly one entry point, everything else closed

A reverse proxy accepts every request on port 443 and routes it. No service gets its own port on the router. Databases and admin panels are not reachable from outside at all.

  • Router: forward only 80/443, and 80 only for the redirect to HTTPS.
  • Apps without strong sign-in of their own go behind a central login, e.g. via ForwardAuth.
  • Services only you need belong behind a VPN, not on the public internet.
Self-check: Is there exactly one public entry point and a login in front of every app?
Network Access MediationWeb Session Access Mediation
04

TLS everywhere, renewed automatically

Every connection is encrypted. Certificates renew themselves — an expired certificate is the most common self-inflicted outage.

  • Let's Encrypt with automatic renewal, ideally a wildcard certificate via DNS challenge.
  • Enable HSTS so browsers never ask unencrypted again.
  • Switch off outdated protocols (TLS 1.0/1.1).
Self-check: Is every connection TLS-encrypted, with certificates renewing automatically?
Message EncryptionCertificate Rotation
05

Set security headers

A handful of response headers tell the browser what it may do. The most important is the Content Security Policy: it defines where scripts, styles and fonts may be loaded from. A generic example for a purely static site:

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self';
  img-src 'self' data:; font-src 'self'; frame-ancestors 'none';
  base-uri 'self'; form-action 'self'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
  • Test in "Content-Security-Policy-Report-Only" mode first, then enforce.
  • Self-host fonts and libraries instead of loading them from a CDN. That helps privacy, too.
Self-check: Does your site send security headers such as CSP and HSTS?
Application Configuration Hardening
06

A second factor for every sign-in from outside

Stolen passwords are the most common way in. A second factor makes a captured password worthless on its own.

  • Passkeys or hardware keys are best, otherwise a TOTP app. SMS only if nothing else works.
  • A central identity provider means configuring it right once instead of in every app.
  • Keep recovery codes offline.
Self-check: Does every sign-in from outside require a second factor?
Multi-factor AuthenticationOne-time Password
07

Updates by plan, not by luck

Known vulnerabilities are exploited automatically within hours. Updates must come quickly — but traceably.

  • Pin image versions instead of :latest. That way you know what runs.
  • A bot (e.g. Renovate) proposes new versions as pull requests; you decide.
  • Subscribe to security advisories for your key components.
Self-check: Are updates applied promptly and traceably?
Software Update
08

Keep secrets out of Git

A password in a repository stays in its history forever, even if it is deleted later.

  • Distribute credentials from a password vault into files or secrets; the repository holds only the reference.
  • Run a secret scanner as a pre-commit hook or in the pipeline.
  • Anything that leaked gets rotated. Deleting it is not enough.
Self-check: Do credentials never sit in code or Git, and do you rotate them after a leak?
Credential ScrubbingCredential Rotation
09

Least privilege for every service

When a service is taken over, its privileges decide the damage.

  • Containers not as root, with no-new-privileges and read-only where possible.
  • Mount the Docker socket only where it is unavoidable — it equals root on the host.
  • Change default passwords; disable unused admin accounts and remote access.
Self-check: Do services run with least privilege, without unnecessary admin or remote access?
User Account PermissionsDisable Remote Access

Detect

D3FEND tactic
10

Collect and evaluate sign-ins centrally

An attack almost always starts with sign-in attempts. Having logs but never looking at them means not noticing.

  • Ship the logs of every service to one place.
  • Alert on bursts of failures, new devices or sign-ins at unusual times.
  • Alerts to your phone — but only the important ones. Too many alerts get ignored.
Self-check: Are sign-ins collected centrally, with anomalies reported?
Authentication Event ThresholdingUser Behavior Analysis
11

Make silent failures audible

The most dangerous backup is the one that has been failing silently for weeks. Every important job reports its success actively; if the report is missing, an alert fires.

  • A "dead man’s switch": a push monitor with an expected interval.
  • Monitoring for reachability, certificate expiry, disk space.
  • Test the alert path itself: does the message really arrive?
Self-check: Does your monitoring report outages and silent failures on its own?
Platform MonitoringApplication Performance Monitoring
12

Notice unexpected changes

Whoever takes over a server changes files: start-up scripts, scheduled tasks, keys. A checksum over the critical files makes that visible.

  • Hash critical files regularly and compare against a reference.
  • Keep the reference outside the monitored system.
  • Explain every deviation instead of clicking it away.
Self-check: Would you notice if a system file, start-up script or scheduled task changed unexpectedly?
File Integrity MonitoringFile Hashing

Isolate

D3FEND tactic
13

Separate networks, limit outbound traffic

A compromised service should not be able to talk to everything — and should not be able to open an arbitrary channel back to the internet.

  • Attach containers only to the networks they need; databases on an internal network.
  • IoT devices in a VLAN of their own.
  • Restrict outbound traffic per service to what it needs. Tedious, but effective.
Self-check: Are networks separated (internal, IoT, public) and is outbound traffic restricted?
Network IsolationOutbound Traffic Filtering
14

Filter at the edge — carefully

Rate limits and reputation lists keep scanners and brute-force attempts away before an app sees them. A badly placed filter can lock you out, though.

  • Introduce it first where a false positive costs nothing.
  • Never in front of the path you would use to fix a mistake.
  • A DNS filter on the home network blocks known malicious domains for every device.
Self-check: Are scanners, known attacker IPs and malicious domains filtered at the edge?
IP Reputation AnalysisDNS Denylisting

Evict

D3FEND tactic
15

Write the emergency down beforehand

In an incident there is no calm for thinking. A short runbook says what to do in which order.

  • Lock an account and end all sessions — how, and in which menu, on your setup?
  • Which credentials must be renewed if service X was taken over?
  • Have an emergency access path that does not depend on the system that just failed.
Self-check: Can you lock an account immediately, end sessions and revoke credentials?
Account LockingSession TerminationCredential Revocation

Restore

D3FEND tactic
16

3-2-1 backups — and rehearse the restore

Three copies on two media, one off-site, encrypted. But a backup only counts once a restore has worked.

  • At least once a year, restore one service completely onto empty hardware.
  • Do not keep the backup password only in the vault that is itself inside the backup.
  • Set up the off-site copy so an attacker cannot delete it.
Self-check: Are there encrypted backups with an off-site copy?
Self-check: Have you rehearsed a complete restore, including issuing new credentials?
Restore ObjectRestore DatabaseRestore Configuration

Check from the outside

Free public tools show what a stranger sees of your site: Mozilla Observatory and securityheaders.com check the headers, SSL Labs the TLS configuration. Only test systems you own.

D3FEND cube →