Deployment guide

Web Check

Overview

Web Check is an open-source, self-hosted OSINT and security-analysis dashboard for websites. You enter a URL, and it gathers what is publicly observable about that site into a single report of around 35 cards. The cards cover DNS and TXT records, SSL/TLS certificate detail and TLS connection information, HTTP security headers, HSTS, open ports, DNSSEC, redirect chains, cookies, detected technology stack, WHOIS and registration data, mail configuration, crawl rules, social tags and an estimated carbon footprint.

This SecureAnyCloud image runs the Web Check 2.2.2 (MIT) Node.js server behind nginx on port 80, hardened and ready on first boot.

Web Check has no authentication of its own, and its analysis API fetches arbitrary URLs on a requester's behalf. The image is therefore secure by default: the Node server is bound to the loopback interface, and nginx gates the whole dashboard and its API behind per-VM HTTP Basic-Auth. A unique password is generated on the first boot of every instance and written to a root-only file. A public, unauthenticated health endpoint is exposed at /health.

What you get:

  • Web Check 2.2.2, built from the official source at /opt/web-check/src
  • Node.js 22 running the analysis server as the non-login webcheck user, bound to 127.0.0.1:3000
  • nginx on :80 as the single public listener, gating the dashboard and API behind per-VM HTTP Basic-Auth
  • A pinned headless Chrome at /opt/web-check/puppeteer, so the screenshot and quality checks work out of the box
  • A first-boot service that generates a unique admin password into a root-only 0600 file
  • An SSRF guard that blocks analysis of cloud instance metadata and private network ranges
  • A public, unauthenticated health endpoint at /health
  • web-check.service, nginx.service and web-check-firstboot.service as systemd units, enabled on every boot
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the dashboard. Also permit outbound HTTPS and DNS, because Web Check reaches out to the sites you analyse.

Web Check serves plain HTTP on port 80. For production, terminate TLS in front of it with your own domain.

Step 1 - Deploy from the Azure Marketplace

In the Azure portal, choose Create a resource, search for Web Check on Ubuntu 24.04 LTS by SecureAnyCloud, and select Create. Pick your subscription, resource group and region, choose the Standard_B2s size, and supply your SSH public key for the azureuser account.

On the Networking tab, allow inbound 22/tcp from your management network and 80/tcp for the dashboard. Then review and create the VM.

Step 2 - Deploy from the Azure CLI

Accept the Marketplace terms, then create the VM.

az vm image terms accept --urn sac1647283583153:web-check-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name my-web-check \
  --image sac1647283583153:web-check-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Step 3 - Connect to your VM

Connect over SSH as the azureuser administrator.

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the platform and version

Run this command to confirm the base image, the Node.js runtime and the Web Check release.

. /etc/os-release && echo "$PRETTY_NAME" node --version jq -r '.name + " " + .version' /opt/web-check/src/package.json

The output shows the Ubuntu release, the Node.js 22 runtime and Web Check 2.2.2.

Ubuntu 24.04.4 LTS v22.23.2 web-check 2.2.2

Step 5 - Confirm the services are running

Web Check runs as a systemd service behind nginx, and a one-shot first-boot service prepares the per-VM login. Confirm that all three units are in place and that the analysis server listens on loopback only.

systemctl is-active web-check.service nginx.service
systemctl is-enabled web-check-firstboot.service web-check.service nginx.service ss -ltn | grep -E ':(80|3000)\b' test -f /var/lib/sac/data/web-check-firstboot.done && echo "first boot complete"

Both services report active, and all three units are enabled. Port 3000 is bound to 127.0.0.1 only, while nginx owns 0.0.0.0:80. The analysis API is therefore reachable only through the authenticated proxy.

active active enabled enabled enabled LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 511 127.0.0.1:3000 0.0.0.0:* LISTEN 0 511 [::]:80 [::]:* first boot complete

Step 6 - Verify the authentication gate

Web Check has no login of its own, so nginx gates the dashboard and the analysis API behind HTTP Basic-Auth. The public /health endpoint returns 200 without credentials. The dashboard and the API return 401 without credentials and 200 with the per-VM login.

curl -s -o /dev/null -w 'health: %{http_code}\n' http://127.0.0.1/health
curl -s -o /dev/null -w 'unauth UI: %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'unauth API: %{http_code}\n' 'http://127.0.0.1/api/dns?url=https://example.com'
sudo bash -c 'U=$(grep ^WEB_CHECK_USERNAME= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); P=$(grep ^WEB_CHECK_PASSWORD= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); curl -sL -o /dev/null -w "auth UI: %{http_code}\n" -u "$U:$P" http://127.0.0.1/'

The output shows 200 for the public health probe, 401 for the unauthenticated dashboard and API, and 200 once the per-VM credential is supplied.

health: 200 unauth UI: 401 unauth API: 401 auth UI: 200

Step 7 - Read your per-VM login

On first boot, the unique per-VM credential (username admin) is written to a root-only file. Check the file's mode and owner.

sudo stat -c 'file mode: %a owner: %U:%G' /var/lib/sac/data/web-check-credentials.txt
sudo grep -c . /var/lib/sac/data/web-check-credentials.txt

The file is mode 600, owned by root:root.

file mode: 600 owner: root:root

Print the file when you need the password, and keep it off shared terminals.

sudo cat /var/lib/sac/data/web-check-credentials.txt
# Web Check 2.2.2 on Ubuntu 24.04 (sac Azure Marketplace image)
# Per-VM HTTP Basic-Auth credentials - UNIQUE to this VM, minted at first boot. WEB_CHECK_URL=http://<vm-public-ip>/ WEB_CHECK_USERNAME=admin WEB_CHECK_PASSWORD=<generated-per-vm-password>

Step 8 - Open Web Check

Browse to http://<vm-public-ip>/ in any modern browser. When the browser prompts for the HTTP Basic-Auth login, enter admin and the password from Step 7.

Web Check opens on its analysis screen with a single URL box. Every supported check is listed underneath, so you can see what the report will cover.

Step 9 - Run your first analysis

Type a domain into the box and select Analyze!. The domain example.com is a good first target.

Web Check runs around 38 checks in parallel and streams in the results as each one answers. The report fills in progressively over roughly ten to thirty seconds.

The report opens with an Advisory panel that groups what it found by severity: Critical, Issues, Warnings, Informational and Passes. This is the fastest way to see what is wrong with a site. In the example run, it flagged an imminent domain expiry and five missing security headers.

Step 10 - Read the certificate, header and DNS cards

Scroll down to the individual report cards, which carry the detail behind the advisory.

  • The SSL Certificate card shows the subject, issuer, trust status, curve, serial number, fingerprint, and both the expiry and renewal dates.
  • The Headers card lists the live response headers exactly as the server returned them.
  • DNS Records shows the resolved A, AAAA, MX, NS, SOA and TXT records.
  • HTTP Security grades the site against the standard protective headers.

Step 11 - Inspect TLS, DNS infrastructure and DNSSEC

Further down the report, these cards cover the connection and DNS infrastructure.

  • The TLS Connection card reports the negotiated protocol, cipher suite, forward secrecy, session resumption and OCSP stapling.
  • DNS Server resolves the authoritative nameservers to their addresses.
  • Firewall identifies any WAF in front of the site.
  • Threats checks reputation feeds.
  • DNSSEC lists the zone signing keys with their algorithms.

Step 12 - Query the analysis API directly

Every check is also a JSON endpoint, so you can drive Web Check from scripts and pipelines. Each endpoint takes a url parameter, and the same per-VM credential authenticates it.

sudo bash -c 'U=$(grep ^WEB_CHECK_USERNAME= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); P=$(grep ^WEB_CHECK_PASSWORD= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); curl -s -u "$U:$P" "http://127.0.0.1/api/dns?url=https://example.com" | jq "{A,NS}"'
sudo bash -c 'U=$(grep ^WEB_CHECK_USERNAME= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); P=$(grep ^WEB_CHECK_PASSWORD= /var/lib/sac/data/web-check-credentials.txt | cut -d= -f2-); curl -s -u "$U:$P" "http://127.0.0.1/api/ssl?url=https://example.com" | jq "{subject,issuer}"'

Each endpoint returns the same data that the matching dashboard card displays.

{ "A": [ "104.20.23.154", "172.66.147.243" ], "NS": [ "elliott.ns.cloudflare.com", "hera.ns.cloudflare.com" ] } { "subject": { "CN": "example.com" }, "issuer": { "C": "US", "O": "SSL Corporation", "CN": "Cloudflare TLS Issuing ECC CA 3" } }

To run every check at once, request /api with no check name. It returns the whole report as a single JSON document.

Step 13 - Review the built-in SSRF guard

Because Web Check fetches whatever URL it is given, this image ships a blocklist so that the appliance cannot be aimed at cloud instance metadata or at your own private network. Confirm that the blocklist is in place.

grep '^API_BLOCKED_HOSTS=' /etc/web-check/web-check.env

The blocklist covers the Azure instance metadata endpoint and every RFC1918, CGNAT, loopback and link-local range.

API_BLOCKED_HOSTS=169.254.0.0/16,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10,localhost

To analyse a host inside your own network deliberately, remove that range from the list and restart the service. Do this only on an instance you keep private.

Step 14 - Enable the optional third-party checks

Around 35 of the checks work immediately with no configuration. A small number call external services that need a free API key of your own: Shodan, Google Safe Browsing threat data, global ranking, subdomain discovery and page quality. Without a key, those cards report that the key is missing and the rest of the report is unaffected. No key is baked into this image.

To enable one, add it to the runtime environment file and restart the service. List the available key names first.

grep -E '^#\s+[A-Z_]+_API_KEY|^#\s+TRANCO|^#\s+WHO_API_KEY' /etc/web-check/web-check.env

The key names are listed as comments, ready for you to fill in.

# GOOGLE_CLOUD_API_KEY=
# SHODAN_API_KEY=
# SECURITY_TRAILS_API_KEY=
# URL_SCAN_API_KEY=
# CLOUDMERSIVE_API_KEY=
# WHO_API_KEY=
# TORRENT_IP_API_KEY=

Uncomment the line you want and paste in your key. Then run sudo systemctl restart web-check to pick it up.

Maintenance

Web Check is stateless. It stores no database and no report history, so maintenance is limited to the service and the OS. Check the service status and recent log lines.

systemctl status web-check.service --no-pager | head -5 journalctl -u web-check.service --no-pager -n 10

Restart the analysis server with sudo systemctl restart web-check. After editing /etc/nginx/sites-available/web-check, reload nginx with sudo systemctl reload nginx. The OS receives unattended security updates automatically.

To rotate the dashboard password, write a new one with htpasswd.

sudo htpasswd -B /etc/nginx/.web-check-htpasswd admin

The rate limiter that upstream ships for its public instance is deliberately disabled here (API_ENABLE_RATE_LIMIT=false in /etc/web-check/web-check.env). A single full analysis makes around 38 API calls, and the public limits would throttle you on your own instance. If you expose this VM to a wider audience, set the value to true and restart the service.

Support

SecureAnyCloud provides 24/7 technical support for this image by email at sales@secureanycloud.com and via live chat, with a one-hour average response time for critical issues.

We help with deployment, reverse proxy and TLS configuration, managing the per-instance login, enabling the optional third-party integrations, tuning the blocked host rules, headless browser troubleshooting and version upgrades.

Deploy on Azure

Launch Web Check 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

Deploy on Azure