Skip to content

Commit a580b4f

Browse files
author
Marius Benthin
committed
refactor: base image
1 parent 9a7e276 commit a580b4f

8 files changed

Lines changed: 126 additions & 93 deletions

File tree

.github/workflows/build.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Build and Publish Base Image
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- ghcr-io #TODO: remove branch after testing
8+
workflow_dispatch:
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME: ${{ github.repository }}
13+
14+
jobs:
15+
build-and-push:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
packages: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Log in to GitHub Container Registry
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ${{ env.REGISTRY }}
29+
username: ${{ github.actor }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Extract metadata
33+
id: meta
34+
uses: docker/metadata-action@v5
35+
with:
36+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
37+
tags: |
38+
type=raw,value=latest,enable={{is_default_branch}}
39+
type=sha,prefix=sha-
40+
41+
- name: Build and push image
42+
uses: docker/build-push-action@v6
43+
with:
44+
context: .
45+
file: Containerfile
46+
push: true
47+
tags: ${{ steps.meta.outputs.tags }}
48+
labels: ${{ steps.meta.outputs.labels }}

Containerfile

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@ LABEL maintainer="Marius Benthin <marius.benthin@nextron-systems.com>"
44
# install dependencies
55
RUN apk add --no-cache wget unzip
66

7-
# pass contract token via --build-args
8-
ARG CONTRACT_TOKEN
9-
RUN test -n "$CONTRACT_TOKEN" || (echo "CONTRACT_TOKEN is required!" && false)
10-
117
# specify environment variables
128
ENV TEMP_DIR="/tmp/thunderstorm"
139
ENV TARGET_DIR="/opt/nextron/thunderstorm"
1410
ENV UPLOAD_DIR="$TEMP_DIR/uploads"
15-
ENV SIGNATURE_UPDATE_INTERVAL=24
1611

1712
# create directories and user
1813
RUN mkdir -p "$TEMP_DIR" "$TARGET_DIR" "$UPLOAD_DIR" && \
@@ -23,19 +18,6 @@ RUN mkdir -p "$TEMP_DIR" "$TARGET_DIR" "$UPLOAD_DIR" && \
2318
COPY entrypoint.sh /entrypoint.sh
2419
RUN chmod +x /entrypoint.sh
2520

26-
# copy custom THOR config
27-
COPY custom-thor.yml /opt/nextron/thunderstorm/config/custom-thor.yml
28-
2921
USER thunderstorm
3022

31-
# download and extract Thor
32-
RUN wget -O "$TEMP_DIR/thor.zip" "https://portal.nextron-systems.com/api/voucher/download/$CONTRACT_TOKEN/thor/linux"
33-
RUN unzip -o -q "$TEMP_DIR/thor.zip" -d "$TARGET_DIR"
34-
35-
# cleanup
36-
RUN rm "$TEMP_DIR/thor.zip"
37-
38-
# copy custom THOR config
39-
COPY custom-thor.yml "$TARGET_DIR/config/custom-thor.yml"
40-
4123
ENTRYPOINT ["/entrypoint.sh"]

README.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,70 +2,53 @@
22

33
Many companies rely on the containerization of services to increase economic and technical efficiency. Customers which use containerization need to create images that make the services available as containers. In this guide, we provide you with the necessary requirements and templates to run Thunderstorm as a container.
44

5-
## Containerize Thunderstorm
5+
## Quick Start
66

7-
Thunderstorm is a web service which allows you to scan files with our compromise assessment tool THOR through a Web-API. By sane defaults, the web service listens to `127.0.0.1` on port `8000` only. However, if we want the Thunderstorm API to be accessible from anywhere, we need to adjust the binding address via command line parameter `--host`.
7+
Thunderstorm is a web service which allows you to scan files with our compromise assessment tool THOR through a Web-API. A ready-to-use base image is published to the GitHub Container Registry and only requires your contract token to run.
88

9-
We created an `entrypoint.sh` which accepts optional environment variables from a Containerfile and deployment configuration. First, the shell script updates the THOR signatures to download all detection rules published after the image was created. Subsequently, the Thunderstorm executable is started which will run infinitely until the container is stopped.
10-
11-
### Build Container Image
12-
13-
The Thunderstorm binary is not publicly available and requires a non-host-based license from our portal. Therefore, we cannot provide a ready-to-use image. However, you can use the following Containerfile in combination with your contract token to build your personal Thunderstorm image.
14-
15-
1. Clone the repository
9+
1. Download the `docker-compose.yml` from this repository
1610

1711
```
18-
git clone https://github.com/NextronSystems/thunderstorm-deployment.git
12+
curl -O https://raw.githubusercontent.com/NextronSystems/thunderstorm-deployment/master/docker-compose.yml
1913
```
2014

21-
2. Change to repository directory
15+
2. Start the service with your contract token
2216

2317
```
24-
cd thunderstorm-deployment/
18+
CONTRACT_TOKEN=<CONTRACT_TOKEN> docker compose up -d
2519
```
2620

27-
3. Build image where `<TAG>` could be the Thunderstorm version and `<CONTRACT_TOKEN>` is the contract token of your non-host-based Thunderstorm license.
21+
On first start, Thunderstorm downloads the THOR binaries using your `CONTRACT_TOKEN` (your non-host-based Thunderstorm license) and persists them in a Docker volume so subsequent restarts are instant. THOR signatures are updated automatically on every start and periodically while running.
2822

29-
```
30-
docker build -f Containerfile -t thunderstorm:<TAG> --build-arg CONTRACT_TOKEN=<CONTRACT_TOKEN> .
31-
```
32-
33-
4. Push image to your container registry
34-
35-
```
36-
docker tag thunderstorm:<TAG> registry.internal/thunderstorm/thunderstorm:<TAG>
37-
docker push registry.internal/thunderstorm/thunderstorm:<TAG>
38-
```
23+
The `docker-compose.yml` contains commented environment variables for all available configuration options such as TLS, port, queue size, and signature update interval.
3924

4025
## Signature Updates
4126

42-
By default, Thunderstorm tries to download new THOR signatures every 24 hours while running. You should keep in mind that the THOR signature release cycle may differ, so there is not always a new package available. The signature update interval can be modified on an hourly basis by specifying the environment variable `SIGNATURE_UPDATE_INTERVAL` in the `Containerfile` or `docker-compose.yml`.
27+
By default, Thunderstorm tries to download new THOR signatures every 24 hours while running. You should keep in mind that the THOR signature release cycle may differ, so there is not always a new package available. The signature update interval can be modified on an hourly basis by specifying the environment variable `SIGNATURE_UPDATE_INTERVAL` in the `docker-compose.yml`.
4328

4429
### Rolling Deployment
4530

4631
If you are running a single Thunderstorm instance, you may want to use a Rolling Deployment to prevent a downtime of your Thunderstorm service. A Rolling Deployment spawns a new container and stops the old one after ensuring that the new one is healthy and ready to accept requests. The configuration differs between container management systems such as Kubernetes, Docker or Docker Swarm.
4732

48-
For Docker we recommend `start-first` as value for `deploy.update_config.order`. A docker-compose template can be found under `ochestration/docker/docker-compose.yml`.
33+
For Docker we recommend `start-first` as value for `deploy.update_config.order`, as configured in the `docker-compose.yml` at the repository root.
4934

5035
### Multiple Replicas
5136

5237
If you want to deploy multiple Thunderstorm instances, we recommend to distribute the requests equally using a load-balancer such as [Traefik](https://traefik.io/traefik) or [Nginx](https://nginx.org).
5338

54-
We created a docker-compose template for a Docker Swarm setup with Traefik under `ochestration/docker-swarm/docker-compose.yml`.
39+
## Passing Additional Arguments
5540

56-
## Remote Logging
41+
Any argument supported by Thunderstorm or THOR can be passed via the `THUNDERSTORM_ARGS` and `THOR_ARGS` environment variables in `docker-compose.yml`. This means new parameters released in future versions are available immediately without any changes to the image or entrypoint.
5742

58-
Thunderstorm is able to pass custom parameters to the THOR executable. By default, the respective Container Image disables the generation of JSON reports with `--no-json` because the reports will be deleted after the container stops (unless a persistence volume is used). However, you usually want to log the scan results to a remote SIEM system such as [Splunk](https://www.splunk.com) or [Elastic](https://www.elastic.co). Therefore, you may want to specify your remote logging systems inside the `custom-thor.yml` template file.
43+
For example, to forward scan results to a remote SIEM:
5944

6045
```yaml
61-
# Send scan output to a remote server
62-
remote-log:
63-
- splunk.intern:514:DEFAULT:TCP
64-
- elastic.intern:1514:JSON:TCP
46+
environment:
47+
THOR_ARGS: "--remote-log splunk.intern:514:DEFAULT:TCP --remote-log elastic.intern:1514:JSON:TCP"
6548
```
6649
6750
## Security
6851
6952
The communication between a client and the Thunderstorm service could involve sensitive files. Therefore, we highly recommend to encrypt the traffic using TLS by mounting the certificate and private key via the built-in secrets functionality of Docker or Kubernetes into the container. In addition, you need to specify the file path to the TLS certificate and private key in the environment variables `TLS_CERT` and `TLS_KEY`.
7053

71-
Out of the box, Thunderstorm API is unauthenticated and does not support authentication providers at the moment. If you require an authentication layer, we suggest to use a proxy middleware which delegates the authentication to an external provider such as [Microsoft Entra ID](https://www.microsoft.com/de-de/security/business/identity-access/microsoft-entra-id).
54+
Out of the box, Thunderstorm API is unauthenticated and does not support authentication providers at the moment. If you require an authentication layer, we suggest to use a proxy middleware which delegates the authentication to an external provider such as [Microsoft Entra ID](https://www.microsoft.com/de-de/security/business/identity-access/microsoft-entra-id).

custom-thor.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

docker-compose.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
version: '3.8'
2+
3+
services:
4+
thunderstorm:
5+
image: ghcr.io/nextronsystems/thunderstorm-deployment:latest
6+
ports:
7+
- "${PORT:-8000}:${PORT:-8000}"
8+
environment:
9+
# Required: your non-host-based Thunderstorm contract token
10+
CONTRACT_TOKEN: "${CONTRACT_TOKEN}"
11+
# Optional: bind address (default: 0.0.0.0)
12+
# HOST: "0.0.0.0"
13+
# Optional: service port (default: 8000)
14+
# PORT: "8000"
15+
# Optional: hours between signature updates (default: 24)
16+
# SIGNATURE_UPDATE_INTERVAL: "24"
17+
# Optional: TLS certificate and private key paths (mounted via secrets)
18+
# TLS_CERT: "/run/secrets/tls_cert"
19+
# TLS_KEY: "/run/secrets/tls_key"
20+
# Optional: persistent upload queue location
21+
# QUEUE_STORAGE: "/data/persisted-uploads"
22+
# Optional: upload queue size warning threshold (default: 50000)
23+
# QUEUE_WARN_SIZE: "50000"
24+
# Optional: result cache size (default: 250000)
25+
# RESULT_CACHE_SIZE: "250000"
26+
# Optional: minimum score for storing samples (default: 200)
27+
# STORE_SAMPLES_SCORE: "200"
28+
# Optional: additional Thunderstorm arguments (e.g. "--new-param value")
29+
# THUNDERSTORM_ARGS: ""
30+
# Optional: additional THOR arguments (e.g. "--remote-log splunk.intern:514:DEFAULT:TCP")
31+
# THOR_ARGS: ""
32+
volumes:
33+
# Persist Thor binaries and signatures across restarts
34+
- thor-data:/opt/nextron/thunderstorm
35+
deploy:
36+
replicas: 1
37+
update_config:
38+
order: start-first
39+
restart_policy:
40+
condition: on-failure
41+
42+
volumes:
43+
thor-data:

entrypoint.sh

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
#!/bin/sh
22

3+
# download Thor if not already present
4+
if [ ! -f "$TARGET_DIR/thor-util" ]; then
5+
if [ -z "$CONTRACT_TOKEN" ]; then
6+
echo "CONTRACT_TOKEN is required to download Thor!" >&2
7+
exit 1
8+
fi
9+
wget -O "$TEMP_DIR/thor.zip" "https://portal.nextron-systems.com/api/voucher/download/$CONTRACT_TOKEN/thor/linux" && \
10+
unzip -o -q "$TEMP_DIR/thor.zip" -d "$TARGET_DIR" && \
11+
rm "$TEMP_DIR/thor.zip"
12+
fi
13+
314
# update THOR signatures
415
"$TARGET_DIR/thor-util" update
516

6-
# build optional TLS and VFS arguments
7-
EXTRA_ARGS=""
8-
[ -n "$TLS_CERT" ] && EXTRA_ARGS="$EXTRA_ARGS --cert $TLS_CERT"
9-
[ -n "$TLS_KEY" ] && EXTRA_ARGS="$EXTRA_ARGS --key $TLS_KEY"
10-
[ -n "$VFS_DIR" ] && EXTRA_ARGS="$EXTRA_ARGS --vfs-dir $VFS_DIR"
17+
# append optional TLS and VFS arguments to THUNDERSTORM_ARGS
18+
[ -n "$TLS_CERT" ] && THUNDERSTORM_ARGS="$THUNDERSTORM_ARGS --cert $TLS_CERT"
19+
[ -n "$TLS_KEY" ] && THUNDERSTORM_ARGS="$THUNDERSTORM_ARGS --key $TLS_KEY"
20+
[ -n "$VFS_DIR" ] && THUNDERSTORM_ARGS="$THUNDERSTORM_ARGS --vfs-dir $VFS_DIR"
1121

1222
# run Thunderstorm service
23+
# use THUNDERSTORM_ARGS and THOR_ARGS to pass any additional arguments to either binary
1324
exec "$TARGET_DIR/tools/thunderstorm" \
1425
"--host" "${HOST:-0.0.0.0}" \
1526
"--port" "${PORT:-8000}" \
@@ -19,8 +30,8 @@ exec "$TARGET_DIR/tools/thunderstorm" \
1930
"--store-samples-score" "${STORE_SAMPLES_SCORE:-200}" \
2031
"--thor-location" "${THOR_LOCATION:-$TARGET_DIR}" \
2132
"--upload-dir" "$UPLOAD_DIR" \
22-
"--signature-update-interval" "$SIGNATURE_UPDATE_INTERVAL" \
23-
$EXTRA_ARGS \
33+
"--signature-update-interval" "${SIGNATURE_UPDATE_INTERVAL:24}" \
34+
$THUNDERSTORM_ARGS \
2435
"--" \
2536
"--no-json" \
26-
"--template" "$TARGET_DIR/config/custom-thor.yml"
37+
$THOR_ARGS

ochestration/docker-swarm/docker-compose.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

ochestration/docker/docker-compose.yml

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)