Linux resources
The nine resource types that inspect Linux subsystems.
On this page
These nine resource types read Linux subsystems that have no cross-platform
equivalent. Give a control that uses them platform = ["linux"], so it is
omitted on other targets rather than erroring there.
Most of them are label-only: nothing needs addressing because the check inspects a subsystem as a whole, so the check name is just the report label.
auditd
Label-only. Reads auditctl -l, falling back to the rules files under
/etc/audit/.
| Attribute | Type | Notes |
|---|---|---|
rule |
string, required | Go regex matched against each audit rule line |
present |
bool | Default true |
cron
Label-only.
| Attribute | Type | Notes |
|---|---|---|
pattern |
string, required | Go regex matched against each crontab line |
user |
string | Whose crontab. Empty means the system crontabs, /etc/crontab plus /etc/cron.d/* |
present |
bool | Default true |
mount
Path-addressed at the mount point, read via findmnt.
| Attribute | Type | Notes |
|---|---|---|
path |
string, address | |
mounted |
bool | |
options |
list(string) | All must be present, for example ["noexec", "nosuid"] |
device |
string | Substring against the source device |
fstype |
string | Exact match |
check "tmp-hardening" "mount" {
path = "/tmp"
mounted = true
options = ["noexec", "nosuid", "nodev"]
}firewall
Label-only, conventionally addressed as default. Probes ufw, then firewalld,
then nftables. This is the Linux counterpart to windows_firewall.
| Attribute | Type | Notes |
|---|---|---|
enabled |
bool | Some backend must be active |
backend |
string | ufw, firewalld, nftables. Unset means the first active backend in probe order |
default_incoming |
string | deny, reject, allow. ufw and firewalld only |
default_outgoing |
string | ufw only |
sshd_config
Label-only. Asserts on the effective configuration via sshd -T, so it sees
Include files, Match blocks, and compiled-in defaults. Grepping
sshd_config cannot do that, and it can be fooled by a drop-in or by a
default that was never written down.
| Block | Attribute | Notes |
|---|---|---|
option "<Name>" |
The label is matched case-insensitively | |
value |
Exact effective value, case-insensitive | |
min_value / max_value |
Numeric options such as maxauthtries |
|
contains |
A token in a comma-separated value such as ciphers, macs, kexalgorithms |
Option labels are matched case-insensitively, so option "PermitRootLogin" and
option "permitrootlogin" are the same assertion. The example below uses the
lowercase form because that is how sshd -T prints its keywords, which makes a
check easy to compare against the command’s output by hand. The examples
elsewhere in these docs use the sshd_config(5) spelling, and behave
identically.
check "sshd" "sshd_config" {
option "permitrootlogin" {
value = "no"
}
option "maxauthtries" {
max_value = 4
}
option "ciphers" {
contains = "chacha20-poly1305@openssh.com"
}
}user_db
Label-only. Account database hygiene across /etc/passwd and /etc/shadow as
a whole, complementing the single-account user resource. Failure messages
name the offending accounts.
| Attribute | Type | Notes |
|---|---|---|
no_duplicate_uids |
bool | |
no_uid0_besides_root |
bool | |
no_empty_passwords |
bool | Reads /etc/shadow, so pair it with --sudo |
max_password_age_days |
int | Shadow field 5 |
min_password_age_days |
int | Shadow field 4 |
timesync
Label-only. Uses timedatectl, falling back to chronyc tracking.
| Attribute | Type | Notes |
|---|---|---|
synchronized |
bool | |
service |
string | chrony, systemd-timesyncd, ntpd, mapped onto systemd units |
max_offset_ms |
int | Absolute clock offset bound. Requires chrony, since chronyc tracking is the only portable offset source, and fails with an explanation elsewhere |
mac
Label-only. Mandatory access control status: SELinux via getenforce, AppArmor
via aa-status.
| Attribute | Type | Notes |
|---|---|---|
system |
string | Required. selinux or apparmor. Only that system is probed |
enabled |
bool | The named system is installed and switched on |
enforcing |
bool | SELinux Enforcing, or AppArmor with at least one profile in enforce mode. Permissive and complain-only count as not enforcing |
A check names one system, so the resource never guesses which is in play.
SELinux installed but Disabled reports system: selinux with
enabled: false, separating “switched off” from “not installed”.
To accept either system, put both checks in an any_of group and let the group
decide:
any_of "mac-active" {
check "selinux" "mac" {
system = "selinux"
enabled = true
enforcing = true
}
check "apparmor" "mac" {
system = "apparmor"
enabled = true
}
}boot_params
Label-only. Reads /proc/cmdline, the runtime truth, rather than parsing grub
configuration variants. It therefore reflects what the kernel actually booted
with, including parameters the bootloader injected.
| Attribute | Type |
|---|---|
contains |
list(string) |
not_contains |
list(string) |
Entries match whole parameters. audit=1 matches only the token audit=1,
while a bare audit matches audit or any audit=<value>.