Deployment guide

Dragonfly 2.5.3

Overview

This guide shows you how to launch and use the SecureAnyCloud Dragonfly 2.5.3 on Ubuntu 24.04 AMI on Amazon EC2. The image is one software version of the SecureAnyCloud file sharing and sync listing on AWS Marketplace. You select it when you subscribe and launch.

Dragonfly is an open source peer-to-peer (P2P) distribution system for files, container images, OCI artifacts and AI models, and a graduated project of the Cloud Native Computing Foundation. Instead of every machine downloading the same large file from its origin, Dragonfly splits the file into pieces and lets machines fetch those pieces from each other, coordinated by a scheduler. This image runs a complete single-node Dragonfly deployment with these components:

  • The manager (version 2.5.3) with its web console and REST API, which holds the clusters, the schedulers, the jobs and the users.
  • The scheduler, which plans which peer fetches which piece from where.
  • A dfdaemon seed peer (client 1.5.10), which downloads from origins ("back to source"), keeps the pieces in its cache and serves them. The dfget command-line tool pulls a file through it.
  • MariaDB and Redis, the manager's database and cache.

You can pull files through the P2P cache with dfget, use the local dfdaemon proxy as a registry mirror for a container runtime on the instance, and run preheat jobs from the console to load files or images into the cache before they are needed.

What you get:

  • Closed by default. Every Dragonfly listener (the manager's REST API, console and gRPC port, the scheduler and every dfdaemon port), MariaDB and Redis listen on 127.0.0.1 only. The only network ports are SSH (22) and nginx (80 and 443). This is a single-node appliance, so no peer on another host can reach it until you open access on purpose (see "Join peers on other hosts").
  • HTTPS from the first boot. nginx serves the console on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped.
  • Two sign-ins, both unique to your instance. nginx asks for a per-instance Basic authentication credential before it shows any part of the console or its API. The console then asks for its own root account. Dragonfly normally creates root with the published password dragonfly. On this image, first boot creates root directly with a random password, so the published default never exists. Self-registration, which would give anyone a read-only account, is refused.
  • Secrets unique to your instance. The image ships with no database, no configuration, no signing key and no certificate. First boot creates the MariaDB database and its account, the Redis password, the key that signs console sessions and the TLS key, all on your instance.
  • Hardened web front. nginx removes the manager's permissive cross-origin (CORS) headers and marks its session cookie Secure and SameSite=Strict. It refuses cross-origin requests that change something and cross-site requests to the OAuth sign-in pages. It sets the client address itself, so a forged X-Forwarded-For header is ignored, keeps query strings out of its access log and rate limits the sign-in.
  • Unprivileged and fenced in. The manager, scheduler and dfdaemon run as an unprivileged dragonfly account with no Linux capabilities. Every service, including MariaDB, Redis and nginx, is blocked at the kernel level from reaching the EC2 instance metadata service. A URL given to Dragonfly (a dfget download, a proxy request or a preheat job) can therefore never fetch the instance's role credentials.
  • Built from source with current security fixes. SecureAnyCloud compiles the Dragonfly 2.5.3 manager and scheduler from the project's own release tag with the current Go toolchain and patched Go libraries. The upstream release binaries are built with an older Go release that has since received many security fixes. The web console is the project's own build, unchanged. The build is reproducible and its record is on the image.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Dragonfly manager and scheduler 2.5.3 and dfdaemon and dfget 1.5.10 (/opt/dragonfly/bin, Apache-2.0), MariaDB 10.11 and Redis 7.0 from the Ubuntu archive, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The licences, the source locations, the exact Go module list and the build record are in /usr/share/doc/sac/dragonfly/.

Default user: ubuntu; Architecture: x86_64; Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet.
  • A security group that allows TCP 22 (SSH), TCP 443 (the console) and TCP 80 (redirects to HTTPS) from your own networks only.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Select Dragonfly 2.5.3 on Ubuntu 24.04 as the software version, choose your Region, and select Launch through EC2.

Choose m5.large, your key pair, the security group described above and a subnet. The AMI has an 8 GiB root volume, and the dfdaemon piece cache lives on it (/var/lib/dragonfly/storage). Raise the root volume under Configure storage to fit the files you plan to cache.

Alternatively, launch with the AWS CLI. Replace the values in angle brackets. This command sets the root volume to 100 GiB:

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=100,VolumeType=gp3}' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=dragonfly}]'
2

Connect to your instance

Version SSH user

Dragonfly 2.5.3 on Ubuntu 24.04 ubuntu

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

On first boot, the instance creates the database, the secrets, the configuration and the console account, then starts Dragonfly and publishes the console. This takes about half a minute. Confirm that all services are active:

systemctl is-active dragonfly-firstboot mariadb redis-server dragonfly-manager dragonfly-scheduler dragonfly-dfdaemon nginx
active active active active active active active

Only SSH (22) and nginx (80, 443) listen on the network. Everything else listens on 127.0.0.1: MariaDB (3306), Redis (6379), the manager (8080 console and REST API, 65003 gRPC), the scheduler (8002) and the dfdaemon (4000 to 4005, and UDP 4006). The two port 53 entries are Ubuntu's local DNS resolver.

sudo ss -lntu | awk 'NR>1 {print $1, $5}' | sort -u
tcp 0.0.0.0:22 tcp 0.0.0.0:443 tcp 0.0.0.0:80 tcp 127.0.0.1:3306 tcp 127.0.0.1:4000 tcp 127.0.0.1:4001 tcp 127.0.0.1:4002 tcp 127.0.0.1:4003 tcp 127.0.0.1:4004 tcp 127.0.0.1:4005 tcp 127.0.0.1:6379 tcp 127.0.0.1:65003 tcp 127.0.0.1:8002 tcp 127.0.0.1:8080 tcp 127.0.0.53%lo:53 tcp 127.0.0.54:53 tcp [::]:22 tcp [::]:443 tcp [::]:80 udp 127.0.0.1:4006 ...

The manager's health endpoint needs no sign-in, and the programs report their versions:

curl -sk https://127.0.0.1/healthy; echo /opt/dragonfly/bin/manager version | grep GitVersion dfget --version
"OK" GitVersion: v2.5.3 dfget 1.5.10 (024c6e9c7, 2026-10-26)

If nginx serves nothing, first boot has not finished, or it failed. In that case nothing is published and Dragonfly does not start. Check systemctl status dragonfly-firstboot and journalctl -u dragonfly-firstboot.

4

Get your URL and passwords

sudo cat /root/dragonfly-credentials.txt

The file is readable by root only. It holds the address, the Basic authentication credential, the console sign-in and the passwords the Dragonfly services use for MariaDB and Redis:

# Dragonfly on Ubuntu 24.04 (sac AWS Marketplace image) - this instance's sign-in. ... DRAGONFLY_CONSOLE_URL=https://ec2-203-0-113-10.compute-1.amazonaws.com/ CONSOLE_BASIC_AUTH_USER=admin CONSOLE_BASIC_AUTH_PASSWORD=<CONSOLE_BASIC_AUTH_PASSWORD> MANAGER_ADMIN_USER=root MANAGER_ADMIN_PASSWORD=<MANAGER_ADMIN_PASSWORD> MANAGER_DB_USER=dragonfly MANAGER_DB_PASSWORD=... REDIS_PASSWORD=...

You can verify the whole setup from the instance itself. The helper goes through nginx and checks that the console refuses a missing or wrong Basic credential. It checks that self-registration, root/dragonfly and a wrong password are refused, and that your root password signs in. It then pulls a 6 MiB test file through the dfdaemon seed peer and compares its checksum. On success it prints DRAGONFLY_ROUNDTRIP_OK:

sudo /usr/local/sbin/dragonfly-verify.sh | tail -1
DRAGONFLY_ROUNDTRIP_OK

The certificate is self-signed until you install your own (Step 8). Before you accept it in the browser, compare its SHA-256 fingerprint with the one the browser shows:

sudo openssl x509 -in /etc/ssl/dragonfly/dragonfly.crt -noout -fingerprint -sha256
sha256 Fingerprint=3F:A1:...:7C
5

Sign in to the console

Open the DRAGONFLY_CONSOLE_URL address in your browser and accept the certificate once, after comparing the fingerprint. When the browser asks for a user name and password, enter admin and the CONSOLE_BASIC_AUTH_PASSWORD. On the console sign-in page that follows, enter root and the MANAGER_ADMIN_PASSWORD.

The sign-in page offers Create an account, but self-registration is switched off on this image and nginx refuses it. A self-registered account could read every cluster, job and audit record. Add people from the console (User) or connect an OAuth provider instead.

Change the console password now. Open the account menu at the bottom left, choose Profile, and set a password of your own (8 to 16 characters, with at least one lower case letter and one digit). nginx allows two sign-in attempts a second per address, with a short burst, so a script hammering the sign-in is slowed down with HTTP 429.

The console opens on the cluster list. The single cluster cluster-1 holds this instance's scheduler and its seed peer:

6

Pull files through the P2P cache

dfget asks the local dfdaemon to download a URL. The dfdaemon fetches the file from its origin in pieces, or from its cache, or from other peers when you run a cluster, and writes it to the output path. The following example downloads the Dragonfly licence file and checks its published checksum:

F=/tmp/dragonfly-LICENSE-$$
sudo dfget https://raw.githubusercontent.com/dragonflyoss/dragonfly/v2.5.3/LICENSE -O "$F" >/dev/null
sudo sha256sum "$F" | cut -c1-64
c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4

Keep these points in mind when you use dfget on this image:

  • The dfdaemon writes the output file as the dragonfly account (mode 0640, group dragonfly). The output directory must therefore be writable by dragonfly, for example /tmp or a directory you create and give to dragonfly.
  • Only root and members of the dragonfly group can use dfget, because the dfdaemon's socket directory is closed to everyone else. Add a user with sudo usermod -aG dragonfly <user>.
  • The origin must support HTTP range requests, which most web servers, S3 and CDNs do. dfget --help lists the object storage schemes (s3://, gs:// and others) and options such as --digest sha256:<hash>, which makes dfget verify the file's checksum.
7

Preheat and the registry mirror

Preheat loads files or container images into the cache before anyone asks for them. In the console, open Job, then Preheat, and choose Add preheat. Enter a file URL (or an image reference and its registry credentials), pick the cluster and create the job. The list shows each run:

The console marks a preheat run as finished even when its download failed, so open the run to see which peers succeeded. For automation, create a personal access token under Developer and call the open API (https://<your-host>/oapi/v1/jobs) with Authorization: Bearer <token>. The open API does not use the Basic credential.

The dfdaemon also runs an HTTP proxy on 127.0.0.1:4001. A container runtime on this instance can use it as a registry mirror (Docker Hub by default), so image layers travel through the P2P cache. Point containerd or Docker on the instance at http://127.0.0.1:4001, as described in the Dragonfly documentation. The proxy listens on localhost only, so it is not an open proxy.

8

Use your own host name and certificate

Point a DNS record at the instance. An Elastic IP keeps the address across stop and start. Then tell the instance its name. This command mints a new self-signed certificate for that name and updates the nginx host rule, the origin and cross-site guards and the address in the credentials file. It also keeps the name across reboots:

sudo dragonfly-set-hostname dragonfly.example.com

To use a certificate from a public authority instead, replace /etc/ssl/dragonfly/dragonfly.crt (full chain) and /etc/ssl/dragonfly/dragonfly.key (mode 0600, owned by root) with your own, then run sudo systemctl reload nginx. If you run dragonfly-set-hostname again later, it replaces them with a new self-signed pair.

To change the Basic authentication password, write a new hash and reload nginx. openssl asks for the new password twice:

sudo sh -c 'printf "admin:%s\n" "$(openssl passwd -6)" > /etc/nginx/dragonfly.htpasswd'
sudo chown root:www-data /etc/nginx/dragonfly.htpasswd && sudo chmod 0640 /etc/nginx/dragonfly.htpasswd
sudo systemctl reload nginx
9

Join peers on other hosts

This image is a closed single node. To let dfdaemons on other machines use it as their manager, scheduler and seed peer, make the manager's gRPC port (65003), the scheduler (8002) and the dfdaemon's upload and piece ports (4000, 4005, 4006/udp) listen on the instance's private address. Set listenIP and advertiseIP in /etc/dragonfly/manager.yaml and scheduler.yaml, and the ip fields in dfdaemon.yaml. Then open those ports in the security group.

The Dragonfly gRPC services have no authentication of their own. Open them only to the private address ranges of your own peers, never to the internet, and consider Dragonfly's mutual TLS options. The Dragonfly documentation describes multi-node deployments.

10

Check persistence and updates

Every service is enabled, so Dragonfly returns after a reboot or a stop and start. If the public address changes, the next boot re-issues the certificate and the address for the new name, unless you set your own name in Step 8. Unattended security upgrades keep the operating system, MariaDB, Redis and nginx patched:

systemctl is-enabled mariadb redis-server dragonfly-manager dragonfly-scheduler dragonfly-dfdaemon dragonfly-set-host nginx unattended-upgrades
enabled enabled enabled enabled enabled enabled enabled enabled

SecureAnyCloud builds the manager and scheduler from the 2.5.3 source, and /usr/share/doc/sac/dragonfly/BUILD-PROVENANCE.txt records how. SecureAnyCloud publishes a new version of this image for new Dragonfly releases.

To move to a newer release yourself, back up first (Step 11). Then replace the programs in /opt/dragonfly/bin with the new releases from the Dragonfly releases page and the client releases page, and restart the three dragonfly-* services. Read the release notes first, because a new manager may migrate its database.

11

Back up

The manager's state (clusters, jobs, users, tokens) is in the MariaDB database manager, and the configuration is in /etc/dragonfly. The dfdaemon cache in /var/lib/dragonfly/storage can always be rebuilt from the origins. An EBS snapshot of the root volume, or AWS Backup on the instance, captures everything. To take a database dump, run:

sudo mariadb-dump --single-transaction manager | gzip > dragonfly-manager.sql.gz

Security notes

  • No shared secret ships in the image. No password, database, configuration, signing key or TLS key exists until your instance's first boot generates them. The published root/dragonfly console login is never created.
  • Fail closed. If first boot cannot complete, nothing is published. nginx has nothing to serve, and the Dragonfly services, MariaDB and Redis do not start.
  • Dragonfly is confined. Every Dragonfly, MariaDB and Redis port listens on 127.0.0.1. The Dragonfly services run as the unprivileged dragonfly account, hold no Linux capabilities and write no core dumps. They cannot change their programs or configuration, and they cannot read the TLS key, the credentials file or the database files. Every service is blocked from the EC2 instance metadata service.
  • Every published Dragonfly advisory is fixed in 2.5.3, and each class was re-tested on this image. The manager's REST API answers nothing without the Basic credential and the console sign-in, the gRPC services cannot be reached from another host, and neither dfget, the proxy nor a preheat job can reach the metadata service.
  • Origin certificates. By upstream design, the dfdaemon does not verify the TLS certificate of the origin it downloads from, and its proxy answers HTTPS requests with a certificate it creates itself. Verify what you download with dfget --digest, or rely on container image digests, which container runtimes check.
  • Go libraries. The Go vulnerability scanner lists two advisories for the Docker daemon library (GO-2026-4883 and GO-2026-4887: an authorisation plugin bypass and a plugin privilege check in the Docker daemon). No fixed version exists. Dragonfly uses only that library's registry client helpers, never the daemon code concerned.
  • Client libraries. The Rust dfdaemon carries some library advisories with no compatible fix yet. These include the XML parser quick-xml (denial of service from a hostile XML document, which the dfdaemon parses only from object storage servers you choose and for profiling output) and moderate rustls, certificate store, DNS and time parsing issues. None of the dfdaemon's ports is reachable from outside the instance.
  • Restrict network access. Limit 22/tcp to your management network, and limit 80 and 443 to the networks that use the console.

Architecture summary

Component Detail

Manager Dragonfly manager 2.5.3 (Apache-2.0, SecureAnyCloud source build), dragonfly-manager.service, console and REST 127.0.0.1:8080, gRPC 127.0.0.1:65003, account dragonfly

Scheduler Dragonfly scheduler 2.5.3, dragonfly-scheduler.service, gRPC 127.0.0.1:8002

Seed peer dfdaemon 1.5.10, dragonfly-dfdaemon.service, 127.0.0.1:4000 to 4005 and UDP 4006, socket /run/dragonfly/dfdaemon.sock, cache /var/lib/dragonfly/storage

Database and cache MariaDB 10.11 (127.0.0.1:3306, database manager), Redis 7.0 (127.0.0.1:6379, password)

Web server nginx on 443 (HTTPS, per instance certificate in /etc/ssl/dragonfly, Basic authentication), 80 redirects to HTTPS

Configuration /etc/dragonfly/{manager,scheduler,dfdaemon}.yaml (generated at first boot, root owned, readable by dragonfly)

Logs /var/log/dragonfly/{manager,scheduler,dfdaemon}

Credentials /root/dragonfly-credentials.txt, mode 0600, root only

First boot dragonfly-firstboot.service; host name and certificate dragonfly-set-host.service (every boot)

Tools dfget, dragonfly-set-hostname, dragonfly-verify.sh

Ports 22 SSH, 80 redirect, 443 console and API

Base image Ubuntu 24.04 LTS, fully patched, unattended security upgrades enabled, IMDSv2 required

Support

SecureAnyCloud images come with 24/7 support. Email sales@secureanycloud.com with your AWS account ID and the instance ID. For questions about Dragonfly itself, see the Dragonfly documentation and the Dragonfly project on GitHub.

Dragonfly is a Cloud Native Computing Foundation project. SecureAnyCloud is not affiliated with or endorsed by the Dragonfly project or the CNCF.

Deploy on AWS

Launch Dragonfly 2.5.3 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS