ArcLibrary

Server & Container Hardening

Turn defaults into 'survives a hostile environment' — simple but unskippable basics.

SecurityHardeningContainers
核心 · Key Idea

In one line: 80 % of breaches come from default configs + weak passwords + missing patches. This is the minimum security checklist for every production server and container — not advanced offensive/defensive work; just don't fail at easy stuff.

Server minimum checklist#

  1. SSH pubkey-only
    Disable PasswordAuthentication, ban root login, change port if you wish.
  2. Auto security updates
    unattended-upgrades / dnf-automatic — at least security patches.
  3. Minimal firewall
    Default-deny inbound; allow only what's needed (22 / 80 / 443). ufw / nftables / cloud SG.
  4. fail2ban
    Ban brute-force IPs (SSH / nginx).
  5. Dedicated service users
    No root for services; add systemd sandbox fields.
  6. Centralized logs + alerts
    Even if the host is tampered, external evidence remains.
  7. Backups + drills
    See the previous article.

Container minimum checklist#

# Dockerfile
USER 1000
COPY --chown=1000:1000 app /app
# K8s securityContext
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]
  seccompProfile: { type: RuntimeDefault }

Pair with:

  • Image scanning (Trivy / Grype): CI blocks high-severity CVEs.
  • Signing + SBOM (cosign + syft): reject untrusted images.
  • NetworkPolicy: default deny-all, allowlist explicitly.
  • Resource limits: CPU/Mem/PID caps so one Pod can't take the node down.
  • PSA / Kyverno / OPA Gatekeeper (PSP replacements): policy enforcement.

Analogy#

打个比方 · Analogy

A default server install is a new house with no locks and no security — burglars are the default outcome. This checklist is a lock + camera + gas alarm + fire extinguisher.

Key concepts#

Least privilegeLeast Privilege
Processes / users / IAM roles get exactly what they need — nothing more.
Defense in depthDefense in Depth
Network + host + app + monitoring layers — **no single failure is fatal**.
Zero TrustZero Trust
Don't trust the internal network. Verify identity + policy on every access.
Secrets hygieneSecrets Hygiene
No hardcoding, regular rotation, short-lived credentials.
WAFWeb Application Firewall
Cloudflare / nginx + ModSecurity — blocks SQL injection / XSS.

Practical notes#

  • Never expose DB / Redis to the public internet — private subnet + SG + strong passwords.
  • Disable password login > strong password — weak-password dictionaries are attack #1.
  • Inside containers: read-only root filesystem + non-root user + minimal capabilities.
  • K8s: enable audit log — sensitive operations (exec / port-forward) have a paper trail.
  • Don't put secrets in git — CI uses env vars; runtime uses Vault / SOPS / cloud KMS / external-secrets.
  • Dependency manifest + auto-scan: dependabot / renovate + trivy image scan.
  • Drills: simulate "this host is compromised" periodically — verify IAM / firewall / app layers detect and contain in time.
  • Retain logs 90+ days — for forensic analysis.

Common mistakes#

  • chmod 777 to solve problems — equivalent to removing the lock.
  • sudo NOPASSWD ALL in production — one phished engineer = whole cluster compromised.
  • Service binds 0.0.0.0 but no firewall — add the firewall or bind 127.0.0.1 + reverse proxy.
  • Mounting Docker socket into a container — escape = host root.
  • Default ServiceAccount auto-mounted in K8s — set automountServiceAccountToken: false.
  • CI runner executes public PR code — code injection grabs internal secrets.

Easy confusions#

Availability
Whether the service runs well.
Measured by SLA / SLO.
Security
Whether **adversaries** can break it.
Few observable metrics — relies on **process + drills**.

Further reading#