Security Azure

Ghostwriter on Ubuntu 24.04 on Azure User Guide

| Product: Ghostwriter on Ubuntu 24.04 LTS on Azure

Overview

This image runs Ghostwriter 7.2.3, the open source engagement and project management platform from SpecterOps, on Ubuntu 24.04 LTS. Ghostwriter gives offensive security and red teams one place to plan assessments, track clients and projects, check infrastructure in and out, maintain a reusable library of findings, and generate consistent Word and PowerPoint reports.

The application runs as its official upstream Docker Compose production stack, managed by the official ghostwriter-cli tool under systemd. Seven containers make up the stack: an nginx TLS front door on ports 80 and 443, a Django application server, a PostgreSQL database, Redis, a background queue worker, a Hasura GraphQL engine, and a real-time collaboration server. The web console, the GraphQL API and the collaboration service are all served behind the single nginx front door over HTTPS.

What is included:

  • Ghostwriter 7.2.3 (official upstream production images, pinned), run by systemd via ghostwriter-cli
  • The web console over HTTPS on port 443, with a self-signed certificate out of the box
  • A unique administrator password and all application secrets generated on first boot, recorded in a root-only file
  • docker.service and ghostwriter.service as systemd units, enabled and active
  • A 4 GB swap file so the multi-container stack has headroom on smaller VM sizes
  • The base fully patched with unattended security upgrades enabled
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up for heavier use. NSG inbound: allow 22/tcp from your management network and 443/tcp for the web console. Ghostwriter serves a self-signed certificate on port 443; for production, front it with your own domain and trusted TLS certificate (see the final step).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Ghostwriter by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTPS (443). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name ghostwriter \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name ghostwriter --port 443 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

On first boot the image runs a one-time initialization that generates this VM's secrets and admin password and brings the stack up. Give it a couple of minutes on first boot, then confirm Docker and the Ghostwriter stack are active and all seven containers are running:

sudo systemctl is-active docker ghostwriter
sudo docker ps --format '{{.Names}}  {{.State}}'

docker and the ghostwriter systemd unit active, with the seven-container production compose stack (nginx, django, postgres, redis, queue, graphql_engine and collab-server) all running

Step 5 - Retrieve your per-VM administrator password

Ghostwriter ships with no baked-in credential. On the first boot of every instance a unique administrator password and all application secrets are generated and written to a root-only file. Read it to get your sign-in details:

sudo cat /root/ghostwriter-credentials.txt

The per-VM Ghostwriter credentials file with the console URL, the admin username and the administrator password (redacted), root only and mode 0600

Step 6 - Confirm the web console

Check that nginx is serving the sign-in page over HTTPS on port 443 (the certificate is self-signed, so -k skips verification):

curl -ks -o /dev/null -w 'sign-in page: HTTP %{http_code}\n' https://127.0.0.1/accounts/login/

A 200 confirms the console is up. The image also verifies on first boot that the generated administrator password signs in and that a wrong password is rejected.

The Ghostwriter sign-in page returning HTTP 200, a wrong password rejected and the per-VM administrator password logging in with a redirect to the dashboard

Step 7 - Sign in to the web console

Open https://<vm-public-ip>/ in your browser. The certificate is self-signed, so your browser will warn once; accept it to continue (replace it with your own trusted certificate for production). Sign in as admin with the password from Step 5.

The Ghostwriter sign-in page

Step 8 - The dashboard

After signing in you land on your personal dashboard: a calendar of your scheduled work and a quickstart panel that walks you through managing clients and projects, building the findings library and generating reports.

The Ghostwriter dashboard showing the calendar and the quickstart panel for a signed-in user

Step 9 - Add a client and track engagements

From the sidebar open Clients and choose Create Client to register an organization you are assessing. Each client holds its projects, points of contact and infrastructure, so a whole engagement history lives in one place.

The Ghostwriter clients list showing a registered client with its short name, codename and project count

Step 10 - The findings library

Open Findings to browse and build your reusable findings library. Findings you write once - with severity, description, replication steps and remediation - can be added to any report, so your deliverables stay consistent across engagements.

The Ghostwriter findings library, where reusable findings are created and added to reports

Step 11 - Production hardening

For production use:

  • Use your own domain and TLS certificate. Replace the self-signed certificate under the Ghostwriter data directory with your own, and point DNS at the VM. Restrict DJANGO_ALLOWED_HOSTS to your hostname with sudo -i; cd /opt/ghostwriter; ./ghostwriter-cli config set DJANGO_ALLOWED_HOSTS "your.hostname" and set DJANGO_CSRF_TRUSTED_ORIGINS to https://your.hostname, then ./ghostwriter-cli containers up.
  • Restrict the NSG. Allow port 443 only from the networks that need it, and SSH only from your management network.
  • Change the admin password after first sign-in and add named user accounts for your team.
  • Back up with sudo /opt/ghostwriter/ghostwriter-cli backup, which dumps the PostgreSQL database and media files.

Maintenance

The stack starts automatically on boot. To manage it, use the CLI in /opt/ghostwriter (run as root):

sudo HOME=/root /opt/ghostwriter/ghostwriter-cli healthcheck

To stop or start the whole stack, use sudo systemctl stop ghostwriter and sudo systemctl start ghostwriter. Security updates for the base OS are applied automatically by unattended-upgrades.

Support

Every cloudimg image includes 24/7 support. Contact us at support@cloudimg.co.uk with the deployment guide name and your Azure region, and we will help you get up and running.