Deployment guide

Timesketch

Overview

Timesketch is Google's open-source platform for collaborative forensic timeline analysis. Investigators load timelines from evidence into a shared sketch, then search, filter and pivot across millions of combined events at once. They record findings on the timeline itself with tags, stars, comments and annotations. Saved views capture a line of enquiry so it can be handed over, and stories turn a sequence of events into a written narrative with the underlying evidence still attached.

This SecureAnyCloud image ships the free and open-source, Apache-2.0 licensed Timesketch on Ubuntu 24.04 on Azure. It is deployed the officially supported way, as the upstream container stack, and everything is captured into the VM, so your instance starts in minutes rather than after an afternoon of orchestration.

Because this platform holds evidence, nothing ships with a known secret. The administrator account, the database password, the Flask signing key and the task queue password are generated for each VM on first boot, before the application is reachable. The search cluster, database and task queue are bound to the internal container network only and are never reachable from the internet.

What you get:

  • Timesketch (Apache-2.0), pinned to the upstream release the image was built from
  • The Timesketch web application and the Celery ingest worker, which processes plaso, CSV and JSONL timelines
  • OpenSearch as the event search cluster, sized automatically from the VM's memory
  • PostgreSQL for sketches, timelines, annotations and access control
  • Redis as the task queue broker, password-protected per instance
  • nginx as the single public front door on port 80
  • A per-instance administrator account, generated on first boot
  • 24/7 SecureAnyCloud support

Timesketch, OpenSearch, PostgreSQL and Redis are trademarks of their respective owners. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by any of them. It ships the free and open-source, Apache-2.0 licensed, self-hosted software.

The one change from the upstream stack is that OpenSearch's Security Analytics plugin and its bundled Sigma rule set are not included. Timesketch does not use that plugin. You load the Sigma rules you want yourself (Step 14).

Prerequisites

  • An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
  • A subscription to the Timesketch listing on the Azure Marketplace

Recommended virtual machine size: Standard_B4ms (4 vCPU, 16 GB RAM). Upstream Timesketch documents a minimum of 8 GB RAM, and OpenSearch is given half the VM's memory as its heap. 16 GB is therefore a comfortable working size for real casework. For large plaso ingests or several concurrent analysts, use Standard_D8s_v5 or larger.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the web interface from the networks your analysts use.

1

Deploy from the Azure Portal

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Timesketch by SecureAnyCloud, and select Create.

On the Basics tab, 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 HTTP (80).

Then select Review + create and Create.

2

Deploy from the Azure CLI

Create the resource group, network, security rules and VM from a gallery image.

RG="timesketch-prod"; LOCATION="eastus"; VM_NAME="timesketch-01" GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-sac/providers/Microsoft.Compute/galleries/sacGallery/images/timesketch-ubuntu-24-04/versions/<version>" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name ts-vnet --address-prefix 10.100.0.0/16 --subnet-name ts-subnet --subnet-prefix 10.100.1.0/24 az network nsg create -g "$RG" --name ts-nsg az network nsg rule create -g "$RG" --nsg-name ts-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name ts-nsg --name allow-http --priority 110 \
  --destination-port-ranges 80 --access Allow --protocol Tcp az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
  --size Standard_B4ms --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name ts-vnet --subnet ts-subnet --nsg ts-nsg --public-ip-sku Standard
3

Connect to your VM

Connect over SSH as azureuser.

ssh azureuser@<vm-ip>
4

Confirm the services are running

The platform runs as six containers under one timesketch.service. On the very first boot, timesketch-firstboot.service generates this VM's secrets and only then releases the application to start. Allow a few minutes after launch before the web interface answers.

sudo systemctl is-active docker timesketch
sudo docker compose --project-directory /opt/timesketch ps

Both services report active, and all six containers report running. Only nginx publishes a port to the host. OpenSearch, PostgreSQL and Redis have no host port mapping at all and are reachable solely on the internal container network.

5

Read the per-instance credentials

The administrator account, the PostgreSQL password, the Flask signing key and the Redis password were all generated for this VM on its first boot, before the application was reachable. They are written to a root-only file. List and read it:

sudo ls -l /root/timesketch-credentials.txt
sudo cat /root/timesketch-credentials.txt

The file (mode 0600 root:root) holds TIMESKETCH_URL, TIMESKETCH_USERNAME and TIMESKETCH_PASSWORD. None of these values ship in the image.

The image contains no database, no search index and no configured secret at all. The live configuration is deleted at build time and rebuilt from secret-free templates on first boot. No two instances share a credential, and there is no default login to change.

6

Verify the security model

Because Timesketch holds evidence, the most important property of this image is that the search cluster is not reachable from outside the VM. Upstream runs OpenSearch with its security plugin disabled, which is safe only because the port is never published.

Confirm this for yourself. List every listening socket, then try to reach OpenSearch on the VM's own routable address.

sudo ss -ltnp | awk '{printf "%-24s %s\n", $4, $6}'
HOST_IP=$(hostname -I | awk '{print $1}') timeout 5 bash -c "</dev/tcp/$HOST_IP/80" && echo "port 80 (web interface): reachable" || echo "port 80: unreachable" timeout 5 bash -c "</dev/tcp/$HOST_IP/9200" && echo "port 9200 (OpenSearch): REACHABLE - unexpected" || echo "port 9200 (OpenSearch): refused, as intended" timeout 5 bash -c "</dev/tcp/$HOST_IP/5432" && echo "port 5432 (PostgreSQL): REACHABLE - unexpected" || echo "port 5432 (PostgreSQL): refused, as intended"

Only 22 (SSH) and 80 (the web interface) are bound to a routable address. OpenSearch, PostgreSQL and Redis refuse connections because they are published to no host port at all.

The reachable port 80 result is the control that proves the test itself works. A probe that could not connect to anything would otherwise "prove" every port closed.

OpenSearch is running and healthy, but it is reachable only from sibling containers. Confirm both facts, and confirm that Redis rejects an unauthenticated command:

sudo docker compose --project-directory /opt/timesketch exec -T nginx wget -qO- http://opensearch:9200/_cluster/health
sudo docker compose --project-directory /opt/timesketch exec -T redis redis-cli ping 2>&1 | head -1

The cluster reports a green or yellow status from inside the container network. Redis answers NOAUTH Authentication required, because this VM's task queue password is required.

7

Sign in to the web interface

Browse to http://<vm-ip>/ to reach Timesketch. Sign in with the TIMESKETCH_USERNAME and TIMESKETCH_PASSWORD from Step 5.

8

Create a sketch

A sketch is the shared workspace for an investigation. It holds one or more timelines plus every annotation your team makes on them.

From the landing page, choose to create a new sketch and give it a name that identifies the case.

9

Ingest a timeline

Timesketch accepts plaso storage files (the output of log2timeline) and CSV or JSONL timelines.

A CSV needs at minimum a datetime, a timestamp_desc and a message column. Any further columns, such as hostname, become searchable fields in their own right.

Upload the file into the sketch. The ingest worker indexes it in the background.

10

Explore and search events

Open the timeline to explore it. Search across every ingested event with free text, or query a specific field such as hostname:WIN-FORENSIC-01. Filter results by time range, star, tag and comment on events, and save a search worth keeping as a view.

You can also confirm an ingest from the command line. This command creates a sketch, uploads a small timeline and reads the events back:

sudo /usr/local/sbin/timesketch-selftest.sh
11

Managing the service

Check the service status, restart it, or read the ingest worker log:

sudo systemctl status timesketch --no-pager sudo systemctl restart timesketch
sudo docker compose --project-directory /opt/timesketch logs --tail=50 timesketch-worker

The whole stack is managed as a single unit. timesketch.service brings the containers up and down together. If a timeline does not appear after upload, check the ingest worker's log.

12

How OpenSearch is sized

OpenSearch is given half of the VM's memory as its JVM heap, following upstream's own sizing rule. The value is calculated on first boot from the machine you actually launched and is not fixed when the image is built.

A Standard_B4ms gives OpenSearch an 8 GB heap. A larger VM gives it proportionally more, capped at 31 GB. To see what this instance chose, run:

sudo grep -E 'OPENSEARCH_MEM_USE_GB|NUM_WSGI_WORKERS' /opt/timesketch/config.env
sudo docker inspect opensearch --format '{{range .Config.Env}}{{println .}}{{end}}' | grep JAVA_OPTS free -g | head -2

The configuration file is 0600 root:root because it carries this VM's database and task queue passwords, so these reads need sudo. The reported OPENSEARCH_MEM_USE_GB and the JVM's -Xms/-Xmx agree with each other and with half the memory shown by free.

If you resize the VM later and want the heap recalculated to match, regenerate the configuration and restart:

sudo /usr/local/sbin/timesketch-gen-env.sh
sudo systemctl restart timesketch
13

Add a user

Timesketch accounts are managed with tsctl. Add a colleague to this instance:

sudo docker compose --project-directory /opt/timesketch exec -T timesketch-web tsctl create-user analyst2

You are prompted for a password. Sketches are access-controlled, so a new user sees only the sketches shared with them. Share a sketch from its Sharing menu in the web interface.

14

Add Sigma rules

Timesketch can tag events that match Sigma detection rules. This image ships with no Sigma rules loaded, so you choose the rule set that fits your casework.

Rules are kept in Timesketch's own database. The folder /opt/timesketch/etc/timesketch/sigma/rules on the VM appears inside the web container as /etc/timesketch/sigma/rules. This is the easiest place to stage rules for import.

To import the Linux rules from the public SigmaHQ repository, run:

curl -fsSL https://github.com/SigmaHQ/sigma/archive/refs/heads/master.tar.gz \
  | sudo tar -xz -C /opt/timesketch/etc/timesketch/sigma/rules --strip-components=2 sigma-master/rules/linux
sudo grep -rlE '\|(cidr|expand|fieldref)' /opt/timesketch/etc/timesketch/sigma/rules | sudo xargs -r rm -f sudo docker compose --project-directory /opt/timesketch exec -T timesketch-web tsctl import-sigma-rules /etc/timesketch/sigma/rules/
sudo docker compose --project-directory /opt/timesketch exec -T timesketch-web tsctl list-sigma-rules | head

The grep line removes rules that use Sigma modifiers Timesketch cannot translate. One such rule would otherwise stop the import part way through. Swap rules/linux for rules/windows, rules/network or your own rule folder as needed.

You can also create and edit individual rules in the web interface under Studio, Sigma rules. Once rules are loaded, run the Sigma analyzer on a timeline to tag the matching events.

15

Use your own domain and HTTPS (production)

The image serves plain HTTP on port 80. That suits a private network but is not appropriate for evidence crossing an untrusted one. Before you upload real case data, put Timesketch behind TLS.

Upstream documents the supported approach at timesketch.org/guides/admin/https. In short, point a DNS record at the VM, obtain a certificate, and add a TLS server block to /opt/timesketch/etc/nginx.conf listening on 443. Restart with sudo systemctl restart timesketch, and restrict port 80 in your NSG once 443 is serving.

16

Security recommendations

  • Put TLS in front of it before ingesting real evidence (Step 15). Timesketch serves plain HTTP by default.
  • Restrict port 80/443 in your NSG to the networks your analysts work from. Do not expose this service to the public internet.
  • Change the first-boot administrator password after your first sign-in, from the user menu.
  • Keep OpenSearch unpublished. It runs with its security plugin disabled, so publishing port 9200 would expose every ingested event without authentication. Step 6 shows how to verify that it is not published.
  • Take disk snapshots of the VM. Sketches, annotations and the search index all live on the OS disk.
  • Give each analyst their own account (Step 13) so annotations are attributed.
17

Support and Licensing

Timesketch is free and open-source software licensed under the Apache License 2.0. This SecureAnyCloud image bundles it unmodified, with 24/7 SecureAnyCloud support for the image and its deployment. For questions about Timesketch itself, see the upstream documentation and GitHub project.

Deploy on Azure

Find Timesketch on Ubuntu 24.04 LTS on the Azure Marketplace and deploy it in minutes with 24/7 SecureAnyCloud support.

Deploy on Azure

Launch Timesketch on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure