Deployment guide

Databasus 3.66.0

Overview

This guide covers launching and using Databasus 3.66.0 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened Adminer & Database Admin and Backup Tools AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other tools in the listing are described on the listing's guide hub.

Databasus (formerly Postgresus) is a self-hosted backup tool with a web interface. It backs up PostgreSQL, MySQL, MariaDB and MongoDB.

You add each database once, choose where its backups go (a directory on this instance or an S3 bucket, among others), and set a schedule and a retention policy. Databasus runs the dumps, keeps the history, restores a backup on request and tells you when something fails.

What you get:

  • Your own administrator, no open sign-up. On its first boot each instance creates one Databasus administrator with a random password before the web server starts. The image contains no account, no password and no setup token, and open sign-up is closed: you add other people from the Users page.
  • Per-instance secrets. Databasus's master key (/databasus-data/secret.key) signs sign-in sessions and encrypts every database password, storage key and notifier credential Databasus stores, and the backups you choose to encrypt. Each instance generates its own key on first boot, together with its own password for Databasus's PostgreSQL metadata database. The service refuses to start with a missing, short or malformed key.
  • HTTPS from the first boot. nginx serves Databasus on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS. Requests for a host name the instance does not serve get no answer.
  • Everything else on localhost. Databasus's own PostgreSQL 17 listens on 127.0.0.1:5437 only with scram-sha-256 passwords. Databasus itself listens on port 4005, and a firewall table on the instance drops every connection to that port that does not come from nginx on the instance itself.
  • Protection from other web sites acting with your login. nginx refuses a backup, restore, connection test or download that another web site's page sends in your browser, refuses any form post whose browser Origin is not this instance, and rate-limits sign-in and sign-up attempts per address. Databasus records the real client address of each request.
  • No access to the instance metadata service. Databasus and every pg_dump, mysqldump, mariadb-dump, mongodump and webhook it starts, PostgreSQL and nginx are blocked at the kernel level from the EC2 instance metadata service (IPv4 and IPv6) and from the special-purpose address ranges no database or bucket uses (multicast, reserved, benchmarking and IETF protocol ranges). Private addresses in your own VPC stay reachable, so Databasus can back up RDS and EC2 databases there. This also means Databasus cannot use the instance's IAM role: S3 storages use an access key and secret key (Step 7).
  • MySQL and MariaDB clients that never hand over local files. A database server can ask its client to upload a local file (LOAD DATA LOCAL INFILE). On this image the MySQL and MariaDB clients Databasus runs refuse every such request, so a database you add cannot read Databasus's key, settings or backups through them.
  • Built from source, checked. Databasus 3.66.0 is built from its release source (checksum pinned) with Go 1.27.3 and current versions of its libraries, with no known reachable vulnerabilities at build time. The service runs as the unprivileged databasus user with no Linux capabilities. There is no compiler on the image.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Databasus 3.66.0 (/opt/databasus), PostgreSQL 17 for Databasus's own data, the client tools Databasus runs (PostgreSQL 12 to 18, MySQL 8.0, 8.4, 9.7 and 26.10, MariaDB 12.3 and 13.0, MongoDB Database Tools 100.20.1), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair, and a VPC subnet that can reach the databases you want to back up (and your S3 endpoint, if you use one).
  • A security group that allows TCP 22 (SSH), TCP 443 (Databasus) and TCP 80 (redirects to HTTPS) from the networks your administrators work from. Databasus needs no other inbound port.
  • On each database server, a security group rule that lets this instance connect, and a database user that can read everything you want in the backup.
1

Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Databasus 3.66.0 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, the subnet and a security group as above. A smaller instance also works for a few small databases.

Local backups are written to the root volume. Size the volume for the backups you plan to keep there, or send them to S3.

With the AWS CLI (replace the values in angle brackets):

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=50,VolumeType=gp3}' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=databasus}]'
2

Connect to your instance

Connect over SSH as the default login user for your AMI. For Databasus 3.66.0 on Ubuntu 24.04, the login user is ubuntu:

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

Check the services

First boot sets the host name, generates the certificate, creates this instance's PostgreSQL cluster, master key and Databasus administrator, and then starts Databasus and nginx:

systemctl is-active databasus-firstboot databasus postgresql@17-main nginx databasus-port-guard
sudo test -f /var/lib/sac/data/databasus-firstboot.done && echo FIRSTBOOT_DONE

All five units are active and the first boot marker is present:

active active active active active FIRSTBOOT_DONE

Only SSH and nginx are reachable from the network. Databasus's PostgreSQL listens on localhost only. Databasus itself always binds port 4005 on every address; the databasus-port-guard firewall table drops any connection to it that does not arrive on the loopback interface, so only nginx on this instance reaches it:

sudo ss -lntpH | awk '{print $4, $6}' | sed -E 's/users:\(\("([^"]+)".*/\1/' | grep -v '127.0.0.5' | sort -u
*:4005 databasus 0.0.0.0:22 sshd 0.0.0.0:443 nginx 0.0.0.0:80 nginx 127.0.0.1:5437 postgres [::]:22 sshd [::]:443 nginx [::]:80 nginx

A health check for a load balancer or uptime monitor answers without signing in:

curl -sk https://127.0.0.1/healthz
ok
4

Get your URL and password

sudo cat /var/lib/sac/data/databasus-credentials.txt

The file is readable by root only and holds the URL and the administrator's email and password for this instance:

# Databasus 3.66.0 - generated on first boot by databasus-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. DATABASUS_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ DATABASUS_ADMIN_EMAIL=admin@databasus.local DATABASUS_ADMIN_PASSWORD=<DATABASUS_ADMIN_PASSWORD>
#
# Open DATABASUS_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to # https) and sign in with DATABASUS_ADMIN_EMAIL / DATABASUS_ADMIN_PASSWORD. Change the e-mail and password from your # profile after the first sign-in. Open sign-up is CLOSED: add people from the Users page (Settings). # Databasus's master key /databasus-data/secret.key (it signs sign-in sessions and encrypts every stored database,
# storage and notifier credential, and backups you choose to encrypt), its PostgreSQL 17 metadata database
# (127.0.0.1:5437) and that database's password (/etc/databasus/databasus.env, root only) are unique to this instance. # BACK UP secret.key: without it the stored credentials and encrypted backups cannot be read. # Local backups go to /databasus-data/backups (0700). Instance metadata is blocked for Databasus: S3 storages use # access keys, not the instance role. # Self-test:
sudo databasus-selftest Change the served name:
sudo databasus-set-hostname <your-domain>
# Forgot the password:
sudo databasus-reset-password Administrators:
sudo databasus-admin --list-admins
# User guide: https://secureanycloud.com/stacks/databasus-3-66-0/

The URL uses the instance's public DNS name from EC2 instance metadata. Opening https://<public-ip>/ sends you on to that name.

The image includes a self test. Through nginx it signs in as the administrator and checks the API, the closed sign-up, the request guards, Databasus's privileges, the port guard, the localhost database and the metadata block:

sudo databasus-selftest
SELFTEST-OK https 301 + healthz + health HEALTHY + version 3.66.0 + UI + anonymous 401 + exactly 1 user admin@databasus.local ADMIN + sign-up closed (403) + sign-in COMPLETED + wrong password refused (401) + 403 cross-site test + 403 cross-origin POST + 444 unknown host + databasus uid databasus, no capabilities, :4005 loopback-only (private 000, nobody 000) + PostgreSQL 127.0.0.1:5437 only + metadata 000 inside databasus, nginx and PostgreSQL (control 200) + secret guard OK
5

Sign in

Open the URL from the credentials file. Your browser warns about the self-signed certificate the first time. Accept it for this host (Step 11 replaces it with your own). Sign in with the administrator email and password.

Change the administrator's email address and password from your profile after your first sign-in. To give colleagues access, add them from the Users page under Settings. Nobody can create an account on their own.

6

Add a database

Databasus groups databases, storages and notifiers into workspaces. Create a workspace, then choose Add database, pick the engine and enter the host, port, user, password and database name. Choose Test connection to check the details before you save. The password is encrypted with your instance's master key before it is stored.

The image carries the client tools for every server version Databasus supports, and Databasus picks the matching one for each database:

  • PostgreSQL (server versions 12, 13, 14, 15, 16, 17, 18): pg_dump, pg_restore, psql 12 to 18 (PGDG packages, kept patched by apt); pg_basebackup, pg_receivewal, pg_combinebackup 17 and 18
  • MySQL (server versions 8.0, 8.4, 9.x, 26.x): mysql and mysqldump 8.0.46, 8.4.13, 9.7.4, 26.10.0
  • MariaDB (server versions 10.2 to 13.0): mariadb and mariadb-dump 12.3.3 (servers 10.2 to 12.x) and 13.0.2 (13.x)
  • MongoDB (the versions MongoDB Database Tools 100.20.1 supports): mongodump, mongorestore 100.20.1 (kept patched by apt)

MySQL 5.7 and MariaDB 5.5 and 10.1 servers are not supported on this image, because there are no Ubuntu 24.04 client builds for them.

Confirm the installed client versions:

T=/opt/databasus/assets/tools/x64 for v in 12 13 14 15 16 17 18; do $T/postgresql/postgresql-$v/bin/pg_dump --version; done for v in 8.0 8.4 9 26; do $T/mysql/mysql-$v/bin/mysqldump --version; done $T/mongodb/bin/mongodump --version | head -1
pg_dump (PostgreSQL) 12.22 (Ubuntu 12.22-3.pgdg24.04+1) pg_dump (PostgreSQL) 13.23 (Ubuntu 13.23-1.pgdg24.04+1) pg_dump (PostgreSQL) 14.24 (Ubuntu 14.24-1.pgdg24.04+2) pg_dump (PostgreSQL) 15.19 (Ubuntu 15.19-1.pgdg24.04+2) pg_dump (PostgreSQL) 16.15 (Ubuntu 16.15-1.pgdg24.04+2) pg_dump (PostgreSQL) 17.11 (Ubuntu 17.11-1.pgdg24.04+2) pg_dump (PostgreSQL) 18.6 (Ubuntu 18.6-1.pgdg24.04+2) mysqldump Ver 8.0.46 for Linux on x86_64 (MySQL Community Server - GPL) mysqldump Ver 8.4.13 for Linux on x86_64 (MySQL Community Server - GPL) mysqldump Ver 9.7.4 for Linux on x86_64 (MySQL Community Server - GPL) mysqldump Ver 26.10.0 for Linux on x86_64 (MySQL Community Server - GPL) mongodump version: 100.20.1

For an Amazon RDS or Aurora database, use its endpoint as the host. In the database's security group, allow this instance's security group on the database port.

Give Databasus a database user that can read every table you want in the backup. A table it cannot read makes the dump fail, and Databasus records that run as failed with the error.

7

Choose where backups go

Local. A Local storage writes into /databasus-data/backups on this instance, which only the databasus service user can open:

sudo stat -c '%a %U:%G %n' /databasus-data /databasus-data/backups
700 databasus:databasus /databasus-data 700 databasus:databasus /databasus-data/backups

Local backups share the root volume. Give the instance a larger volume at launch, or use S3 so that losing the instance does not also lose its backups.

S3. Add an S3 storage with the bucket, its region, the endpoint (https://s3.<region>.amazonaws.com for Amazon S3; S3-compatible stores work too), an access key and a secret key. Both keys are encrypted with your instance's master key before they are stored.

Databasus on this image cannot use the instance's IAM role. The instance metadata service, where the role's temporary credentials come from, is blocked for Databasus, so a database host or webhook URL entered in the interface can never be used to read it. Create an IAM user (or access key) for Databasus that can reach only its own bucket, for example:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::<your-bucket>" }, { "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"], "Resource": "arn:aws:s3:::<your-bucket>/*" } ] }

Rotate that key in IAM like any other long-lived credential, and update it in the storage's settings when you do.

8

Schedule backups and encrypt them

Open the database's backup settings. Choose the storage, the schedule and how long to keep backups, and set Encryption to Encrypted.

Encrypted backups are written with a key derived from this instance's master key, so a copy of the bucket or the backup directory is unreadable on its own. Each backup is stored with a small .metadata file next to it that records its encryption salt and IV. These values are not secret without the master key.

Choose Make backup right now to run a backup immediately. The backup list shows each run with its status, size and duration. From the list you can download a backup (Databasus decrypts it for the download) or restore it.

A backup is only as good as the master key that decrypts it. See Step 10.

9

Restore and notifications

Open a successful backup and choose Restore to restore it into the same database or another one you have added. Restore into an empty database, so existing objects do not clash. Databasus refuses to restore a backup into an older server version than the one it came from.

Notifiers tell you when a backup fails or succeeds. Databasus supports email, Slack, Telegram, Discord, Microsoft Teams, Mattermost and webhooks. For email, set the SMTP settings in /etc/databasus/databasus.env, then run sudo systemctl restart databasus.

10

Back up the master key

/databasus-data/secret.key holds this instance's master key (64 hexadecimal characters). It decrypts every database password, storage key and notifier credential that Databasus has stored, and every encrypted backup. Without it, those backups cannot be restored, and you would have to enter every database and storage again. Only the service user can read it:

sudo stat -c '%a %U:%G %n' /databasus-data/secret.key /etc/databasus/databasus.env
sudo grep -oE '^[A-Z_]+=' /etc/databasus/databasus.env
600 databasus:databasus /databasus-data/secret.key 640 root:databasus /etc/databasus/databasus.env ENV_MODE= DATABASE_DSN= IS_DISABLE_ANONYMOUS_TELEMETRY= APP_VERSION= DATABASUS_URL= LOG_LEVEL=

DATABASE_DSN holds the password of Databasus's own PostgreSQL database, which listens on localhost only. Before you rely on the instance, copy the master key into the place your team keeps secrets, for example AWS Secrets Manager or a password manager. To print the key, run sudo cat /databasus-data/secret.key in your own session.

To protect Databasus's own settings and history as well, back up its database, the key and the environment file together:

sudo -u postgres pg_dump -p 5437 -Fc databasus > /root/databasus-db.dump
sudo cp -p /databasus-data/secret.key /root/databasus-secret.key.backup
sudo cp -p /etc/databasus/databasus.env /root/databasus.env.backup
11

Use your own domain and certificate

  • In your DNS, point <your-domain> (an A record) at the instance's public IP address. An Elastic IP keeps that address stable.
  • Tell the instance to use it. This sets the name nginx accepts and its request guards, sets the URL Databasus uses in emails, and generates a new self-signed certificate for it:
sudo databasus-set-hostname <your-domain>
  • For a certificate your browser trusts, put the certificate chain for <your-domain> in /etc/ssl/databasus/databasus.crt and its private key in /etc/ssl/databasus/databasus.key (root only, mode 600), and run sudo systemctl reload nginx. Alternatively, put the instance behind an Application Load Balancer with an AWS Certificate Manager certificate that forwards to port 443 on the instance.
12

Security checks

Databasus, PostgreSQL and nginx are blocked from the instance metadata service:

for u in nginx databasus postgresql@17-main; do printf '%s ' "$u"; systemctl show -p IPAddressDeny --value "$u" | tr ' ' '\n' | sort | tr '\n' ' '; echo; done
nginx 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 databasus 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 postgresql@17-main 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128

The block applies to the whole service, so every dump, restore and webhook request that Databasus starts is blocked too. A database registered at 169.254.169.254 fails its connection test, and a webhook to that address is never delivered. The same applies to the special-purpose ranges in the list (192.0.0.0/24, 198.18.0.0/15, multicast 224.0.0.0/4 and reserved 240.0.0.0/4).

Private addresses in your own VPC are deliberately not blocked: Databasus has to reach them to back up an Amazon RDS, Aurora or EC2 database in the same VPC. Your security groups and each database's own access rules decide what it can reach there, so allow this instance only to the databases it should back up. IPv6 egress is unchanged, for databases and S3 endpoints you reach over IPv6.

Databasus runs as databasus with no Linux capabilities and cannot gain any:

P=$(systemctl show -p MainPID --value databasus) ps -o user= -p "$P" grep -E '^(CapEff|CapBnd|CapAmb|NoNewPrivs)' /proc/"$P"/status
databasus CapEff: 0000000000000000 CapBnd: 0000000000000000 CapAmb: 0000000000000000 NoNewPrivs: 1

Databasus's PostgreSQL accepts only the databasus role, from localhost, with a password, plus the postgres superuser over the local socket for root's maintenance:

sudo -u postgres psql -p 5437 -w -tA -c "SELECT type, database, user_name, address, auth_method FROM pg_hba_file_rules ORDER BY rule_number"
local|{all}|{postgres}||peer host|{databasus}|{databasus}|127.0.0.1|scram-sha-256

The MySQL and MariaDB clients Databasus runs are small root-owned wrappers around the real programs. Each one turns LOCAL INFILE off (mysql and mariadb; the dump tools never answer such a request), and starts the real client with a clean environment and an empty home directory, so neither Databasus's settings nor a .my.cnf in its data directory reach it:

tail -1 /opt/databasus/assets/tools/x64/mysql/mysql-8.4/bin/mysql
exec /usr/bin/env -i PATH=/usr/bin:/bin HOME=/opt/databasus/assets/tools/x64/.client-home LC_ALL=C.UTF-8 LANG=C.UTF-8 /opt/databasus/assets/tools/x64/mysql/mysql-8.4/libexec/mysql "${pre[@]}" --local-infile=0 "$@"

Signed-out callers are refused, sign-up is closed, nginx refuses a connection test that another web site's page sends and a sign-in posted from a foreign Origin, and a request for a host name the instance does not serve gets no answer at all:

H=$(sudo sed -n 's#^DATABASUS_URL=https://\([^/]*\)/$#\1#p' /var/lib/sac/data/databasus-credentials.txt)
curl -sk -o /dev/null -w 'signed-out workspaces: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/api/v1/workspaces"
curl -sk -o /dev/null -w 'sign-up: %{http_code}\n' --resolve "$H:443:127.0.0.1" -X POST -H 'Sec-Fetch-Site: same-origin' -H "Origin: https://$H" -H 'Content-Type: application/json' --data '{"email":"someone@example.com","password":"Sac-Probe-1","name":"Someone"}' "https://$H/api/v1/users"
curl -sk -o /dev/null -w 'cross-site connection test: %{http_code}\n' --resolve "$H:443:127.0.0.1" -X POST -H 'Sec-Fetch-Site: cross-site' "https://$H/api/v1/database-tests"
curl -sk -o /dev/null -w 'cross-origin sign-in: %{http_code}\n' --resolve "$H:443:127.0.0.1" -X POST -H 'Origin: https://evil.example' "https://$H/api/v1/sessions"
curl -sk -o /dev/null -w 'unknown host name: %{http_code}\n' --resolve evil.example:443:127.0.0.1 https://evil.example/ || true
signed-out workspaces: 401 sign-up: 403 cross-site connection test: 403 cross-origin sign-in: 403 unknown host name: 000

The credentials, the TLS key, the environment file, the master key and the backups are readable by root (and the last three by the databasus service user) only:

sudo stat -c '%a %U:%G %n' /var/lib/sac/data/databasus-credentials.txt /etc/ssl/databasus/databasus.key /etc/databasus/databasus.env /databasus-data/secret.key /databasus-data/backups
600 root:root /var/lib/sac/data/databasus-credentials.txt 600 root:root /etc/ssl/databasus/databasus.key 640 root:databasus /etc/databasus/databasus.env 600 databasus:databasus /databasus-data/secret.key 700 databasus:databasus /databasus-data/backups

Other notes:

  • Sign-in limits. nginx allows about 10 sign-in attempts and 10 sign-up attempts a minute per address and answers more with 429. It uses the address that connected to nginx, and it replaces any forwarding headers a client sends.
  • Who can reach it. An administrator can read every registered database through its backups. Open ports 80 and 443 in the security group only to the networks your administrators work from.
  • The build. /usr/share/doc/sac-databasus/BUILD-INFO.txt records the release, its checksums, the toolchain and the library versions. The *.go-version-m.txt files next to it list every library in each program.
  • Logs. nginx logs are in /var/log/nginx. Databasus logs to the journal (journalctl -u databasus), including each request with its client address.
13

Keep it up to date

Ubuntu security updates, the PostgreSQL client tools and the MongoDB tools install automatically. To apply all updates now:

sudo apt-get update && sudo apt-get upgrade -y

New Databasus releases arrive as new versions of this listing, built and checked the same way. Read the Databasus release notes before you move to one.

To move to a new version, back up Databasus's database, secret.key and /etc/databasus/databasus.env (Step 10). Then launch the new version, restore all three and restart databasus.

Troubleshooting

The page does not load. Check that first boot finished: until it has created the master key and the administrator, Databasus and nginx stay stopped on purpose.

systemctl is-active databasus-firstboot
sudo journalctl -u databasus-firstboot --no-pager -n 20 -o cat | tail -5

Databasus does not start. Its start-up guard says why in the journal (sudo journalctl -u databasus -b), for example a master key that was emptied or changed.

A backup failed. The error is shown on the backup. The usual causes are a security group or database access rule that does not let this instance in, a wrong password, TLS settings the server does not accept, or a user that cannot read a table.

Forgot the administrator password. Run sudo databasus-reset-password. The command sets a new random password for the administrator and writes it to the credentials file:

sudo databasus-reset-password

Support and licensing

Databasus is free software under the Apache License 2.0 (the Databasus authors). The license and the project's NOTICE are in /usr/share/doc/sac-databasus/.

The MySQL client programs are under the GPL version 2 with the Universal FOSS Exception, and the MariaDB client programs are under the GPL version 2. Their copyright files and a written offer of their source code are in /usr/share/doc/sac-databasus/third-party/. The Go libraries are under permissive licenses (MIT, BSD, Apache 2.0, MPL 2.0). PostgreSQL is under the PostgreSQL license, MongoDB Database Tools under the Apache License 2.0 and nginx under the BSD license.

There is no per-user license fee. The AMI price covers SecureAnyCloud's build, hardening, first-boot setup and support. SecureAnyCloud is not affiliated with or endorsed by the Databasus project.

  • Email: sales@secureanycloud.com
  • Website: https://secureanycloud.com
  • Support: 24/7, with a 24 hour response SLA

The other versions on this listing are on the database admin and backup tools guide.

Deploy on AWS

Launch Databasus 3.66.0 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