SafeServerSetup
All case studies · Sample engagement · representative numbers

Hardened an AWS Lightsail box for a Django consultancy before client handover

They build Django apps for a living and still wanted a second pair of eyes.

Customer
Django consultancy
Team size
3 engineers
Provider
AWS Lightsail
OS
Ubuntu 24.04
Plan · Duration
Pro · 26 hours
Engagement summary

A three-person consultancy migrating a client's Django app from a shared host to AWS Lightsail. They wanted hardening done by someone other than the team that built the app, before handing the box over to a non-technical client who would own it long-term.

Why they came to us

Their selling point with the client was "we handle the boring stuff." They could absolutely have done this themselves — but the client was paying for an audit report from someone who hadn't written the code, and that report needed to be on company letterhead other than theirs.

Audit findings

What we found on the box.

First pass before changing anything. Severity ranges from critical (act immediately) to low (worth knowing).

  • Django DEBUG = True in production settings

    critical
  • SECRET_KEY committed to a config repo with broader access than intended

    critical
  • gunicorn running as root

    high
  • PostgreSQL listening on 0.0.0.0 (Lightsail edge blocked it, but no defense in depth)

    high
  • Lightsail firewall allowed all from 0.0.0.0/0 on the app port

    medium
  • No log rotation; logs at 4.2GB on a 40GB disk

    medium
Hardening applied

What we changed, in order.

Each change is reversible and documented in the handover doc. Commands shown are illustrative.

  1. 1

    Set DEBUG = False; enabled Django security middleware (HSTS, SECURE_SSL_REDIRECT, secure cookies, SameSite=Lax).

  2. 2

    Rotated SECRET_KEY and moved configuration to a systemd EnvironmentFile with restricted permissions.

  3. 3

    Re-ran gunicorn under systemd as a dedicated app user.

  4. 4

    Bound PostgreSQL to 127.0.0.1, switched authentication to scram-sha-256.

  5. 5

    NGINX in front of gunicorn with rate-limiting on /login and /admin.

  6. 6

    UFW + Lightsail firewall: only the custom SSH port, 80, and 443 reachable.

  7. 7

    logrotate configured for application, access, and error logs.

  8. 8

    Set up CloudWatch shipping for application logs so the client could see them post-handover.

Before / after

The numbers that moved.

Representative figures from this engagement. Real, named-customer studies will publish actual numbers with a link to verify.

<code>DEBUG</code> exposed in prod
Before
yes
After
no
PostgreSQL bind address
Before
0.0.0.0
After
127.0.0.1
Process running as root
Before
yes
After
no
SSL Labs rating
Before
B
After
A+
Disk free
Before
38%
After
76%
Ready to be the next one

Hand us your VPS, get an engagement like this one.

Pick a plan, send the credentials through the encrypted form, and we'll come back with the same kind of audit + hardening + handover the studies above describe.