Sirius Scan
Overview
Sirius Scan is an open source, general-purpose vulnerability scanner. Point it at a host or an address range and it discovers what is there. It identifies the operating systems and services it finds and matches them against a CVE-backed vulnerability database.
It presents the result as a risk picture you can work through: severity across your estate, a per-host inventory of open ports and detected software, and per-finding detail with scoring and remediation guidance. Everything the console does is also available over a documented REST API, so you can schedule vulnerability assessment and wire it into an existing security workflow rather than run it by hand.
The SecureAnyCloud image runs the complete Sirius Scan v1.1.0 release stack on one virtual machine. The stack contains the Next.js web console, the Go REST API, the Go scan engine with a bundled Nmap 7.95, a PostgreSQL database for findings, a message broker that carries scan jobs to the engine, and a cache that tracks live scan progress. Every container is pinned to the exact published v1.1.0 release build by immutable digest, so the image is reproducible and cannot drift onto a moving tag.
The upstream project publishes a working sample value for every shared secret in the stack. This image therefore generates its own on the first boot of each machine: the console administrator password, the database password, the session signing key and the internal service API key. None of them is baked into the image, the database ships empty with no administrator, and the running services actively refuse each published default.
What you get:
- Sirius Scan v1.1.0, every component pinned by immutable digest to the published release build
- The web console on
:80behind nginx, with a per-VM administrator account - The REST API on
:9001, authenticated with a per-VMX-API-Key, plus an unauthenticated readiness probe for load balancer health checks - The scan engine with a bundled Nmap 7.95 and the
NET_RAWcapability it needs for host discovery - The agent gRPC listener on
:50051for remote scanning agents - PostgreSQL 15 holding hosts, ports, software inventory and vulnerability findings
- A message broker carrying scan jobs to the engine, and a Valkey cache holding scan state, templates and live progress, both confined to a private container network with no host port
- A per-VM administrator password, database password, session signing key and internal service API key, generated on first boot and never shared between machines
docker.service,sirius-scan.serviceandnginx.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Prerequisites
- An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region.
- Standard_B2s (2 vCPU / 4 GiB RAM) is the recommended size and runs the whole stack comfortably.
- NSG inbound rules that allow
22/tcpfrom your management network and80/tcpfor the web console. - Also allow
9001/tcpif you intend to use the REST API or the console's system monitoring panels from a browser. - Allow
50051/tcponly if you deploy remote scanning agents.
Sirius Scan is an active scanner. It sends real probe traffic to whatever you point it at, so scan only systems you own or have explicit written authorisation to test.
Microsoft does not require pre-approval to run penetration tests against your own Azure resources, but the Microsoft Cloud Unified Penetration Testing Rules of Engagement still apply. Scanning anything outside your own estate may breach your provider's terms or the law in your jurisdiction.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Sirius Scan by SecureAnyCloud, and select Create.
On Basics, 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 choose Review + create and Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:sirius-scan:default:latest
az vm create \
--resource-group <your-rg> \
--name sirius-scan \
--image sac1647283583153:sirius-scan:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name sirius-scan --port 80 --priority 1001
az vm open-port --resource-group <your-rg> --name sirius-scan --port 9001 --priority 1002Find the public address of the machine you just created:
az vm show --resource-group <your-rg> --name sirius-scan -d --query publicIps -o tsvStep 3 - Confirm the stack is running
SSH to the VM as azureuser. On the very first boot, the appliance generates its own secrets and starts the stack. This takes a little under two minutes, and every boot after that is immediate. Check the three systemd units first:
systemctl is-active docker sirius-scan nginxExpected output:
active active activeThen check the containers themselves. sirius-compose is a small wrapper that runs docker compose against this appliance's compose file with the per-VM environment already wired in, so you never have to remember the paths:
sudo sirius-compose ps --format 'table {{.Service}}\t{{.Status}}'Expected output:
SERVICE STATUS sirius-api Up 9 minutes (healthy) sirius-engine Up 9 minutes (healthy) sirius-postgres Up 9 minutes (healthy) sirius-rabbitmq Up 9 minutes (healthy) sirius-ui Up 9 minutes (healthy) sirius-valkey Up 9 minutes (healthy)The seventh service, sirius-migrate, is a one-shot schema migrator. It applies the core database schema and exits before the API and the engine are allowed to start. It is therefore correct for it not to appear in the running list.
Step 4 - Retrieve the per-VM credentials
Every secret this appliance uses was generated for your machine alone on its first boot. It is written to a file that only root can read.
sudo cat /root/sirius-scan-credentials.txtThe file records the console URL, the administrator username and password, the REST API URL and key, and the PostgreSQL user and password. Nothing in it exists in the published image, and no two machines launched from this image share a value.
To read individual values without printing the whole file, run:
sudo grep -E '^SIRIUS_(URL|ADMIN_USERNAME)=' /root/sirius-scan-credentials.txtStep 5 - Sign in to the web console
Open http://<vm-ip>/ in a browser. The sign-in page asks for a username and a password. Use the SIRIUS_ADMIN_USERNAME and SIRIUS_ADMIN_PASSWORD values from the credentials file.
After you sign in, you land on the Security Command Center. This dashboard summarises total vulnerabilities, critical issues, active hosts and severity breakdown across everything you have scanned.
To confirm the same credential works from the shell, run this before you open a browser:
curl -s -c /tmp/sirius.jar -b /tmp/sirius.jar http://127.0.0.1/api/auth/csrf | head -c 40; echoStep 6 - Run your first scan
Open Scan Dashboard from the left-hand rail. Type a target into the target box and press Enter to commit it. Sirius accepts single addresses, CIDR ranges such as 10.0.0.0/24, dash ranges such as 192.168.1.1-10, and domain names. Choose a scan profile, then click Start Scan.
The dashboard tracks the scan live. It shows the elapsed time, the number of hosts discovered so far, and a severity tally that fills in as findings arrive.
You can also watch the scan from the shell, which is useful when driving scans from automation:
sudo bash -c 'K=$(grep -E "^SIRIUS_API_KEY=" /root/sirius-scan-credentials.txt | cut -d= -f2-); curl -s -m 20 -H "X-API-Key: $K" http://127.0.0.1:9001/api/v1/scans/status | head -c 200'; echoStep 7 - Read the host inventory
Environment lists every host Sirius knows about, with its detected operating system, its open port count, its vulnerability count and a risk level. This is the working inventory the scanner builds up over time.
Click a host to open its detail page. The overview gives you the vulnerability count, the package count, the number of open ports and a risk score. The discovered ports are listed on the right. Separate tabs show vulnerabilities, system detail, network detail and scan history.
The same inventory is available over the REST API:
sudo bash -c 'K=$(grep -E "^SIRIUS_API_KEY=" /root/sirius-scan-credentials.txt | cut -d= -f2-); curl -s -m 20 -H "X-API-Key: $K" http://127.0.0.1:9001/host/ | head -c 400'; echoStep 8 - Use the REST API
The API listens on :9001. Every route except the readiness probe requires the per-VM key in an X-API-Key header. A caller without the key gets 401 rather than data.
curl -s -o /dev/null -w 'GET /host/ without a key -> HTTP %{http_code}\n' -m 15 http://127.0.0.1:9001/host/Expected output:
GET /host/ without a key -> HTTP 401With the key, the same route answers normally:
sudo bash -c 'K=$(grep -E "^SIRIUS_API_KEY=" /root/sirius-scan-credentials.txt | cut -d= -f2-); curl -s -o /dev/null -w "GET /host/ with the per VM key -> HTTP %{http_code}\n" -m 15 -H "X-API-Key: $K" http://127.0.0.1:9001/host/'Expected output:
GET /host/ with the per VM key -> HTTP 200To call the API from another machine, read the key out of the credentials file and send it as a header. Replace <vm-ip> with your machine's address:
curl -s -H "X-API-Key: <SIRIUS_API_KEY>" http://<vm-ip>:9001/host/Step 9 - Health checks and load balancer probes
Two health endpoints exist, and they answer different questions. /health is unauthenticated and reports only that the API process is up. That is exactly what an Azure Load Balancer probe should ask:
curl -s -m 10 http://127.0.0.1:9001/healthExpected output:
{"status":"healthy","timestamp":"2026-08-07T10:53:43.032454986Z","service":"sirius-api","version":"1.1.0"}/api/v1/system/health is the one to use when you want to know whether the appliance is working. It requires the API key and reports each of the six services separately. A dead database or a dead broker shows up instead of hiding behind a green process check:
sudo bash -c 'K=$(grep -E "^SIRIUS_API_KEY=" /root/sirius-scan-credentials.txt | cut -d= -f2-); curl -s -m 25 -H "X-API-Key: $K" http://127.0.0.1:9001/api/v1/system/health | head -c 400'; echoStep 10 - Attach a remote scanning agent
The console's Get Agent button downloads the Sirius agent for your platform. Agents connect back to the engine's gRPC listener on port 50051. They let one console scan networks it cannot reach directly, such as a segmented subnet or a branch office.
If you deploy agents, open 50051/tcp in the network security group and restrict it to the source addresses your agents connect from:
az vm open-port --resource-group <your-rg> --name sirius-scan --port 50051 --priority 1003Confirm the listener is up before you deploy an agent:
ss -tln | grep -E ':50051 ' || echo "agent gRPC listener not found"Server Components
Sirius Scan 1.1.0: vulnerability scanner with the console, REST API and scan engine.
Nmap 7.95: host, port and service discovery, bundled inside the scan engine.
PostgreSQL 15: hosts, ports, software inventory and vulnerability findings.
RabbitMQ 3.12: scan job queue between the API and the scan engine.
Valkey 7.2: scan state, scan templates and live scan progress.
nginx 1.24: reverse proxy fronting the web console on port 80.
Docker Engine 29.x: container runtime for the whole stack.
Ubuntu 24.04 LTS: base operating system.
Port Reference
Port 22, all interfaces: SSH.
Port 80, all interfaces: web console, through nginx.
Port 9001, all interfaces: REST API, authenticated with X-API-Key.
Port 50051, all interfaces: agent gRPC listener for remote scanning agents.
Port 5432, 127.0.0.1 only: PostgreSQL, protected by the per-VM password.
Port 3000, 127.0.0.1 only: the Next.js console process, reached through nginx.
Broker and cache, private container network: no host listener at all, reachable only by the Sirius services.
Filesystem Layout
/ (29 GB): root filesystem, holding the container images and the PostgreSQL volume.
/boot (881 MB): operating system kernel files.
/boot/efi (105 MB): UEFI boot partition (Gen2 Hyper-V).
/mnt (7.8 GB): Azure temporary resource disk, used for swap.
Key directories:
/etc/sirius-scan/compose.yaml: the appliance compose file, with every image pinned by digest.
/etc/sirius-scan/sirius-scan.env: the per-VM secrets consumed by compose (0600 root:root).
/etc/sirius-scan/secrets/sirius_api_key.txt: the internal service API key mounted into the containers.
/etc/sirius-scan/rabbitmq.conf: the message broker configuration.
/root/sirius-scan-credentials.txt: the per-VM credentials, readable only by root (0600 root:root).
/var/lib/docker/volumes/sirius_postgres_data: the PostgreSQL data directory holding your findings.
Managing the services
systemctl status sirius-scan --no-pager | head -5Stop and start the whole stack through systemd:
sudo systemctl stop sirius-scan
sudo systemctl start sirius-scan
sudo systemctl restart sirius-scanWork with individual containers through the wrapper:
sudo sirius-compose ps
sudo sirius-compose logs -f sirius-engine
sudo sirius-compose restart sirius-uiFollow the appliance logs:
sudo journalctl -u sirius-scan -f sudo journalctl -u sirius-scan-firstboot -n 50Connect to the findings database with the per VM password:
PGPASSWORD='<SIRIUS_POSTGRES_PASSWORD>' psql -h 127.0.0.1 -U postgres -d sirius -c '\dt'Scripts and Log Files
/usr/local/sbin/sirius-scan-firstboot.sh: generates every per-VM secret and brings the stack up on first boot.
/usr/local/sbin/sirius-scan-roundtrip.sh: proves the per-VM credentials work and every published default is refused.
/usr/local/bin/sirius-compose: runs docker compose against the appliance with its environment wired in.
/usr/local/sbin/sac-mnt-swap.sh: creates swap on the ephemeral resource disk on every boot.
/var/lib/sac/data/sirius-scan-firstboot.done: first-boot sentinel. Its presence stops the first-boot script from running again.
/var/lib/sac/data/sirius-scan-bootstrap.ready: bootstrap marker that the application unit is gated on.
journalctl -u sirius-scan: appliance service log.
sudo sirius-compose logs <service>: per-container logs.
/var/log/nginx/access.log: nginx access log.
On Startup
On the very first boot, sirius-scan-firstboot.service runs before the application. It resolves the machine's address and generates the administrator password, the database password, the session signing key and the internal service API key. It writes them to /etc/sirius-scan/sirius-scan.env and /root/sirius-scan-credentials.txt and brings the stack up. It proves that the datastores are reachable and that the published default credentials are refused. Only then does it create /var/lib/sac/data/sirius-scan-bootstrap.ready.
That last step matters. sirius-scan.service carries ConditionPathExists on that marker, so on a first boot it cannot start until the secrets exist. The image ships without the marker, which guarantees the stack never comes up against an upstream default credential.
On every later boot, the sentinel is present, the first-boot script exits immediately, and the containers restart normally.
You can confirm the gate is in place on your own machine:
grep -c ConditionPathExists /etc/systemd/system/sirius-scan.serviceExpected output:
1Troubleshooting
The console does not answer straight after launch. On a first boot the appliance is generating its secrets and initialising the database, broker and cache. Give it two minutes, then check sudo journalctl -u sirius-scan-firstboot -n 50.
systemctl status sirius-scan shows the unit as inactive with a condition failure. The bootstrap marker is missing, which means firstboot has not completed. Check the firstboot journal as above. Once firstboot succeeds the marker appears and the unit starts.
The console returns 502. nginx is up but the Next.js console is not yet listening. Check sudo sirius-compose ps and sudo sirius-compose logs --tail 60 sirius-ui.
/health says healthy but nothing works. /health reports only that the API process is alive. Ask the dependency-aware endpoint instead, as in Step 9, and look for any service that is not up.
Sign-in is refused. Use the username and password from /root/sirius-scan-credentials.txt on this machine. Credentials are unique per machine, and none of the upstream sample credentials work, by design. sudo bash /usr/local/sbin/sirius-scan-roundtrip.sh walks the whole chain and prints which part is failing.
A scan starts but never produces findings. The engine consumes scan jobs off the message broker, so check it is running and attached with sudo sirius-compose ps and sudo sirius-compose logs --tail 60 sirius-engine.
Scanning a remote network finds nothing. Confirm the network security groups and firewalls between this machine and the target allow the probe traffic, and remember the engine scans from this machine's own network position. For networks it cannot reach directly, deploy a remote agent as in Step 10.
Security Recommendations
- Restrict the NSG so that
22/tcp,80/tcp,9001/tcpand50051/tcpare reachable only from the networks that need them. A vulnerability scanner holds a map of what is weak in your estate, so treat it as sensitive infrastructure. - Put the console behind your own TLS-terminating load balancer or reverse proxy, or install a certificate on this machine, before exposing it beyond a trusted network.
- Change the console password from the account menu after your first sign in, and create named accounts for your team rather than sharing the administrator.
- Back up
/root/sirius-scan-credentials.txtsomewhere safe, then consider removing it from the machine. The appliance reads its secrets from/etc/sirius-scan/sirius-scan.env, not from that file. - Keep PostgreSQL on loopback and leave the broker and cache unpublished. Neither needs to be reachable from the network for this appliance to work.
- Treat the API key as a full access credential and rotate it if it is ever exposed.
- Only scan systems you own or are explicitly authorised to test, and keep a record of that authorisation.
- Leave unattended security updates enabled so the operating system keeps receiving patches.
Support
SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com with your Azure subscription ID and the VM name.
For questions about Sirius Scan itself, see the Sirius Scan GitHub repository.
Deploy on Azure
Launch Sirius Scan 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