How to Set Up Automated Security Audits on FreeBSD
A verifiable FreeBSD security-update workflow for pkg and base-system auditing, periodic delivery, patch-method detection, staged remediation, and evidence.
Automated vulnerability detection reduces the time between a published advisory and operator awareness. It is not automated security: the database can cover only known issues, delivery can fail, a vulnerable component may not be reachable, and an unlisted local exposure may still be critical. A defensible FreeBSD workflow verifies checks, alerts, update mechanism, remediation, reboot requirements, and final state.
FreeBSD 15 can be installed with base-system packages, while traditional binary installations use freebsd-update and source-tracking systems use Git plus build/install procedures. Determine the host’s actual method before applying commands.
Inventory release, packages, and update mechanism
Capture the installed kernel and userland versions, repository configuration, and base-package presence:
freebsd-version -kru
uname -m
pkg -vv
pkg info -g 'FreeBSD-*'
pkg audit -F
An installed FreeBSD-* package set and enabled FreeBSD-base repository indicate pkgbase management. Absence alone is not enough to authorize freebsd-update; confirm how the machine was installed and whether it uses a custom kernel or source-built world. Record the supported-release status from the FreeBSD Security page. No updater can keep an end-of-life branch secure.
Separate base-system and third-party findings. FreeBSD security advisories cover the base system; the pkg vulnerability database covers software represented as packages and, in current pkg, can also evaluate base-version identifiers. Local applications, firmware, containers, and external dependencies need their own inventories.
Audit installed packages with fresh data
Fetch the current vulnerability database and audit the installed package database:
pkg audit -F
Preserve the exit status and full output in the monitoring system. A quiet command returning nonzero must alert; redirecting all output to /dev/null turns automation into silence. Follow the VuXML link for affected ranges, references, and package origin.
To focus on an installed package named in a finding:
pkg audit package-name
pkg info package-name
Replace the placeholder. Confirm the exact installed version and whether a fixed package exists in the configured Quarterly, Latest, or internal repository. Exploitability affects prioritization, but “the feature is disabled” is not a permanent remediation when configuration can drift.
pkg audit cannot find malware, weak configuration, exposed listeners, or a vulnerability not yet entered in VuXML. Combine it with service inventory, configuration review, vendor advisories for non-Ports software, and incident monitoring.
Configure periodic with current variable names
Periodic configuration belongs in /etc/periodic.conf, not rc.conf; therefore sysrc periodic-daily-security_output=... was both the wrong file and an invalid variable name. Current FreeBSD and pkg security scripts use settings such as:
daily_status_security_enable="YES"
daily_status_security_output="[email protected]"
security_status_pkgaudit_enable="YES"
security_status_baseaudit_enable="YES"
Replace the monitored address. The pkg scripts default to running daily, but defining the intended controls makes policy review clearer. Check the installed /etc/defaults/periodic.conf and /usr/local/etc/periodic/security scripts because available variables follow the installed base and pkg versions.
Do not edit /etc/defaults/periodic.conf; local overrides go in /etc/periodic.conf. If output should go to a file instead of mail, use a dedicated path and configure newsyslog rotation, ownership, capacity, and a separate alert path. A local file nobody reads is not notification.
Run the security scripts manually and test delivery end to end:
periodic security
periodic daily
The first shows security-script output directly; the second exercises the daily wrapper and configured destination. Verify the message reaches the monitored mailbox and triggers an alert for a controlled nonzero test. The nonexistent mailer_check_pending and fabricated /var/log/security/security.YYYYMMDD path from older instructions should not be used.
Check traditional base-system updates safely
For a supported binary installation managed by freebsd-update, fetching downloads and stages metadata or patches but does not install them:
freebsd-update fetch
freebsd-update updatesready
Review advisories and output, create a ZFS boot environment or verified backup, then schedule installation:
freebsd-update install
freebsd-version -kru
The current Handbook documents @daily root freebsd-update cron as a way to download available patches and notify root without applying them. Use it only after mail delivery is proven and disable conflicting update cron jobs before release upgrades.
freebsd-update automatically handles GENERIC kernels, not arbitrary custom kernels. If kernel or modules changed, reboot and confirm the running kernel catches up with installed userland. Restart affected services even when a reboot is unnecessary. Test freebsd-update rollback and console recovery in a nonproduction system before depending on them.
Handle pkgbase and source-managed hosts differently
For a pkgbase installation, follow the exact repository and branch instructions for that release. A minor update uses the named base repository:
pkg update -r FreeBSD-base
pkg upgrade -n -r FreeBSD-base
The dry run is for review. After a boot environment or backup and an approved window, remove -n, reboot when required, and validate freebsd-version -kru. Do not run both pkgbase and legacy base-update workflows against the same installation.
A source-built host must update its source branch and rebuild using the Handbook’s documented sequence, including etcupdate and custom kernels. Automated detection should identify which runbook owns the host rather than guessing.
Stage third-party package remediation
Refresh repository catalogues and preview the complete transaction:
pkg update
pkg upgrade -n
Check /usr/local/etc/pkg/repos, ABI, repository origin, locked packages, deprecations, package messages, configuration changes, and services that will need restart. A fix absent from the configured branch may require a repository-policy decision, not an unsafe manual archive.
During the approved window:
pkg upgrade
pkg audit
Review .pkgnew or other configuration notices, restart affected daemons, and run application-level checks. A successful package transaction does not prove the running process loaded the new library; long-lived services can retain deleted vulnerable objects until restart.
Build an auditable response loop
For every finding, retain discovery time, database timestamp, advisory, affected asset, installed version, exposure assessment, owner, deadline, change record, fixed version, restart or reboot evidence, and final clean audit. Track accepted exceptions with expiry dates instead of suppressing them permanently.
Monitor the monitor: alert when the periodic job stops, the vulnerability database grows stale, email delivery bounces, the host approaches end-of-life, repositories fail, or the last successful audit exceeds its interval. Periodically inject a harmless test notification to prove the whole path.
Automate detection aggressively. Automate installation only where rollback, compatibility tests, service restart, and ownership are equally mature. The target state is not “the command ran”; it is current software, a verified running version, restored service health, and evidence that no known finding remains unexplained.
Related:
- How to Configure Audit(4) for Security Event Logging on FreeBSD
- How to Safely Upgrade FreeBSD Between Major Versions
Sources: