FAQ

Frequently asked questions

Common questions about how Astrari works, the scanners, site monitoring, alerts, and billing.

General

What is Astrari?

Astrari is a security monitoring platform for agencies managing Linux servers and websites. A lightweight agent installs on each server, runs security scans locally, and reports findings to a central dashboard. Any website can be added for external monitoring — no plugin or server access required. WordPress sites get additional deep scanning: CVE matching across 12,250+ known vulnerabilities, plugin/theme version detection, and agent-assisted auto-fixes.

Who is Astrari for?

Primarily web agencies and managed service providers who manage Linux servers and websites on behalf of clients. It's also used by businesses managing their own infrastructure who want ongoing security visibility without dedicated security staff.

Does the agent need inbound ports or firewall exceptions?

No. The agent is fully outbound-only. It connects to api.astrari.io over HTTPS (port 443) to check in and post results. No inbound connections are ever made to the server.

Is my data stored securely?

Yes. Agent tokens are stored as SHA-256 hashes — the plain token is shown once at creation and never stored. All communication is over HTTPS. Scan findings are stored per-organisation with strict multi-tenancy isolation.

The agent

What Linux distributions are supported?

Any Linux distribution running systemd on x86_64 or arm64 hardware. The agent binary is statically compiled (no GLIBC dependency), so it works on RHEL 7, CentOS 7, Ubuntu 18.04, Debian 9, Rocky Linux, AlmaLinux, and anything newer. The installer supports both Debian/Ubuntu (apt) and RHEL/CentOS/Fedora (dnf/yum) package managers.

Will the install upgrade existing packages on my server?

Possibly — and the installer now asks you before doing anything. When ClamAV and rkhunter are installed via apt or dnf, your package manager may upgrade other packages that are pulled in as transitive dependencies. The most common case is RHEL-family servers where installing ClamAV 1.4.x bumps the rest of the ClamAV stack and pulls in a newer OpenSSL build from your distro's current security stream. Before making any changes the install script prints exactly what would be installed and upgraded (using 'dnf install --assumeno' or 'apt-get install --simulate') and asks you to choose: (y) install everything shown, (s) skip OS scanners and install only the agent, or (n) abort and install nothing. For unattended installs append --yes to confirm automatically, or --no-tools to install the agent without any OS scanners. The installer never runs 'dnf upgrade' or 'apt-get upgrade' — it only installs the two packages we ask for. Any other version changes are dependency resolution by your package manager, and they're shown in the preview before you confirm. After OpenSSL upgrades you may need to restart services that hold libssl in memory (nginx, php-fpm, mysqld) — 'needs-restarting -r' on RHEL family or 'checkrestart' on Debian will tell you which.

ClamAV / rkhunter / MalDet say 'not installed' on my server — what do I do?

Open the server's detail page and you'll see the affected scan button is greyed out, with an Install button next to it. Click it, confirm the warning, and the agent will pick the install up on its next 30-second checkin. Why isn't it auto-installed? In earlier agent versions we did try to install ClamAV and rkhunter automatically during the agent install. We stopped doing that after a customer noticed the package manager had transitively upgraded openssl/libssl on production servers as a side-effect (this is normal apt/dnf behaviour but caught them off guard). Now we only install on explicit confirmation per server. ClamAV: pulled from your distro's apt/dnf repos. May upgrade libssl and related transitive packages — restart nginx/php-fpm/mysqld afterwards if you rely on a specific OpenSSL version. rkhunter: pulled from apt/dnf repos. Small, few dependencies. MalDet (Linux Malware Detect): not in standard repos. The agent downloads the upstream tarball from rfxn.com, extracts it, and runs its install.sh. No package manager dependencies are touched. Once installed, the SRV_SCAN_ERROR finding auto-resolves on the next scan and the scan button becomes available.

Why doesn't 'apt upgrade' fix the CRITICAL 'CVEs in system binary runtimes' finding?

Because those CVEs are compiled INTO specific binaries — Node.js, Python, Teleport, Plesk, esbuild, the Astrari agent itself, and similar. The vulnerable code is part of the binary, not a shared library that apt/dnf can swap out. A fix requires the binary's own vendor to ship a new release. These findings stay OPEN and visible because they are real CVEs that need addressing — just not via your package manager. To stop them from tanking the score on otherwise well-maintained servers, we apply a light flat -5 score penalty (instead of the full -30 a CRITICAL finding would normally cost). So a server with one lang-runtime CVE finding caps out at 95, not 70. The practical fix is usually: bump Node.js / Python / Plesk / Teleport / etc. to its latest stable release using its own update mechanism (nvm, pyenv, plesk_installer, teleport-update, etc.), then re-scan. Once the binary's runtime version moves past the CVE's fixed version, the finding resolves automatically.

Does it work with Plesk, cPanel, or WHM?

Yes. The agent installs and runs normally on servers managed by Plesk, cPanel, or WHM. These control panels use Apache as the web server, which means .htaccess-based auto-fixes for WordPress sites work correctly on those servers. MalDet also scans cPanel and Plesk account directories automatically. The agent also detects which panel is installed and surfaces it on the server detail page and in the servers list — handy when you manage many servers and need to recall at a glance which run cPanel/WHM vs Plesk vs bare. Detection is based on the standard install paths (/usr/local/cpanel, /usr/local/psa) and the version is read from each panel's own version file.

How does the agent timer work?

A systemd timer fires every 30 seconds (with up to 20 seconds of randomised jitter to spread load across many servers). Each fire starts the agent as a oneshot service — it checks in with the API, processes any queued actions (forced scans, package updates, .htaccess fixes), and exits. Between runs it consumes no resources whatsoever. The frequent heartbeat means dashboard-triggered actions apply within seconds rather than minutes.

Will the agent update itself automatically?

Yes. On every run the agent checks for a newer version. If one is available it downloads the new binary, verifies its SHA-256 hash and Ed25519 cryptographic signature against a key baked into the binary, then replaces itself atomically and re-executes — all within the same timer fire. No manual action is required. Updates are refused if the signature does not match, protecting against tampered binaries.

What happens if the Astrari server is down?

The agent handles outages gracefully. If the API is unreachable: check-ins fail silently, scans still run on their normal schedule, and results are cached locally in /var/lib/astrari/pending_results.json. When the server comes back the cached results are posted automatically on the next heartbeat. The agent will never repeat an expensive scan just because posting failed.

How do I stop a running scan?

You can cancel a queued scan from the dashboard — this is effective if the agent hasn't started it yet. Since the agent checks in every 30 seconds, you typically have only a brief window to cancel. If a scan is already running on the server it must complete naturally. To force-stop a running scan: run 'systemctl stop astrari-agent.service' on the server. The scan will be cleanly terminated.

What does the Load · Disk · Mem strip on each server show?

Lightweight runtime state captured by the agent on every 30-second checkin: 1-minute load average, percentage of root filesystem used, percentage of memory used (using MemAvailable, the same number 'free -m' shows under available). Values colour to amber when concerning (load > 2, disk > 80%, mem > 85%) and red when critical (load > 5, disk > 90%, mem > 95%). It's the at-a-glance pair to the server's security score — a server can have a perfect score and still be 95% disk-full, which is its own problem because logs stop writing and scanners can't run. We deliberately don't keep history or build trend graphs — that's monitoring-tool territory (Datadog, Grafana, etc.) and we're not trying to be that. The strip is point-in-time current state from the last checkin, refreshed every 30s. If you need historical trend data on a host, pair us with a real ops monitoring tool.

What's the 'Needs your attention' card at the top of each server?

A summary of any actionable issues, condensed to a short list of pills. Each pill represents one signal — agent offline, malware detected, backup failed, EOL OS, scanner install failed, reboot required, vault verification failed, critical/high CVE counts, package updates available — colour-coded by urgency (red = blocking, amber = act soon, info = good to know). Clicking a pill jumps to the relevant tab on the page. When nothing's wrong you see one green pill: 'All checks healthy · last scan Xh ago'. We render the green pill rather than hiding the card entirely so an empty card never reads as 'still loading'. If more than 5 issues fire at once, the lowest-priority ones collapse into a '+ N more' link.

Server scanners

What does each server scanner detect?

Trivy: CVE vulnerabilities in installed OS packages (matched against NVD/OSV). ClamAV: known malware and virus signatures across high-risk directories — auto-detected if already installed; not auto-installed by the agent installer to avoid touching your system packages. rkhunter: rootkits, backdoors, suspicious binaries, and modified system commands. MalDet: PHP shells, obfuscated backdoors, and web-specific malware in web directories (/var/www, public_html, etc.), including cPanel and Plesk accounts. SSL certs: expired or soon-to-expire TLS certificates detected via Let's Encrypt cert files and TLS probes on port 443/8443. SSH hardening: unsafe sshd_config settings (root login, password auth, empty passwords). Firewall: checks whether ufw or iptables rules are active. File integrity: compares current file hashes against a baseline taken on first run and reports any changes.

How often do the scanners run?

The agent fires every 30 seconds for fast heartbeats and queued action delivery, but scans are throttled separately so the server stays idle most of the time. A full scan (SSH config, SSL certs, firewall, package list, Trivy CVE) runs every 6 hours. ClamAV, rkhunter, and MalDet are heavier — they self-throttle and only run if more than 6 days have passed since their last run, and only as part of a full scan. Forced scans triggered from the dashboard bypass this throttle and start within seconds on the next agent fire.

Will the scans slow down my server?

No. All scan tools run under 'nice -n 19 ionice -c 3' — the lowest possible CPU and I/O scheduling priority. They only get resources when the server is otherwise idle. In practice, the scans are invisible to live workloads. The agent itself exits completely between runs, consuming zero resources.

Can I run a specific scanner without a full scan?

Yes. The server detail page has individual scan buttons for Trivy, ClamAV, rkhunter, and MalDet. Clicking one queues a targeted scan — only that scanner runs on the next agent fire (within ~30 seconds), bypassing the weekly throttle. Use Trivy after applying package updates to confirm patches took effect. Use MalDet if you suspect a web directory compromise. Use rkhunter if you notice suspicious system behaviour.

Can Astrari automatically fix SSH security issues?

Yes — for two common SSH hardening findings, Astrari can apply the fix automatically via the agent: • Disable root login — sets PermitRootLogin to 'no' in /etc/ssh/sshd_config and restarts the SSH service. The agent first checks that at least one non-root user with sudo or wheel group membership exists — if none is found, the fix is skipped to prevent lockout. • Disable password authentication — sets PasswordAuthentication to 'no' and restarts the SSH service. The agent first checks that at least one SSH authorized_keys file exists for any user — if none is found, the fix is skipped to prevent complete lockout. To apply: expand the relevant finding in the 'Access & SSH' section, then click 'Fix now'. A confirmation modal explains the change and requires you to confirm you have an alternative way into the server. The fix is queued in the dashboard and applied on the next agent check-in (within ~30 seconds). Your current SSH session is not affected — only new connections change behaviour.

What does 'Apply updates' do?

Clicking Apply updates queues apt-get upgrade -y (Debian/Ubuntu) or dnf upgrade -y (RHEL/CentOS/Rocky) to run on the server at the next agent check-in — typically within 30 seconds. After the upgrade completes the agent automatically re-runs a Trivy CVE scan and any patched vulnerabilities are resolved in the dashboard automatically. For targeted control, each CVE finding that corresponds to an OS package has a checkbox. Tick the packages you want to update and click 'Update N packages' — this queues a selective upgrade of only those packages rather than a full system upgrade. Useful when you want to patch a critical CVE without rolling out all pending updates. Update lifecycle: once queued the finding badge changes to 'update queued' (green). When the agent picks up the update and starts applying it, the badge changes to 'verifying…' (amber). After the Trivy scan confirms the package was patched, the finding resolves automatically. Note: kernel package CVEs and CVEs in compiled binaries show a 'requires reboot' or 'requires rebuild' badge instead of a checkbox — these cannot be patched in-place by apt/dnf.

How does updating work on cPanel/WHM and Plesk hosts?

These panels manage their own pinned package set, so a blanket apt-get/yum upgrade can corrupt the panel — cPanel loses its accounts DB, Plesk's PSA disconnects from MariaDB, EasyApache's PHP/Apache combinations break. Astrari handles this automatically: Apply OS updates (warning-orange) — runs the OS package manager with panel-managed packages excluded: • cPanel: yum upgrade with --exclude=cpanel-*,ea-*,whm-*,MariaDB*,mysql-community-* • Plesk on Debian/Ubuntu: apt-mark hold plesk-*, psa-*, sw-*, mariadb-* → apt-get upgrade → apt-mark unhold • Plesk on RHEL/AlmaLinux/Rocky: yum upgrade with --exclude=plesk-*,psa-*,sw-*,MariaDB-*,mariadb-* Run cPanel update / Run Plesk update (brass) — invokes the panel's own auto-updater on the host: • cPanel/WHM: /scripts/upcp --force • Plesk: plesk installer update Both buttons appear on the server detail page only when the agent has detected the panel. Selective per-package updates are guarded too — the API rejects an attempt to update a panel-namespaced package and points you at the panel update action instead. After either path completes, Trivy auto-rescans on the next agent check-in and matched CVE findings resolve automatically.

Can Astrari rebind exposed databases (MySQL, Redis, etc.) automatically?

Yes, for six common services where the standard fix is 'change the bind address back to localhost and restart'. When the agent's exposure scanner flags one of these as bound to a public interface, the finding gets a Fix now button: • MySQL/MariaDB → bind-address = 127.0.0.1 in my.cnf • PostgreSQL → listen_addresses = 'localhost' in postgresql.conf • Redis → bind 127.0.0.1 in redis.conf • Memcached → -l 127.0.0.1 in memcached.conf (or OPTIONS on RHEL) • MongoDB → bindIp: 127.0.0.1 in mongod.conf • Elasticsearch → network.host: 127.0.0.1 in elasticsearch.yml Before touching anything, the agent runs preflight checks specific to the service: • Active connections — refuses if any remote (non-loopback) clients are currently connected to the port. • MySQL panel checks — refuses if WHM's 'Allow remote MySQL connections' allowlist has entries, or if Plesk's Database Hosting feature is enabled. (These features intentionally expose MySQL; rebinding to localhost would break customer-database access.) • Container check — refuses inside Docker / containerd because container networking is too varied to reason about safely. If preflight passes, the agent backs up the existing config to <path>.astrari-bak.<unix-timestamp>, edits the bind setting in place, restarts the service via systemctl, and waits up to 30 seconds (60 for Elasticsearch) for the unit to report active. After restart it re-checks the listening ports — if the bind didn't actually move to localhost, the original config is restored automatically and the failure is surfaced as a finding with the diagnostic detail. The exposure scanner re-runs immediately after a successful fix so the finding auto-resolves. What the auto-fix doesn't do: open up legitimate remote access patterns. If you have applications that need to connect from another host, the right tool is firewall allowlisting at the network layer — not changing the bind address. Use the Network tab to manage UFW/iptables rules instead.

How is CloudLinux KernelCare handled?

On CloudLinux servers running KernelCare, kernel CVEs are patched live in memory — uname -r doesn't change because the running kernel image stays the same, but the vulnerable code paths are replaced. Trivy can't tell the difference, so it keeps reporting kernel CVEs that are actually fixed. Astrari closes that gap by reading kcarectl on every agent check-in: • kcarectl --info reports auto-update status and the 'effective kernel version' (what you'd be running if patches were activated by reboot rather than live). • kcarectl --patch-info lists every CVE the loaded patch covers. Matching open Trivy kernel-CVE findings on that host get acknowledged with a note recording the effective kernel version, so you can see at a glance that the host is genuinely protected. The system info table shows the live-patch state — including a clear warning if auto-update is off, in which case CloudLinux advisories should not be considered automatically applied.

Why didn't the scanner catch malware I know exists?

Each scanner has a specific scope. Trivy only checks installed OS packages — not files in your web directory. ClamAV detects known signatures — novel or obfuscated malware may not be in its database. MalDet is the most effective for web-specific threats like PHP shells. For a WordPress infection, run a MalDet scan and also check for recently modified PHP files manually: find /var/www -name '*.php' -mtime -30

Findings

Can I suppress or dismiss a finding?

Yes. Expand any finding on the server or site detail page to reveal suppress options: • Acknowledge — marks the finding as known and reviewed. It still counts towards the security score (you've accepted the risk) but is visually distinguished from unreviewed findings. • False positive — hides the finding from view and excludes it from the score entirely. Use this when a scanner reports something that doesn't apply to your environment (e.g. rkhunter flagging a legitimate custom binary). Both options accept a free-text note explaining the decision. If circumstances change, use Reopen to return the finding to Open status.

Will a suppressed finding come back after a rescan?

No. Suppression survives rescans. The agent uses a fingerprint hash to identify each unique finding — if the same issue is reported again the existing record is updated but its status (Acknowledged or False Positive) is preserved. Only a Reopen action will change it back to Open.

Why did my findings list change after a scan even though I didn't fix anything?

After each scan, findings that were not reported by the scanner are automatically resolved. This keeps the list accurate: if a package was patched by a system update outside of Astrari, its CVE finding will be resolved on the next scan without any manual action. Findings you've marked Acknowledged or False Positive are never auto-resolved — only Open ones.

Where can I see findings across all my sites and servers at once?

The Global Findings page (linked from the sidebar) shows all open findings across every site and server in your organisation, in one list. You can filter by severity, type, and status. This is the fastest way to triage your most critical issues without clicking into individual assets.

Why do some CVE findings get auto-acknowledged?

Five distinct paths can auto-acknowledge a CVE finding, each with a different rationale stamped in the acknowledgement note: • Backport-patched — the agent ran an update, the package version didn't change, but the distro has backported the fix to the existing version. Common on Debian/Ubuntu and RHEL where security fixes are backported rather than version-bumped. • No upstream patch available — Trivy reports the CVE has no known fix anywhere. Auto-acked unless the OS is end-of-life (in which case it stays open with an OS-upgrade note, because 'no fix' on an EOL distro means upgrade, not 'live with it'). • Vendor advisory superseded — we'd previously emitted a manual finding from a CloudLinux/RHSA/USN/DSA/ALSA/CISA-KEV advisory; once Trivy itself starts reporting the same CVE, the manual one is redundant and we ack it in favour of the agent's organic detection. • Live-patched by KernelCare — only on CloudLinux hosts with kcarectl. The kernel CVE is loaded as a live-patch in memory, so the host is genuinely fixed even though Trivy still reports it (uname -r doesn't change). The note records the effective kernel version. • Reboot required (kernel) — not strictly an acknowledgement; the finding stays open but is annotated. Kernel updates land on disk but the running kernel doesn't change until reboot. We surface a server-wide reboot banner instead.

How does Astrari handle CloudLinux KernelCare?

On CloudLinux servers, the agent reads kcarectl --info and kcarectl --patch-info on every check-in. Two things flow back into the dashboard: • Live-patched CVE list — every CVE the running kernel has loaded as a live-patch. Any matching open Trivy finding is acknowledged with a note recording the effective kernel version. • Auto-update state — the dashboard's system info table shows 'KernelCare auto-update on' (genuinely protected within hours of CloudLinux publishing a patch) or 'KernelCare auto-update off — run kcarectl --update' (the host has the kcarectl tool but isn't pulling patches automatically; suppression of CloudLinux advisories would be premature). This means Trivy can keep reporting kernel CVEs based on uname -r, but if KernelCare has the fix loaded the dashboard correctly shows 'live-patched on this kernel' rather than 'reboot required' — because no reboot is required.

Alerts

How do alerts work?

Each server and site has its own alert configuration: enable alerts, pick a severity threshold (CRITICAL only, HIGH+, MEDIUM+, LOW+, or all), and select which contacts and channels should fire. When a new finding lands at or above that threshold, Astrari dispatches the alert to every recipient on the asset. Findings that already exist (just being re-seen by a scan) don't re-trigger — only newly opened or reopened findings do.

Which channels does Astrari support?

Out of the box: email (delivered via Resend), Slack (Incoming Webhooks), Microsoft Teams (Incoming Webhooks), PagerDuty (Events API v2), and a generic JSON webhook with optional HMAC-SHA256 signature for custom integrations. PagerDuty alerts include a stable dedup_key so re-fires for the same finding group into one ongoing incident rather than spamming pages.

How do I add an alert contact?

Go to Alerts → Alert contacts → '+ Add contact'. Provide a name, email, and optionally a phone number. Admin users can scope the contact to a specific client (so it only appears on that client's assets) or leave it org-wide. After adding, click 'Test' to send a sample email to verify delivery.

How do I connect Slack / Teams / PagerDuty?

Go to Alerts → Alert integrations → '+ Add integration'. Pick the type (Slack, Teams, PagerDuty, or generic webhook), give it a name (e.g. '#security-alerts'), and paste the webhook URL or PagerDuty routing key. Each integration has a 'Test' button that sends a sample alert so you can verify it before relying on it. Webhook URL hints: • Slack: workspace → Apps → Incoming Webhooks → Add to Slack → copy URL. • Teams: channel → ⋯ → Connectors → Incoming Webhook → Configure → copy URL. • PagerDuty: service → Integrations → add 'Events API v2' integration → copy routing key.

How do I assign contacts to a server or site?

Open the server or site detail page and find the Alerts card. Toggle 'Enable alerts on this asset', set the severity threshold, then tick the contacts and channels you want to fire. Save. From this point on, any new finding meeting the threshold dispatches to those recipients. Multi-tenant note: contacts and integrations scoped to a specific client only appear in pickers for that client's assets. Org-wide contacts/integrations appear everywhere.

Will I get alert spam if a scanner reports the same issue every cycle?

No. Each (finding, recipient) pair is dispatched at most once. Subsequent scans that re-see the same finding only bump its 'last seen' timestamp — they don't re-fire alerts. Reopening a previously resolved finding does re-fire (so you know it came back).

Will I get alerts for findings on the very first scan of a new server or site?

No — alert delivery is suppressed on the first-ever scan of an asset. The first scan establishes a baseline of what's currently on the box (which on most production servers includes a lot of pre-existing CVEs); those aren't 'new issues' from your perspective, they're the starting state. The first-scan welcome email summarises the count and severity breakdown, and you can browse all findings in the dashboard at any time. From the second scan onwards alerts fire normally — only for findings that genuinely represent a *change* in security posture (new CVE published, new service installed, drift, regression, etc.). This means you'll never get a 50-email blast of HIGH-severity package alerts the moment you install the agent on a busy production server.

Can I see the history of sent alerts?

Every dispatch — successful or failed — is recorded as an AlertEvent with the channel, status, recipient, finding, and any error message. Surfacing this as a UI is on the roadmap; for now you can query the database or contact support.

What happens if email isn't configured?

If the platform's RESEND_API_KEY isn't set, email contacts will record a failed AlertEvent with the reason 'Email not configured (RESEND_API_KEY unset)'. Slack/Teams/PagerDuty integrations are unaffected — they POST directly to their respective webhook endpoints.

Diagnostics

What is the forensic diagnostic and when should I use it?

The forensic diagnostic is an on-demand snapshot you can run on any server (or site linked to a server) when investigating downtime, slowness, or unusual behaviour. It collects: panel detection (Plesk / cPanel / bare), boot/uptime/load/memory, recent out-of-memory killer events, failed systemd units, disks at ≥85% utilisation, and the last 200 error/warn lines from nginx, Apache, PHP-FPM, MySQL/MariaDB and the system journal. The whole snapshot runs in 1–2 seconds on the server and produces a payload of around 50–100 KB. Use it when: a site is throwing 5xx errors, a service has gone down, a server reboot happened unexpectedly, or you simply want to see what the recent error logs say without SSHing in.

How do I run a diagnostic?

Server-wide: open the server detail page and click 'Run diagnostic' in the Forensic diagnostic card. The agent picks it up on its next 30-second check-in, runs the collector, and posts results back. The dashboard polls and auto-expands the latest result. Site-scoped: open the site detail page (the site must be linked to a server with the Astrari agent online). Click 'Run diagnostic' — the collector will narrow log collection to that domain by parsing nginx/Apache vhost configs (or Plesk/cPanel per-domain log paths) for domain-specific error_log entries. If no per-vhost log is configured the global log is used as a fallback.

What logs are collected for each panel?

The collector detects whether the server is running Plesk, cPanel/WHM, or is a bare system, then reads only the paths relevant to that layout: • Bare server — /var/log/nginx/error.log, /var/log/apache2/error.log (Debian) or /var/log/httpd/error_log (RHEL), /var/log/mysql/error.log or /var/log/mariadb/*, /var/log/php*-fpm.log. • Plesk — /var/www/vhosts/system/<domain>/logs/{error_log,proxy_error_log} for each vhost, plus /var/log/plesk-php*-fpm/error.log. • cPanel/WHM — /etc/apache2/logs/error_log, /usr/local/apache/logs/error_log, /opt/cpanel/ea-php*/root/usr/var/log/php-fpm/error.log, and /home/<user>/logs/<domain>.error.log when a site-scoped diagnostic runs. • Always included — journalctl -p err for the same time window.

How heavy is the diagnostic? Does it slow down the server?

Very light. Each log read seeks to the last 1 MB of the file (so it doesn't scan multi-GB files from the start), filters to error/warn-level lines only, and is bounded by both a per-source line cap (200) and a total payload cap (~256 KB). Files larger than 50 MB are skipped entirely. The whole run is sequential, mostly file reads, and finishes in 1–2 seconds. There is no continuous log shipping — the diagnostic only runs when you click the button.

Why doesn't the diagnostic show me logs from outside the last 30 minutes?

By default the collector filters to lines from the last 30 minutes to keep the snapshot small and relevant to the issue you're investigating. The API accepts a wider lookback (up to 24 hours) — if you need a longer window we can expose this in the UI as a follow-up. Lines from older runs are still kept on disk on the server itself; the diagnostic just doesn't include them in the snapshot.

Where are diagnostic results stored?

In your Astrari account, in a dedicated Diagnostic table. Each diagnostic includes the panel detected, the agent version that produced it, the requested-by user, the lookback window, and the full JSON payload. They appear in the Forensic diagnostic card on each server or site detail page, sorted newest first, and persist for the duration of your account.

Site monitoring

What sites can Astrari monitor?

Any website — not just WordPress. Simply add the domain and Astrari scans it externally with no plugin or server access required. Every site gets these checks: • SSL certificate — valid, days until expiry, alerts at 30 / 14 / 7 days. • Domain expiry — queries the RDAP registry to find when the domain itself expires. • Security headers — HSTS, X-Frame-Options, Content-Security-Policy, X-Content-Type-Options, Referrer-Policy. • Cookie security — HttpOnly, Secure, and SameSite flags. • Email security (SPF / DMARC) — checks DNS for SPF and DMARC records. • Blacklist check — Spamhaus DBL and SURBL. • SEO spam and cloaking — HTML scan for spam keywords, CSS-hidden links, and Googlebot content comparison (a difference indicates an SEO hack). • External scripts from suspicious IPs. WordPress sites additionally get: • Plugin, theme, and WordPress core version detection. • CVE matching against 12,250+ known vulnerabilities across 7,600+ components (Wordfence Intelligence). • Outdated plugin, theme, and WordPress core versions flagged with available fix versions. • Sensitive file exposure — wp-config.php, debug.log, xmlrpc.php, readme.txt, .env, .git/config, and more. • User enumeration detection (?author=N redirect probing). • Directory listing on /wp-content/. • Agent-assisted database scan and .htaccess auto-fixes (when linked to an Astrari-monitored server).

The site is behind Cloudflare or a WAF — will scans work correctly?

Partially. The scanner connects from a fixed IP address. If a WAF or CDN serves a challenge page to that IP, some checks may be inaccurate — for example, header findings reflect what the WAF returns, not the origin server, and WordPress detection may fail if the WAF blocks the probe. For the most accurate results, whitelist the Astrari scanner IP in your WAF settings. Contact support to get the current scanner IP address.

Why does the site show 'no data' under Domain expiry?

Domain expiry is looked up via RDAP (the registry's public API). Some registrars or TLDs don't publish expiry data through RDAP, or rate-limit the lookup. When data isn't available the tile shows 'no data' rather than guessing — check expiry directly with your registrar for those domains.

Can I update a WordPress plugin directly from the dashboard?

Yes, if the site is linked to a server that has the Astrari agent installed. On the site detail page, open the 'Hosting server' card and select the server that hosts the site. Once linked, any finding that involves a specific plugin will show a 'wp update' button. Clicking it queues a wp-cli update for that plugin on the linked server. The update runs on the next agent check-in (within ~30 seconds), and the finding automatically resolves after the next scan confirms the fix.

Can Astrari scan the WordPress database for injected malware?

Yes — when a site is linked to an Astrari-monitored server, you can trigger a WordPress database scan from the site detail page. Click 'Scan database' in the Hosting server card (requires the agent to be online). The agent uses wp-cli to run SQL queries directly against the WordPress database. It checks: • wp_options — CSS-hidden injected links, external script and iframe injections. • wp_options — obfuscated PHP payloads (base64-decoded scripts, rot13, gzinflate patterns). • wp_posts — hidden spam links in published post content. Results appear as WP_DB_INJECTION findings on the site. wp-cli must be installed on the server — the agent will attempt to auto-install it if not found.

Can Astrari automatically fix WordPress .htaccess security issues?

Yes — for several common WordPress hardening findings, Astrari can write a fix directly to the site's .htaccess file via the linked server agent. When a supported finding is expanded, an 'Apply fix via agent' button appears. Supported auto-fixes: • XML-RPC enabled — blocks access to xmlrpc.php. • User enumeration — blocks the ?author= query string. • Directory listing on /wp-content/ — adds Options -Indexes. • Missing X-Frame-Options — adds the header via mod_headers. • Missing X-Content-Type-Options — adds nosniff via mod_headers. • Missing Referrer-Policy — adds the header via mod_headers. • Missing Content-Security-Policy — adds a default-src CSP via mod_headers. All fixes are written with Astrari markers so they can be cleanly reverted. Once applied, a 'Revert fix' button replaces the apply button, and the site is automatically rescanned to confirm the finding resolves. Important: these fixes use Apache .htaccess directives. If the site is served by nginx (and does not use Apache), the dashboard will display the equivalent nginx server block directives instead, and the auto-fix button will not appear. Apply those directives manually in your nginx site configuration.

What blacklists do you check?

We check two DNS-based blacklists on every scan — no API key or registration required: • Spamhaus DBL (dbl.spamhaus.org) — tracks domains used for spam, phishing, and malware distribution. • SURBL (multi.surbl.org) — tracks domains appearing in spam and malware URLs. A blacklisted result is flagged CRITICAL — search engines and browsers warn visitors when a site is listed, so prompt action is essential.

Do you need admin access to the WordPress site?

No. External scanning runs without credentials. For deeper coverage — specifically to enumerate the complete list of installed plugins and themes rather than probing file paths — you can optionally add WordPress Application Password credentials per-site. These use the WP REST API and require a user with at least Editor role.

Vault — backups

What is Astrari Vault?

Vault is the optional backup add-on. The agent runs restic on each server you enable it for, encrypts the snapshot client-side, and pushes it to a Backblaze B2 bucket that Astrari provisions on your behalf. It's append-only by design: even if a server is compromised, the agent's key cannot delete prior snapshots, so ransomware can't wipe your backup history. Vault is currently files-only (Phase 1) — database dumps and in-place restores arrive in subsequent phases.

How much does Vault cost?

Pay-as-you-store: £0.05 per GB stored per month. No per-server fee, no minimum, no annual lock-in. Restores incur an egress fee of £0.02 per GB above 10 GB included free each month — so restoring a small site or single subpath is free, and restoring a 50 GB tree costs about £0.80. The dashboard shows a live monthly bill estimate based on your current bucket size; storage is metered after each successful snapshot.

Where does my backup data live, and who controls the encryption?

Snapshots are pushed to a Backblaze B2 bucket Astrari provisions for you (region-selectable: EU Amsterdam, US-West, US-East — EU is the default). Restic encrypts the data on your server before it leaves the host using a recovery passphrase shown to you once at setup. We keep an encrypted escrow copy of that passphrase so we can help if you lose it, but we cannot read your data — only restic with your passphrase can decrypt the snapshots. The agent's B2 application key is append-only (write + list + read, no delete) for the same reason.

How do I enable Vault for a server?

On the server's detail page, scroll to the Vault panel and click 'Install restic →' (the agent needs the restic binary; it asks for your consent before touching system packages). Once installed, click 'Enable backups →' — pick what to back up (e.g. /etc and /var/www), pick a retention preset (Tight/Balanced/Long), choose a region and daily backup time, and Astrari handles the rest: bucket creation, key provisioning, recovery passphrase generation. You'll see the passphrase once — save it.

What retention options are available?

Three presets: Tight (last 3 / daily 7 / weekly 4 / monthly 3 — minimises B2 cost), Balanced (last 7 / daily 14 / weekly 8 / monthly 12 — recommended default), and Long (last 14 / daily 30 / weekly 12 / monthly 36 — ~3 years of history, compliance-friendly). The prune cycle runs every Sunday at 04:00 UTC and enforces whichever policy is current; switching to a tighter policy lets the next prune reclaim B2 space, switching to a longer one applies immediately to new snapshots but won't recover already-pruned history.

Can I trigger a backup outside the schedule?

Yes. Click 'Run backup now' on the Vault panel — the agent picks it up on its next 30-second checkin and runs the snapshot regardless of the schedule. The button is disabled while a backup is already in flight to prevent concurrent restic runs on the same target.

How do restores work?

Click 'Restore from snapshot' on the Vault panel, pick a snapshot from the dropdown, and optionally type a single sub-path (like /var/www/example.com) to restore only that subtree. The agent pulls the data into /var/lib/astrari/restore/<jobId>/ on your server with the original directory structure preserved underneath. Nothing is overwritten — once it's down, you copy what you need wherever you need it (cp, rsync). In-place restore that overwrites originals is intentionally Phase 2b: it lives behind a 2FA gate because a careless restore can make a bad day worse.

Does Vault back up databases?

Yes. The agent discovers MySQL/MariaDB and PostgreSQL databases on each fire and reports them to the dashboard. You opt-in per database — open Edit configuration on the Vault panel and tick the databases you want to back up. Selected databases are dumped via mariadb-dump (or pg_dump) on each backup fire and streamed straight to restic, so each database becomes its own snapshot tagged db:type:name. Discovery covers four sources: cPanel (whmapi1 + uapi per account), Plesk (plesk db), bare MySQL/MariaDB via root socket auth, and PostgreSQL via peer auth as the postgres user. Default is 'no databases selected' — opt-in by design so a multi-tenant cPanel box doesn't enrol 50 customer databases by accident.

How do I see which client owns each database on a multi-tenant box?

On cPanel hosts, the dashboard groups databases by the owning cPanel account ('cPanel: clientuser ([email protected])'). On Plesk hosts, by subscription/domain. Each row shows the database name and engine. This way, when you have an agency-style cPanel box with 30 customer accounts, you can see at a glance which databases belong to whom and tick selectively — back up everything for premium clients, skip caches and dev sandboxes for others.

How do I restore a database?

Open Restore from snapshot on the Vault panel — the snapshot dropdown groups by Files and per-database. Pick the snapshot for the database you want and Restore now. The agent pulls the dump into /var/lib/astrari/restore/<jobId>/db/<type>/<name>.sql.gz on your server (sandbox-only, like file restores). You then load it with mysql < name.sql or psql < name.sql against whichever database you want to restore into. Direct in-place database restore (point at a live database, agent re-imports for you) is Phase 3b — same reasoning as in-place file restore, behind a 2FA gate to prevent accidental wipes of production.

Are database backups consistent or do they corrupt under load?

Consistent. mariadb-dump runs with --single-transaction --quick --routines --triggers --events: a single MVCC transaction snapshot of every InnoDB table, no write locks on the database, stored procedures and triggers preserved. pg_dump uses its own consistent-snapshot mode by default. The dump streams through gzip into restic's --stdin so we don't double the disk footprint while it runs.

What about databases running in Docker, RDS, or somewhere remote?

Not yet — discovery currently relies on socket auth and panel APIs available to root on the host filesystem, which means Docker-isolated databases, AWS RDS, and other network-attached databases are invisible to the agent. We're planning a 'manual database connection' flow next — you'll add a connection in the dashboard (host, port, user, password) and the agent will dump it via TCP, working for any database the host can reach. Until that ships, your options are: back up the volume directory directly (works but risky on a live database — restic snapshots the raw files, which can corrupt under writes), or wait for the manual-connection feature.

Do database dumps slow the server down or lock my application?

Same nice -n 19 ionice -c 3 wrapper as file backups, plus mariadb-dump's --single-transaction means no write locks on InnoDB. PostgreSQL pg_dump is non-blocking by design. On well-tuned hardware a 1 GB database dumps in seconds; on contended boxes the scheduler de-prioritises it under live traffic. The dump is streamed to restic without touching disk, so there's no scratch-space cost beyond the database server's own buffer pool.

What happens if I add a new database to the server?

The agent picks it up automatically. Discovery runs on every 30-second checkin, so a new database created on the server will appear in the Edit configuration panel within ~30 seconds. The dashboard shows the discovered list with checkboxes — you tick the new database to enable it for backup. Existing selections are preserved; you don't have to re-pick everything every time something changes on the host.

What happens if my server is compromised?

The agent's B2 key is append-only — an attacker on the host cannot delete or modify prior snapshots, only add new ones. The full-permission pruner key that runs the weekly forget+prune is held only on Astrari's API infrastructure and never touches your server. Combined with restic's content-addressed encryption, this means a compromised host can't take your backups down with it. To recover, queue a restore against the most recent snapshot from before the compromise, copy what you need to a clean host, and rebuild.

Do backups slow my server down?

Backups run under nice -n 19 ionice -c 3 — the lowest CPU and I/O priority Linux exposes. On idle hardware they're invisible; under heavy load the kernel scheduler will starve restic before touching real workloads. Restic also de-duplicates client-side, so a daily snapshot of a 50 GB tree typically only ships a few hundred MB after the first run.

Can I see the live status of a running backup or restore?

Yes. The server's detail page shows a banner at the top while a vault op is in flight ('Backup running' / 'Restore running'), and the servers list shows a coloured pill alongside the scan-status pill. The Vault panel itself shows snapshot counts, last backup time, recovery score, and a 'Recent restores' feed below the action row. Both the banner and pills clear automatically within ~30s of the agent reporting completion.

How do I know my backups are actually restorable?

Astrari Vault verifies your repo on two layers, both visible on the Vault panel. (1) Integrity check — runs every 7 days on every active target regardless of plan. The agent runs `restic check` against your B2 bucket, validating every snapshot's pack files and index are intact and decryptable. Every fourth run is a deep check that re-reads 5% of pack contents to catch bit-rot. (2) Restore test — runs at the cadence you choose: monthly on the free tier, weekly on paid plans, or off. The agent actually restores the latest snapshot to a sandbox path on the server (`/var/lib/astrari/attestation/<jobId>/`), validates a sample of files materialised correctly, then cleans up. This proves the whole restore pipeline works end-to-end — egress from B2, sandbox creation, file write, file read — not just that bits in B2 are valid. Both kinds also have on-demand 'Verify integrity' and 'Test restore' buttons that bypass cadence and always work regardless of plan. Failures route through your normal alert channels. The on-demand buttons are useful before scheduling risky work — pre-rebuild verification, pre-migration check, or just compliance evidence.

What does 'verification skipped' mean on the Vault panel?

Skipped means the verification couldn't run — usually because preconditions aren't met: restic isn't installed, the agent's vault.env credentials are missing, or B2 returned an authentication error (typically a rotated key). It does NOT mean your backups are corrupt — it means we can't tell yet. Fix the precondition (install restic, re-provision credentials, or rotate the B2 key) and click 'Verify integrity' to retry. We deliberately distinguish 'skipped' from 'failed' so the dashboard never shows a false-positive 'passed' when verification couldn't actually run.

Integrations · Cloudflare

What does the Cloudflare integration do?

Astrari reads your Cloudflare zone state and surfaces it alongside the rest of your security posture. With a scoped read-only API token connected, we poll every 10 minutes and pull: • SSL/TLS mode (off / flexible / full / strict / origin-pull) — flexible and off are flagged as findings because they leave traffic unencrypted between Cloudflare and your origin. • Always Use HTTPS — flagged when off. • DNS records — we hash the canonical record set and fire a HIGH finding when it changes between polls (early detection of unauthorised DNS edits). • Edge certificate expiry — feeds the existing 'SSL certificate expiring' tile, with severity ramping from MEDIUM (60d) → HIGH (30d) → CRITICAL (7d). • Aggregate firewall event count — last 24h, available on all Cloudflare plans. • Per-event firewall detail (top attackers, rule, country, time, request URI) — Pro plan or higher only; Free plan zones gracefully degrade to the aggregate count. We never write back. Astrari is read-only by design — we don't push WAF rules, change DNS, or sit in your request path. Use the Cloudflare dashboard for management; Astrari just gives you one place to see what's happening across all your assets.

How do I connect my Cloudflare account?

Go to Settings → Integrations → Connect a Cloudflare account. You'll need a scoped Cloudflare API token (not a Global API Key). Create one at dash.cloudflare.com → My Profile → API Tokens with these read-only permissions: • Account · Account Settings:Read — used to label the connection. • Zone · Zone:Read — list your zones. • Zone · Zone Settings:Read — SSL mode, Bot Fight, Always-HTTPS, Under-attack mode. • Zone · Zone WAF:Read — firewall events (Pro plan or higher). • Zone · DNS:Read — DNS record list, for change detection. • Zone · SSL and Certificates:Read — edge cert expiry. • Zone · Analytics:Read — aggregate threat counts (works on all plans). Important: pick the DNS:Read scope from under the Zone permission group. There's a separate top-level 'DNS' permission group used for the DNS Firewall product — that one won't grant the access we need. The connection form calls this trap out explicitly. Paste the token, optionally label the connection, click Connect. Astrari verifies the token against Cloudflare's API, lists your zones, and stores the token AES-256-GCM encrypted at rest. Only the last four characters are shown back in the UI.

I added the token but no data is appearing — what's wrong?

Linking a zone is two steps. After connecting the token we list every zone in your Cloudflare account, but none are polled until you opt them in: 1. Click 'Manage zones' on the connection card. 2. Tick the Monitor box next to each zone you want polled. 3. Pick a Site from the dropdown to surface that zone's WAF data on the Site detail page. Linking a zone to a Site auto-enables monitoring (so you don't have to tick both). Use the 'Poll now' button at the top of the connection card to trigger an immediate fresh poll instead of waiting up to 10 minutes for the next cron tick — handy right after you change scopes or enable a zone. If the Manage Zones panel shows a 'Flexible SSL' or 'Always-HTTPS off' chip on a row, that's working as designed — those are findings, not errors.

Why does the connection say 'error' or stop polling?

Three consecutive Cloudflare API failures flips the connection status to 'error' and halts polling until either the next cron tick succeeds or you click 'Poll now'. The most common causes: • Token expired or revoked — rotate it in Cloudflare and reconnect. • Token scope removed — Cloudflare lets you edit a token's permissions; if you narrow them after connecting, polls fail. Check the connection card's last-error line for the missing scope name. • Cloudflare-side rate limit (1200 requests / 5 min) — extremely rare under normal use, but possible if you have hundreds of monitored zones. Contact support if you hit this. While a connection is in 'error' state we don't auto-resolve any existing Cloudflare findings — your last-known good state is preserved until polling is healthy again.

What's the difference between 'monitored' and 'linked to a Site'?

Two independent flags: • Monitored — the zone is included in the 10-minute poll cycle. Without this we don't fetch settings, DNS, or events for that zone. • Linked to a Site — the polled data is surfaced on a specific Site's detail page (Edge protection panel, the ☁ CF badge, attached findings). A monitored zone with no linked Site still produces findings, but they appear org-wide rather than tied to a specific Site. A linked-but-unmonitored zone shows nothing because we have no data for it. The 'auto-monitor on link' shortcut in the UI keeps the common case (link a zone → start polling it now) one click instead of two.

Removing a Cloudflare connection — does it delete my zones from Cloudflare?

No. Removing a connection from Astrari deletes our local copy of the zone list, snapshot data, and any Cloudflare-derived findings. It does NOT touch anything inside Cloudflare itself, and it does NOT revoke the API token — for safety, you should revoke the token yourself in dash.cloudflare.com → API Tokens once the connection is gone from our side. Future tokens for the same zones will repopulate cleanly.

Team & account

Can I invite team members to my account?

Yes. Go to Settings → Team members and click '+ Add member'. Enter their name, email address, and a temporary password they can change after logging in. You can assign them one of two roles: • Member — can view and manage sites and servers, run scans, and mark findings. • Admin — full access including settings, team management, and API key rotation. The account owner (ORG_OWNER) cannot be removed. You cannot remove yourself.

How do I remove a team member?

Go to Settings → Team members and click Remove next to the person you want to remove. This immediately revokes their access. The action cannot be undone — if you need to restore their access, re-invite them.

How do API keys work?

API keys let you integrate Astrari findings into your own tools or scripts. Generate a key in Settings → API keys. Each key has the prefix 'iw_live_' followed by a random string. The full key is shown only once at creation — copy it before closing the dialog. After that, only the first 12 characters (the prefix) are stored for identification. Keys can be revoked at any time from the API keys page. API keys are available on Professional and Agency plans.

Can I open an SSH session to a server from the dashboard?

We deliberately don't proxy SSH ourselves — Astrari is monitoring, not access management, and we never want shell on your customers' servers. But if your team already uses Teleport, Tailscale SSH, AWS SSM Session Manager, or any similar tool, you can wire it up so an "Open in…" button appears on each server's detail page. Go to Settings → Remote access link, paste a URL template that uses {hostname} as a placeholder, and pick a button label. We substitute the agent-reported hostname into the template and open the result in a new tab — your access tool handles authentication, MFA, and session recording. Examples: • Teleport: https://teleport.example.com/web/cluster/main/nodes?search={hostname} • Tailscale: https://login.tailscale.com/admin/machines?q={hostname} Leave the field empty to hide the button. The setting is per-organisation and only admins can change it.

Does Astrari work for sites on shared hosting (SiteGround, WP Engine, etc) where I can't install the agent?

Yes — every site-level check works without an agent. Add the site URL, we scan from outside. You get SSL/domain expiry, security headers, cookie flags, SPF/DMARC, blacklist checks, exposed-file detection, SEO-spam/cloaking, WordPress CVE matching, plus uptime monitoring (5-minute probes with alerts on outages), JavaScript supply-chain detection (we flag new external scripts and SRI hash changes, the Magecart attack class), content / defacement monitoring (6-hourly fingerprinting of your key pages with HIGH alerts on unexpected drift), and TLS deep audit (deprecated protocol versions, weak keys/sig algorithms, HSTS posture — Cloudflare and Let's Encrypt aware). The agent is required only for server-level checks (Trivy CVE scanning, ClamAV, rkhunter, MalDet, file integrity, SSH hardening, package patching). If your hosting provider doesn't let you SSH in, you can still get strong site-level coverage and only miss the OS-level controls — which your hosting provider is implicitly responsible for in that arrangement anyway.

How does uptime monitoring work?

Enable it from the Uptime card on any site's detail page. We probe the URL every 5 minutes via HTTPS GET (10-second timeout). Each probe records latency, HTTP status, and any error. Three consecutive failed probes open a HIGH `Site is unreachable` finding that fires through your normal alert channels (email, Slack, Teams, PagerDuty, generic webhook); two consecutive successful probes auto-resolve it. The Uptime card on the site detail page shows: current status pill, last-probe latency, 24-hour uptime percentage, the last failure timestamp + error reason, and a 24-hour hourly sparkline of success ratios. Historical data: raw probes are kept 7 days, then rolled up to 5-minute aggregates for 30 days, then to hourly aggregates indefinitely. If your homepage isn't a meaningful health check (e.g. a static landing page in front of a dynamic backend), you can change the probe path to point at /api/health or similar via the site's PATCH endpoint.

Do PDF reports cover site-only customers properly?

Yes — when a report includes only websites and no servers, the layout adapts. The cover swaps the generic asset/scan stats for `Sites monitored / Portfolio uptime % / Issues found / Issues fixed`. The executive-summary copy is rewritten to lead on monitoring outcomes (uptime probes, content-change fingerprinting, supply-chain detection, TLS audits, subdomain-takeover sweeps, email-security hygiene) rather than scan counts. And every site card carries a `Monitoring at a glance` strip showing six tiles — uptime %, defacement paths monitored, external-script count, discovered subdomains (with any flagged in danger tone), open email-security findings, open TLS findings — colour-coded by health. The rest of the card (findings opened / resolved / currently open) is unchanged. Server-only and mixed reports keep the original layout.

What does the DNSSEC + DMARC strength check do?

The original SITE_EMAIL_SEC checks just looked for record presence — "do you have an SPF record at all? Do you have DMARC?". That misses the most common real-world failure mode, which is having a record that doesn't actually do anything. We now parse the records and flag: • **SPF with a permissive `+all` or `?all` mechanism** — a record that effectively says "accept mail from anywhere claiming to be us". Same end result as no SPF for any sending source not listed before the all-mechanism. • **DMARC with `p=none`** — monitor-only policy. Reports come in but spoofs aren't blocked. Common because orgs ship `p=none` for the rua reporting and never tighten. • **DMARC with `pct=` < 100** — staged-rollout marker that's been forgotten, so only a fraction of forged mail gets the configured action. • **DMARC with no `rua=`** — no aggregate reporting destination, so you're flying blind on policy effectiveness. • **DNSSEC not enabled** — DNS records aren't cryptographically signed. We probe via Cloudflare's DoH AD bit, which validates the chain. Severity is LOW because most domains still don't run DNSSEC, but enabling it is one click on most modern DNS providers and free. These join the existing presence checks (no SPF / no DMARC at all) under the SITE_EMAIL_SEC category. Severity is LOW for the strength findings — these are hardening rather than active compromise — but they tell the customer how to move from "I have a record" to "my email is actually protected".

What is subdomain takeover, and how do you detect it?

Subdomain takeover is when a DNS record on your domain (typically a CNAME) points at a third-party service that's been decommissioned, but the record is still in place. The classic example: `promo.example.com CNAME example-promo-2018.s3.amazonaws.com`. Marketing deletes the S3 bucket two years later, the DNS record stays. An attacker creates a new S3 bucket with that name (free, no auth needed) and now serves arbitrary content under `promo.example.com` — including phishing pages, cookie-scoped exfiltration of session data on the parent domain, OAuth callback hijacking, and a fresh Let's Encrypt cert that browsers fully trust. **How we detect it:** once a week per site, we enumerate your subdomains via Certificate Transparency logs (free, public, passive — no scraping or active recon). For each discovered subdomain we resolve the DNS chain. When a CNAME points at a known-vulnerable service (S3, GitHub Pages, Heroku, Azure, Shopify, Statuspage, Fastly, Webflow, Tumblr, Pantheon, Squarespace, Zendesk, and others), we fetch the URL and check the response body for the service's specific 'this resource doesn't exist' fingerprint (e.g. AWS's `<Code>NoSuchBucket</Code>`). Both the DNS-target match AND the response-fingerprint match are required before we fire a finding — keeps false positives near zero. **Remediation when flagged:** either delete the dangling DNS record (if you don't need the resource) or re-create the third-party resource using the original target name so you own it before someone else does. The Subdomain audit card on each site's Monitoring tab shows everything we found, with takeover-risk subdomains called out in danger tone at the top.

What does the TLS deep audit check?

On every site scan we run a TLS audit beyond the basic cert-expiry check. It probes whether the server still accepts deprecated TLS 1.0 / 1.1 (HIGH finding if so — both deprecated by RFC 8996 in 2020, removed from all major browsers). It inspects the leaf certificate for self-signed status (CRITICAL), weak RSA keys below 2048 bits (HIGH), and deprecated signature algorithms like SHA-1 / MD5 (HIGH). It also checks HSTS posture: missing Strict-Transport-Security header (LOW), max-age below 6 months (LOW). **Cloudflare-fronted sites:** when we detect Cloudflare (via CF-Ray header or cert issuer), the audit measures CF's edge — not your origin. CF Universal SSL is generally well-configured (TLS 1.3, modern ciphers), so the audit passing on a CF site means edge is healthy. Origin posture is covered by the Cloudflare integration's Edge protection panel separately. The audit surfaces the CF detection as informational so you know what was tested. **Let's Encrypt:** 90-day cert validity is by design. We do NOT flag short remaining validity as a TLS finding — the existing SSL-expiry check (under 30 days) handles absolute renewal alerts, and short-by-design LE certs would otherwise generate false alarms on every healthy LE site every couple of months. The audit runs as part of the regular site scan (no separate cron), so findings appear in your normal Findings list under the **TLS** category.

How does content / defacement monitoring work?

Enable it from the Content monitoring card on any site's detail page. We fetch your configured paths every 6 hours (default just `/`, up to 5 paths per site), strip all script/style/meta blocks and known dynamic-noise patterns (CSRF tokens, nonces, cache-bust query strings, ISO timestamps), then SHA-256 the result. The first check captures the agreed-good baseline silently. From the second check onwards, any path whose hash drifts opens a HIGH `Page content changed: /path` finding (category SITE_INTEGRITY) that fires through your normal alert channels. The normalisation strips the dynamic noise that legitimately changes every page-load — so a different ad, a randomised CSRF token, or a CDN cache-buster won't fire. What it does catch: actual content swaps (defacement, malicious banner injection, unauthorised content edits, redirect-injection from a compromised plugin). False positives are still possible on highly-dynamic sites — that's why the Content monitoring card has a one-click `Re-capture baseline` button: when you legitimately change a page, click that and the new content becomes the agreed-good (any open findings auto-resolve). Use `Check now` to trigger an out-of-cycle check after suspicious activity without losing the existing baseline. The card surfaces every monitored path with its current state (matching, drift detected, or capturing) and the time it was last verified.

What is the JavaScript supply-chain (Magecart) check?

Every site scan extracts the full set of external `<script src>` URLs from the homepage along with their Subresource Integrity (SRI) hash if present. The first scan establishes a baseline; from the second scan onwards we fire findings on changes: • A new external script appearing → HIGH finding. This catches Magecart-style supply-chain compromises (attacker injects a tag manager or CDN reference that exfiltrates checkout data), unauthorised analytics injection, or legitimate-but-unannounced scope creep on the site. • SRI hash changing on an existing script → MEDIUM finding. Could be a planned third-party version bump or a sign that something changed without your knowledge. Same-domain scripts are excluded (they're a different risk class, covered by the WordPress + exposure scanners). The Third-party JavaScript card on the site detail page lists every external script we currently observe along with whether it has an SRI hash pinned — scripts loaded without SRI are highlighted because the browser will execute whatever the third-party origin returns, including a future malicious update.

How does performance monitoring work, and how is it different from New Relic / Datadog?

Enable it from the Performance card on any site's detail page. Once a week (Mondays 06:00 UTC) we run a synthetic mobile audit through Google PageSpeed Insights and store four numbers: overall PSI score, Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). No script gets added to your site — the measurement runs in Google's lab against your public URL. There is also a `Check now` button for ad-hoc runs after a deploy. **It is deliberately not a performance dashboard.** We don't draw charts. We don't show percentiles. We don't pretend to be Datadog or New Relic — those are real-user-monitoring (RUM) tools that ingest every visitor's experience and grow expensively with your traffic. We do one thing: tell you when something measurably regressed. The thresholds are simple — score dropped 15+ points vs the previous successful run, or LCP grew over 50% AND is now above 2,500 ms. Either of those opens a SITE_PERFORMANCE finding. **The differentiation:** when we fire a regression alert, we surface what else changed at the same time on the same site — newly-added third-party scripts, TLS cert switched, redirect chains introduced. So you can tell whether the regression is your dev team's deploy or whether it lines up with something less benign (a hacked plugin pulling in tracker bloat, a CDN misroute). Performance becomes a security-and-integrity signal, not just a speed report. The weekly cadence is intentional — daily would burn API quota and produce more noise than signal at this resolution. If you need higher resolution after a specific deploy, the `Check now` button covers it.

How do I enable two-factor authentication on my account?

Go to Settings → Two-factor authentication → click Enable. Astrari shows a QR code; scan it with any TOTP-compatible authenticator (Google Authenticator, 1Password, Authy, Microsoft Authenticator, etc.). Type the 6-digit code your app shows to confirm, and we'll show you 8 single-use backup codes — save these somewhere safe (password manager or printed and locked away). From this point on, every sign-in asks for both your password AND a 6-digit code from your authenticator. Active sessions stay logged in; you'll only be prompted at the next fresh sign-in. 2FA is per-user — each team member enables it on their own account. We don't currently force it organisation-wide, but get in touch if that's useful for your compliance posture.

I lost my phone — how do I get back in?

Use one of your 8 backup codes at the verification prompt. Each code works once and consumes itself; the dashboard will warn you when you're running low. Once you're back in, go to Settings → Two-factor authentication and either disable 2FA (if you don't want it any more) or re-enable it on your new device. If you've lost your authenticator AND all backup codes, contact [email protected] from the email on the account. We'll verify your identity and reset the second factor manually — there's no way to recover it without that human-in-the-loop step (which is the whole point of having a second factor).

Are my 2FA secrets actually secure?

TOTP secrets are AES-256-GCM-encrypted at rest under a dedicated key-encryption-key (`MFA_KEK`) that's separate from the database, separate from the JWT signing key, and separate from any other credential we encrypt. Backup codes are hashed (SHA-256) — we can verify them at login but can't recover them, which is why we show them once and never again. The second factor isn't bypassed by the refresh-token flow either: each Session row carries an `mfaVerified` flag set when you completed the 2FA challenge, and we propagate that forward through token rotation. A stolen refresh token alone can't issue access tokens for an account where 2FA was active at login.

Is there a quick way to jump to WHM, Plesk, or wp-admin from a server or site?

Yes — when we detect cPanel/WHM or Plesk on a server (via the agent's panel detector), the server detail page shows an 'Open WHM' or 'Open Plesk' button next to the remote-access link. It opens the panel's own login page in a new tab — you log in directly with your panel credentials. We don't store panel passwords or mint SSO URLs; this is a bookmark-style shortcut that saves you remembering the port (cPanel/WHM uses 2087, Plesk uses 8443). For WordPress sites, the site detail page has an 'Open wp-admin' button — same idea, opens {site-url}/wp-admin/ in a new tab. You log in with your normal WordPress credentials. If you want true single-sign-on (no second login prompt), that needs us to store credentials, which we've deliberately avoided for blast-radius reasons. Get in touch if it would be valuable for your workflow and we'll look at it as an opt-in integration.

Billing & plans

What are the plans and how much do they cost?

Four plans, each with its own caps: • Starter — Free. 1 site, 1 server, 24h scan schedule, full scan suite, 7-day data retention. • Basic — £25 / €29 / $35 per month. 5 sites, 2 servers, 24h schedule, email alerts, 30-day retention, email support. • Professional — £65 / €75 / $89 per month. 25 sites, 5 servers, 12h schedule, alerts via email/Slack/Teams/PagerDuty/webhook, API keys, 90-day retention, priority email support. • Agency — £149 / €175 / $199 per month. 125 sites, 25 servers, 6h schedule, all integrations, client sub-accounts, per-client API keys, 1-year retention, priority support. All plans include: Linux server monitoring (Trivy, ClamAV, rkhunter, MalDet, SSH hardening, file integrity), site monitoring (SSL, headers, domain/SSL expiry, SPF/DMARC, blacklists, SEO spam), WordPress CVE matching, on-demand scans, forensic diagnostics, and agent auto-updates. Vault — the optional backup add-on — is billed separately on usage: £0.05 per GB stored per month, with a 10 GB/month free egress allowance for restores (£0.02/GB above that). No per-server fee.

What's included in the free Starter plan?

Starter is permanently free — not a trial. 1 monitored site, 1 Linux server with the full scan suite, on-demand scans, forensic diagnostics, 7-day data retention. It's a real plan, not a gimped preview, and you can stay on it forever if it covers your needs.

How does the 14-day trial work?

Sign up for any paid plan and you get 14 days of full access — no credit card required. After 14 days, mutating actions (creating new scans, adding sites/servers, changing alerts) are paused until you choose a plan; existing data and dashboard browsing remain available so you can subscribe at any time. The countdown shows in a banner at the top of every dashboard page from day 7 onwards.

What happens when the trial ends and I haven't subscribed?

Your dashboard becomes read-only — you can still view all your sites, servers, findings, and scan history, but agent-triggered actions and configuration changes are blocked. Click any 'Choose a plan' button to go to billing and subscribe. Your data is preserved indefinitely; once you subscribe, full functionality returns immediately.

Do you offer annual billing?

Yes — annual billing saves 20% compared to monthly. For example, Professional is £65/mo monthly or £624/yr annual (£52/mo equivalent). Switch interval at any time from the Stripe customer portal we link to from your billing page.

Can I pay in EUR or USD?

Yes — you pick your billing currency at checkout (GBP, EUR, or USD). Prices are set per currency rather than direct FX conversion, so what you see on the pricing page is what you pay. The currency is locked for that subscription; to switch currency, cancel and re-subscribe in the new one.

How do I change my plan or cancel?

From your dashboard, go to Settings → Billing. Click 'Manage in Stripe' to change plan, change interval, update payment details, or cancel. Cancellation takes effect at the end of the current billing period. Annual plans are non-refundable after the 14-day trial but can be cancelled to prevent renewal.

What is the client sub-accounts feature on the Agency plan?

Agency plan customers can create separate client sub-accounts. Each client account contains its own sites, servers, findings, and team members — isolated from other clients. Useful for agencies that manage infrastructure for multiple clients and want each client to have their own login (or stay fully managed without one).

Do you offer managed services — actual server work, not just monitoring?

Yes, but separately. Astrari is the monitoring product. Our parent company Incus Technologies (incustech.co.uk) handles the hands-on side: managed Linux server administration, WordPress and bespoke website development, hosting migrations, performance work, and remediation when something on your Astrari dashboard needs an actual human to fix it. Same UK team, separate engagement model. If you'd like a quote or to chat about taking server work off your hands, head to https://www.incustech.co.uk or email [email protected].

Support

How do I get technical help?

Click the 'Get help' button on any server or site detail page (also from the Support page in your dashboard). Fill in a short message describing what you need and submit — your message goes directly to our support team and a confirmation email is sent to you. To follow up just reply to that email; your reply lands in the same support queue. For urgent issues you can email [email protected] directly.

What does support help with?

Interpreting scan findings, planning remediation, agent installation issues, integrating Astrari with Slack/Teams/PagerDuty, configuring alerts, decoding forensic diagnostics, and general security advice for your servers and sites. We won't perform invasive changes on your servers without your authorisation, and we won't access your servers unless you explicitly ask us to.

What's the response time?

Within one business day for non-urgent questions. Urgent active-incident issues are best raised at [email protected] directly with 'URGENT' in the subject — these are triaged ahead of regular requests during UK business hours.

Do I get a 'first scan' welcome email?

Yes. The first time a server or site completes a scan, Astrari emails the org owner a short summary: the security score, finding counts, what happens next, and a link to view findings. It's a one-off — subsequent scans don't send this email. If you want ongoing notifications, configure Alerts (Slack/Teams/PagerDuty/email/webhook).

Still have a question?

We're happy to help.

Contact us