B3
Analytics AWS

Blazer 3.5.2 on AWS User Guide

| Product: Blazer 3.5.2 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Blazer 3.5.2 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg BI and web analytics listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Blazer is an open source business intelligence tool by Andrew Kane. You explore your data with SQL, turn queries into line, column, bar, pie and map charts, collect them on dashboards, use variables in queries, and save checks that flag when a query returns rows. It connects to PostgreSQL, MySQL, Amazon Athena, BigQuery, Trino, Elasticsearch, OpenSearch, Salesforce and other sources.

What the cloudimg image adds:

  • One sign in, unique to your instance. First boot creates the administrator admin with a random password. nginx asks for it (HTTP Basic authentication over HTTPS, bcrypt hash) and Blazer itself checks the same user name and password, so one browser prompt passes both and a request that bypasses nginx is still refused. There are no default or stock credentials.
  • Per instance secrets. Rails' SECRET_KEY_BASE, both database passwords, the administrator password and the TLS certificate are generated at first boot. Nothing secret is baked into the image.
  • Blazer reads data, it cannot change it. Blazer's own tables (saved queries, dashboards, checks, the audit log) live in the database blazer_meta, owned by Blazer's app role. The sample data lives in a separate database, blazer_sample, which Blazer reads through the role blazer_reader: read only transactions by default, no write privilege, a 30 second statement timeout, and no access to blazer_meta at all.
  • Rebuilt on a patched base, Blazer unmodified. The image is built on the instance from Blazer's own container packaging (ankane/blazer-docker, checked file by file at a pinned commit), on a raised and digest pinned Ruby 4.0.9 Alpine base with Alpine's security updates applied. The app loads the lockfile's fixed json 2.21.2 and net-imap 0.6.4.1 gems.
  • A locked down container. Blazer runs as its own blazer user with a read only root file system, every Linux capability dropped, no new privileges, a process limit, and our own blazer.yml mounted read only. Puma listens on 127.0.0.1 only.
  • HTTPS from the first boot. nginx serves Blazer on port 443 with a certificate generated on your instance, port 80 redirects to HTTPS, requests for a host name the instance does not serve get no answer, and a change sent from another web site is refused.
  • Metadata and private network access blocked, with an allow list you control. No service on the image can reach the instance metadata service. The blazer user cannot reach addresses inside your VPC, link local or reserved ranges, loopback services other than PostgreSQL and DNS, or any mail server. To connect Blazer to your own database, add it to a root owned allow list with one command (Step 7).
  • Nothing leaves the instance by itself. File uploads, the trend forecasting option (which sends data to an external service), Slack and Mapbox are off. Checks can be saved but this image schedules none and sends no email.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on. The AMI requires IMDSv2.

What is on the image: Blazer 3.5.2 (Rails 8.1, Puma, Ruby 4.0.9) in one local container image, Docker CE, nginx, PostgreSQL 16, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

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 (or a private route you use for management).
  • A security group that allows TCP 22 (SSH) from your admin network, and TCP 443 (Blazer) and TCP 80 (redirects to HTTPS) from the networks your analysts work from. Blazer shows query results from your databases, so keep 80 and 443 as narrow as you can.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Blazer 3.5.2 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (or larger for many users or heavy queries), your key pair and a security group as above.

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

First boot creates the databases, the administrator and the certificate, and takes about a minute after the instance is running.

Step 2: Connect to your instance

Version SSH user
Blazer 3.5.2 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot creates the PostgreSQL cluster, both databases, the administrator and the certificate; nginx and Blazer start only after it has finished. blazer-egress-guard loads the firewall rules for Blazer at every boot:

systemctl is-active nginx blazer docker postgresql@16-main blazer-egress-guard blazer-firstboot
sudo test -f /var/lib/cloudimg/blazer-firstboot.done && echo FIRSTBOOT_DONE

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

active
active
active
active
active
active
FIRSTBOOT_DONE

Only SSH and nginx can be reached from the network. Blazer (Puma, in the container) and PostgreSQL listen on the loopback address only:

sudo ss -lntp | awk 'NR>1 && $4 !~ /^127\.0\.0\.5[34]/ {split($6, p, "\""); print $4, p[2]}' | sort
0.0.0.0:22 sshd
0.0.0.0:443 nginx
0.0.0.0:80 nginx
127.0.0.1:5432 postgres
127.0.0.1:8080 ruby
[::]:22 sshd
[::]:443 nginx
[::]:80 nginx

Blazer runs as one container from the one image on the instance, which is never pulled from a registry:

sudo docker ps --format '{{.Names}}  {{.Image}}  {{.Status}}'
sudo docker inspect -f 'user={{.Config.User}} read-only={{.HostConfig.ReadonlyRootfs}} cap-drop={{.HostConfig.CapDrop}} security-opt={{.HostConfig.SecurityOpt}} network={{.HostConfig.NetworkMode}} cgroup-parent={{.HostConfig.CgroupParent}}' blazer
id blazer
blazer  964caa277f4a  Up 31 minutes
user=997:986 read-only=true cap-drop=[ALL] security-opt=[no-new-privileges] network=host cgroup-parent=blazer.slice
uid=997(blazer) gid=986(blazer) groups=986(blazer)

Step 4: Get your URL and password

sudo cat /root/blazer-credentials.txt

The file is readable by root only:

# Blazer 3.5.2 - generated on first boot by blazer-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret.

BLAZER_URL=<url>
BLAZER_ADMIN_USER=admin
BLAZER_ADMIN_PASSWORD=<redacted>
#
# Open BLAZER_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to https)
# and sign in with the user and password above (the browser's sign-in prompt).
# New admin password:      sudo blazer-set-password
# Change the served name:  sudo blazer-set-hostname <your-dns-name>
# Data sources:            /etc/blazer/blazer.yml, then sudo systemctl restart blazer
# Let Blazer reach a host: sudo blazer-egress-allow add <host-or-cidr>:<port>
# Sample data (read-only for Blazer): sudo -u postgres psql blazer_sample
# User guide: https://www.cloudimg.co.uk/guides/blazer-3-5-2-on-ubuntu-24-04-aws/

The URL uses the instance's public DNS name from the EC2 instance metadata, and the certificate also names the public and private IP addresses. nginx answers only to the names in the certificate. The name is fixed at first boot, so if you stop and start the instance without an Elastic IP and its public address changes, run sudo blazer-set-hostname with the new name (Step 9), or better, give the instance an Elastic IP or your own DNS name.

To check the sign in end to end from the instance itself (HTTPS redirect, an unknown host name refused, wrong, empty and stock passwords refused at nginx and at Blazer, and the administrator's password running a query):

sudo blazer-cred-roundtrip
OK https 301 + unknown Host refused + healthz anonymous + 401 without/wrong/empty/stock credentials (nginx and Puma) + admin home + CSRF POST ran SQL

Step 5: Sign in

Open the BLAZER_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own, Step 9). Your browser then asks for a user name and password: enter admin and the password from Step 4. There is no sign in page and no sign out link, because the browser prompt is the sign in; close the browser to sign out.

The home page lists the dashboards and saved queries. The image comes with four example queries and the Sales Overview dashboard over the sample data, so there is something to look at straight away:

The Blazer home page with the query search box, the New Query button and the list with the Sales Overview dashboard and the Orders per Month, Revenue by Status, Top Cities by Users and Weekly Signups queries

Your administrator password. To change it, or if you lose it, set a new one from the instance. It updates nginx's password file, Blazer's own check and the credentials file together, then restarts Blazer. Without an option it generates a random password; with --stdin it reads the password you type (16 to 72 letters and digits):

sudo blazer-set-password
sudo blazer-set-password --stdin

Step 6: Queries, charts and dashboards

The sample data. The data source main is the database blazer_sample with three tables: users (200 people with a city and a plan), orders (1,500 orders with a status and an amount) and events (3,000 events), with dates in the year before first boot. New Query, Schema shows the tables and columns.

Write a query. Choose New Query, type SQL, and choose Run. Blazer charts the result automatically: a time column gives a line chart, a text column with numbers gives a column chart. Choose Create to save it with a name and description:

The Blazer New Query page with a SQL query joining users and orders by plan, the Run button, and the result shown as a column chart of orders and average order value per plan above a four row table

A saved query shows its SQL, its chart and its rows, and can be edited, forked or downloaded as CSV:

The saved Orders per Month query with its description, its SQL, a line chart of orders per month over thirteen months and the first rows of the result table

Dashboards. A dashboard shows several saved queries together; New Query, New Dashboard creates one. The Sales Overview dashboard has three:

The Sales Overview dashboard with the Orders per Month line chart, the Revenue by Status column chart for processing, cancelled, shipped, refunded and completed orders, and the start of the Top Cities by Users chart

Blazer's own documentation covers variables ({start_time}), smart variables, linked columns, cohorts and the other chart types: https://github.com/ankane/blazer.

Checks. A check is a saved query that should return no rows. You can create checks and run them by hand from Checks; this image schedules no check runs and sends no email, and the blazer user cannot reach mail servers.

Step 7: Add your own data source

Blazer's data sources are defined in /etc/blazer/blazer.yml (owned by root, mounted read only into the container). Keep connection strings and passwords in /etc/blazer/blazer.env (root only, mode 0600), which Blazer reads at start. Use a database user with read only access to the data you want to query.

  1. Let Blazer reach the database. The blazer user cannot reach addresses inside your VPC until you allow them, one destination per line, with the root only helper. It takes a host name, an IPv4 address or CIDR, or an IPv6 CIDR in brackets, and a port:
sudo blazer-egress-allow add <your-db-endpoint>:5432
sudo blazer-egress-allow add <cidr>:3306
sudo blazer-egress-allow list
sudo blazer-egress-allow remove <entry>
  1. Add the connection string to /etc/blazer/blazer.env as a new line, for example for an Amazon RDS for PostgreSQL database:
WAREHOUSE_DATABASE_URL=postgres://<read-only-user>:<password>@<your-db-endpoint>:5432/<database>
  1. Add a data source that reads it to /etc/blazer/blazer.yml, under data_sources: next to main:
  warehouse:
    url: <%= ENV["WAREHOUSE_DATABASE_URL"] %>
    timeout: 30
  1. Restart Blazer, choose New Query and pick warehouse in the data source list:
sudo systemctl restart blazer

For MySQL use mysql2://...; for Amazon Athena, BigQuery and the other adapters see Blazer's documentation. Public endpoints (for example Athena or BigQuery) need no allow list entry. Blazer cannot use the instance's IAM role, because it cannot reach the metadata service, so give such a data source its own credentials with only the access it needs.

Step 8: What Blazer can connect to

nginx, Blazer's container, PostgreSQL, Docker and the first boot service are all blocked from the instance metadata service (IPAddressDeny on every unit and on blazer.slice, the control group the container runs in). As a second layer, nftables rules for the blazer user, rebuilt at every boot from your VPC's address ranges in the instance metadata, refuse every address inside your VPC, link local, reserved and multicast ranges, loopback services other than PostgreSQL (127.0.0.1:5432) and the local DNS resolver, and outbound mail (SMTP) ports. Public addresses on other ports stay reachable for public data sources.

sudo nft list chain inet cloudimg_blazer output
table inet cloudimg_blazer {
    chain output {
        type filter hook output priority filter; policy accept;
        oifname "lo" tcp dport 8080 meta skuid != { 0, 33 } counter packets N bytes N reject comment "cloudimg-app-local"
        oifname "lo" tcp dport 5432 meta skuid != { 0, 111, 997 } counter packets N bytes N reject comment "cloudimg-db-local"
        meta skuid 997 ct state established,related accept
        meta skuid 997 ip daddr { 168.63.129.16, 169.254.0.0/16 } counter packets N bytes N reject with icmp port-unreachable comment "cloudimg-metadata"
        meta skuid 997 ip6 daddr { fd00:ec2::/32, fe80::/10 } counter packets N bytes N reject with icmpv6 port-unreachable comment "cloudimg-metadata6"
        meta skuid 997 ip daddr { 224.0.0.0/4, 255.255.255.255 } counter packets N bytes N drop comment "cloudimg-multicast"
        meta skuid 997 ip6 daddr ff00::/8 counter packets N bytes N drop comment "cloudimg-multicast6"
        meta skuid 997 ip daddr { 0.0.0.0/8, 192.0.0.0/24, 198.18.0.0/15, 240.0.0.0/4 } counter packets N bytes N reject with icmp port-unreachable comment "cloudimg-reserved"
        meta skuid 997 ip daddr 127.0.0.53 udp dport 53 accept
        meta skuid 997 ip daddr 127.0.0.53 tcp dport 53 accept
        meta skuid 997 ip daddr 127.0.0.1 tcp dport 5432 accept
        meta skuid 997 ip daddr 127.0.0.0/8 counter packets N bytes N reject with icmp port-unreachable comment "cloudimg-loopback"
        meta skuid 997 ip6 daddr { ::1, ::ffff:0.0.0.0/96 } counter packets N bytes N reject with icmpv6 port-unreachable comment "cloudimg-loopback6"
        meta skuid 997 tcp dport { 25, 465, 587, 2525 } counter packets N bytes N reject comment "cloudimg-smtp"
        meta skuid 997 ip daddr . tcp dport @allow4 counter packets N bytes N accept comment "cloudimg-allow"
        meta skuid 997 ip6 daddr . tcp dport @allow6 counter packets N bytes N accept comment "cloudimg-allow6"
        meta skuid 997 ip daddr @vpc4 counter packets N bytes N reject with icmp port-unreachable comment "cloudimg-vpc"
        meta skuid 997 ip6 daddr @vpc6 counter packets N bytes N reject with icmpv6 port-unreachable comment "cloudimg-vpc6"
        meta skuid 997 ip daddr { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16 } counter packets N bytes N reject with icmp port-unreachable comment "cloudimg-private"
        meta skuid 997 meta nfproto ipv6 counter packets N bytes N reject with icmpv6 port-unreachable comment "cloudimg-ipv6"
    }
}

The allow list /etc/blazer/egress-allow is owned by root and empty when the image ships; only root can change it. The helper refuses the metadata service, link local, the Azure wire server, loopback, multicast and reserved ranges, mail ports and very broad ranges, and the firewall keeps blocking the metadata addresses even if a line naming them is written into the file by hand:

sudo blazer-egress-allow list
sudo blazer-egress-allow add 169.254.169.254:80
sudo blazer-egress-allow add 172.31.0.0/16:25
# entries in /etc/blazer/egress-allow:
(none)
# loaded (nft set elements):
blazer-egress-allow: refused '169.254.169.254:80': 169.254.169.254/32 overlaps the never-open range 169.254.0.0/16 (metadata/link-local/loopback/multicast/reserved)
blazer-egress-allow: refused '172.31.0.0/16:25': port 25 is SMTP; outbound mail is always refused

blazer-egress-guard re-reads the file at every boot and whenever the helper changes it (sudo blazer-egress-allow reload re-resolves host names, for example after an RDS failover changes an address).

Step 9: Your own DNS name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name Blazer is served as. This mints a new self signed certificate for the name, points nginx at it, updates the URL in /root/blazer-credentials.txt, and keeps the name across reboots:

sudo blazer-set-hostname <your-domain>

To use a certificate from a public or internal certificate authority instead (for example one issued by Let's Encrypt for <your-domain>), copy it over the generated pair and reload nginx (running blazer-set-hostname again replaces it with a self signed one):

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/blazer.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/blazer.key
sudo nginx -t && sudo systemctl reload nginx

Step 10: Security checks

nginx asks for the password on every path except the anonymous health check /healthz. No password, a wrong password, an empty password and stock logins are refused, plain HTTP redirects to HTTPS, a request for a name the instance does not serve gets no answer, and Puma itself refuses a request without the credentials:

H=$(sudo grep '^BLAZER_URL=' /root/blazer-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
for p in / /queries/new /dashboards/1 /.git/config; do
  curl -sk -o /dev/null -w "%{http_code}  $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p"
done
for c in admin:admin admin: blazer:blazer; do curl -sk -o /dev/null -w "$c -> %{http_code}\n" -u "$c" --resolve "$H:443:127.0.0.1" "https://$H/"; done
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/healthz"; echo
curl -s -o /dev/null -w 'http:// -> %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'unknown host name -> %{http_code}\n' --resolve "other.example:443:127.0.0.1" "https://other.example/" || true
curl -s -o /dev/null -w 'Puma without credentials -> %{http_code}\n' http://127.0.0.1:8080/
401  /
401  /queries/new
401  /dashboards/1
404  /.git/config
admin:admin -> 401
admin: -> 401
blazer:blazer -> 401
OK
http:// -> 301
unknown host name -> 000
Puma without credentials -> 401

The read only role cannot reach Blazer's own tables or change the sample data, and every new connection it makes starts read only with a statement timeout:

sudo -u postgres psql -X -qAt -d blazer_sample -c "SELECT 'blazer_reader may connect to blazer_meta: ' || has_database_privilege('blazer_reader', 'blazer_meta', 'CONNECT') UNION ALL SELECT 'blazer_reader may insert into orders: ' || has_table_privilege('blazer_reader', 'orders', 'INSERT') UNION ALL SELECT 'PUBLIC may connect to blazer_meta: ' || COALESCE((SELECT bool_or(acl LIKE '=%c%') FROM pg_database, unnest(datacl::text[]) acl WHERE datname = 'blazer_meta'), false) UNION ALL SELECT 'blazer_reader settings: ' || array_to_string(setconfig, ' ') FROM pg_db_role_setting WHERE setrole = 'blazer_reader'::regrole"
blazer_reader may connect to blazer_meta: false
blazer_reader may insert into orders: false
PUBLIC may connect to blazer_meta: false
blazer_reader settings: default_transaction_read_only=on statement_timeout=30s idle_in_transaction_session_timeout=60s

The running app loads the lockfile's fixed gems, not Ruby's older bundled copies:

sudo docker exec blazer ruby -e 'require "/app/config/environment"; require "json"; require "net/imap"; puts "Blazer #{Blazer::VERSION}, Ruby #{RUBY_VERSION}, json #{JSON::VERSION}, net-imap #{Net::IMAP::VERSION}"' 2>/dev/null | tail -1
Blazer 3.5.2, Ruby 4.0.9, json 2.21.2, net-imap 0.6.4.1

The certificate was generated on this instance and names its own addresses:

H=$(sudo grep '^BLAZER_URL=' /root/blazer-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
subject=CN = ec2-<public-ip-dashed>.compute-1.amazonaws.com, O = cloudimg
X509v3 Subject Alternative Name: 
    DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost

None of the services can reach the instance metadata service:

for u in nginx blazer docker postgresql@16-main blazer-firstboot blazer.slice; do printf '%s: ' "$u"; systemctl show "$u" -p IPAddressDeny --value | 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 
blazer: 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 
docker: 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@16-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 
blazer-firstboot: 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 
blazer.slice: 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 

Step 11: Backup, storage and maintenance

Blazer's saved queries, dashboards, checks and audit log are in the PostgreSQL database blazer_meta (/var/lib/postgresql/16/main) on the root volume, so the simplest backup is an EBS snapshot of it. For a database copy of your own while Blazer is running:

sudo -u postgres pg_dump -Fc blazer_meta > <backup-dir>/blazer-meta-$(date +%F).dump

Keep /etc/blazer/blazer.yml, /etc/blazer/blazer.env and /etc/blazer/egress-allow with the dump. Restore with pg_restore into an empty blazer_meta database owned by blazer_app while Blazer is stopped.

The container image is local to the instance and never pulled: blazer.service starts it by the image ID recorded at build time and refuses any other. New Blazer releases arrive as new versions of this listing, and support can help you move your saved queries to one. Operating system security updates install automatically; run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, Docker, Blazer and PostgreSQL restart cleanly and Blazer keeps all of its data.

sudo docker images --format '{{.Repository}}:{{.Tag}}  {{.Size}}'
stat -c '%n %U:%G %a' /etc/blazer /etc/blazer/blazer.yml /etc/blazer/egress-allow
sudo stat -c '%n %U:%G %a' /root/blazer-credentials.txt /etc/blazer/blazer.env /etc/nginx/blazer.htpasswd /etc/nginx/ssl/blazer.key
cloudimg/blazer:3.5.2  257MB
/etc/blazer root:root 755
/etc/blazer/blazer.yml root:root 644
/etc/blazer/egress-allow root:root 644
/root/blazer-credentials.txt root:root 600
/etc/blazer/blazer.env root:root 600
/etc/nginx/blazer.htpasswd root:www-data 640
/etc/nginx/ssl/blazer.key root:root 600
Component Path
Blazer container image cloudimg/blazer:3.5.2 (ID in /usr/share/cloudimg-blazer/image-id), started by blazer.service
Data sources /etc/blazer/blazer.yml (root, 0644, mounted read only)
Secrets and connection strings /etc/blazer/blazer.env (root, 0600)
Blazer's tables PostgreSQL 16 database blazer_meta (role blazer_app), 127.0.0.1:5432 only
Sample data database blazer_sample, read through blazer_reader
Sign in (bcrypt hash) /etc/nginx/blazer.htpasswd (root:www-data, 0640)
Certificate and key /etc/nginx/ssl/blazer.crt, /etc/nginx/ssl/blazer.key
Firewall rules and allow list blazer-egress-guard.service (table inet cloudimg_blazer), /etc/blazer/egress-allow
Helpers /usr/local/sbin/blazer-set-password, blazer-set-hostname, blazer-egress-allow, blazer-cred-roundtrip
Credentials /root/blazer-credentials.txt (mode 0600)
Source, licences and package lists /usr/share/doc/cloudimg-blazer/SOURCE.txt, Gemfile.lock, apk-packages.txt, LICENSE-blazer.txt

Step 12: Security recommendations

  • Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your analysts work from.
  • Use your own DNS name and a certificate your users' browsers trust (Step 9).
  • Change the administrator password (Step 5) and keep the credentials file private.
  • Connect each data source with a read only database user, and open only the destinations Blazer needs in the allow list (Step 7).
  • Copy database dumps off the instance, keep the operating system patched, and snapshot the root volume regularly.

Support and licensing

Blazer and its container packaging are open source under the MIT licence, by Andrew Kane; there is no per user licence fee. The image ships Blazer 3.5.2 unmodified, built from ankane/blazer-docker with only the base image raised, Alpine's security updates applied and one gem test fixture (a sample key from the restforce gem's own test suite) left out; /usr/share/doc/cloudimg-blazer/SOURCE.txt records the commit, the base image digest and every change. The gem set is MIT, Apache 2.0, BSD or Ruby licensed except anomaly_detection (GPL 3.0 or later), whose complete source ships in the image. The AMI price covers cloudimg's hardening, first boot setup and support.

  • Email: support@cloudimg.co.uk
  • Website: https://www.cloudimg.co.uk
  • Support: 24/7, with a 24 hour response SLA

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.