Monitor & abuse-guard internals (code)
The runtime tier of BOA at code level: the cron-driven watchdogs, the abuse-guard ban pipeline, the nightly maintenance sweep, and the trust boundary they all sit on.
The runtime tier of BOA: the scripts that live under /var/xdrago/ on a
deployed box and run on cron, not the installer that put them there. Everything
in this topic is Barracuda-side bash in boa-private (aegir/tools/system/,
mirrored to /var/xdrago/ at build time) plus the one PHP boundary that guards
the backend user — the Drush extension deny-filter in the omega8cc Drush 8
fork.
It is deliberately not the operator's how-to: those pages read live state and cite defaults; these pages are for the maintainer changing the script.
If you touch a monitor/check/*.sh, the ban pipeline, owl.sh / the night/
workers, or boa_extension_filter.inc, this is the execution model your change
lands in.
Two clocks and one privilege boundary organise the whole tier:
- the per-minute clock —
second.sh+minute.sh, each a one-line crontab entry, fan a set ofmonitor/check/*.shwatchdogs out several times a minute; - the nightly clock — one crontab entry (
owl.sh) drives a per-account / per-site maintenance sweep that drops privilege to each tenant's user; - the trust boundary — every one of these runs as root or as
aegir/oN, reads tenant-writable paths and tenant-supplied Drush aliases, and must never let tenant input escalate. The abuse-guard, the path validators and the extension filter all sit on that line.
The deployed tier in one pass
Nothing here is loaded from the build tree at runtime. _xdrago_install_upgrade()
(lib/functions/system.sh.inc:9152) cp -afs the entire
aegir/tools/system/* tree into /var/xdrago/ and installs
cron/crontabs/root into /var/spool/cron/crontabs/root (system.sh.inc:9179,
:9203, :9240) — so on a box every path below is /var/xdrago/..., and the
crontab is the single source of truth for what runs when.
/var/spool/cron/crontabs/root (from aegir/tools/system/cron/crontabs/root)
│
├─ * * * * * second.sh ──▶ _proc_control fan-out (12 watchdogs) [1 deploy surfaces]
│ └▶ hackcheck.sh · hackftp.sh · escapecheck.sh (SSH/FTP IDS)
├─ * * * * * minute.sh ──▶ _launch_auto_healing × _ITER passes:
│ system unbound valkey|redis mysql php
│ fpm_tune nginx nginx_guard java
│ │
│ └▶ nginx_guard.sh ──▶ scan_nginx.sh [2 abuse-guard]
├─ * * * * * guest-fire.sh web.log ─▶ csf -td 900 [2 ban pipeline]
├─ 01 5 … guest-water.sh archive ─▶ csf.deny (_NR_TEST ≥12/≥24) [2 ban pipeline]
├─ */2 … ip_access.sh · user_admin_access.sh · ai_policy.sh ·
│ nginx_deny.sh · nginx_deny6.sh [2 / 4]
├─ */3 … manage_ltd_users.sh (per-user FPM pool, jailed shells) [4 security model]
├─ * * * * * runner.sh (Aegir task queue drain)
└─ 15 4 … owl.sh ──▶ night/night.inc.sh + 90-global-post.sh [3 nightly worker]
└▶ per account: night/10-account.sh ──▶ night/20-sites.sh
(su -s /bin/bash - <HM_U> → drush8 @<site>) [3 / 4]
- [1] Deploy surfaces.
second.shandminute.share the fan-out engines.minute.shclassifies the box (_monitor_box_class→CI/SLOW/NORMAL) and loops_launch_auto_healing_ITERtimes spaced_SLEEPseconds apart (defaultNORMAL= 9×5 s,minute.sh);second.shruns_proc_control, the twelve service watchdogs split out of the legacyproc_num_ctrl.pl, plus the SSH/FTP IDS scanners. There are 27monitor/check/*.shon disk; only the dispatched subset actually runs each tick. - [2] Abuse-guard.
nginx_guard.sh→scan_nginx.shis the web IDS; the detection→ban→enforce pipeline (scan_nginx→web.log→guest-fire.sh→guest-water.sh→nginx_deny.sh→ the$is_bannedgeo) is the same mechanism the operator guide documents, re-read here at code level: the run model, the detector functions and the escalation arithmetic. - [3] Nightly worker.
owl.shis a single-threaded (optionally_NIGHT_PARALLEL) orchestrator that sourcesnight/night.inc.sh(the shared Tier-0 helper library) andnight/90-global-post.sh, then invokesnight/10-account.shas a subprocess per/data/disk/*account, which in turn drivesnight/20-sites.shper site. The split exists so one copy of the drush8 wrappers andchattrhelpers is shared, not duplicated. - [4] Security model. The cross-cutting boundary: the anti-lockout allow
logic in
ip_access.sh, the_validate_safe_dirpath gate the night workers run before any tenant-derivedchown/chmod, the per-user FPMdisable_functionsinjection inmanage_ltd_users.sh, thechattr +iimmutability locks, and the one PHP boundary —boa_extension_filter.inc, which stops tenant-dropped*.drush.incfrom auto-loading as a privileged backend identity.
Each leaf below zooms into one of these boxes.
Adjacent developing topics
- Install & staged-setup internals — how
aegir/tools/system/*and the crontab get onto a box: the stagedAegirSetup*engine and the_xdrago_install_upgrade()path insystem.sh.incthat this topic's deploy surfaces assume already ran. - Web & search stack internals — the Provision
Nginx templates (
server.tpl.phpedge maps,vhost_include.tpl.phpguard chain) that emit the444s andaccess.loglinesscan_nginxscores, and the$is_bannedgeo the ban pipeline feeds back into. - Ægir backend APIs — the Drush 8 fork whose
preflight.incloads the extension filter, and the Provision/Hosting backend the nightlydrush8 @<site>calls drive. - Build & test — verifying a change to any of these scripts:
a rebuild is the only path that re-runs
_xdrago_install_upgradeand lands the edit on a box.
Reference
- Variables and
Commands — the consolidated
_VARand CLI tables, including the_NGINX_*abuse-guard knobs,_MONITOR_FANOUT_*,_NIGHT_*,_INCIDENT_REPORT,_PHP_FPM_DENYand thecsfverbs cited throughout this topic. - Discontinued features — retired monitor scripts and
superseded ban/escalation mechanics land there; check it before documenting
anything found only in old trees,
CHANGELOG.txthistory, or the legacydocs/ctrl/*.ctrlreference files (several of those markers — e.g..no.sql.cpu.limit.cnf,.ip.protected.vhost.whitelist.cnf— have zero live readers and must not be presented as current).
Monitor deploy surfaces & registration
How a monitor reaches a box and runs: the wholesale copy, the launcher that spawns it, the serial-gated per-file fetch, base-package deps, and the box-class fan-out throttle.
Abuse Guard code internals
The maintainer's view of the Abuse Guard scorer: the detector skeleton, incremental log reading, cross-run window state, realip resolution, and how a new detector plugs in.
Nightly worker architecture (owl.sh + night/)
The nightly maintenance sweep at code level: an orchestrator, a per-account and per-site worker family, and the run-freeze that carries state across the subprocess boundary.
Security model internals
The code contracts that keep BOA tenants isolated: the euid trust boundary, the Drush extension filter, the safe path and identifier helpers, and shell-out escaping discipline.