linux

package
v1.19.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package linux holds the Linux check implementations.

Each check operates on the "linux.host" Resources emitted by the linux collector (internal/collectors/linux). Helper functions live here for resource attribute extraction common across many checks.

Per v0.2 ROADMAP §9, the Linux check set targets CIS Ubuntu / Debian directives weighted for "what actually matters in 2026". v0.2 ships 15 checks total; this file holds the five sshd hardening checks.

Index

Constants

View Source
const LoginGraceTimeCeilingSeconds = 60

LoginGraceTimeCeilingSeconds is the maximum LoginGraceTime in seconds. Lower values frustrate online brute-force by tying up fewer connection slots.

View Source
const MaxAuthTriesCeiling = 4

MaxAuthTriesCeiling is the highest value at which MaxAuthTries remains compliant. Operators routinely lower it further; 4 is the CIS-recommended ceiling.

Variables

View Source
var CheckASLREnabled = compliancekit.Check{
	ID:           "linux-aslr-enabled",
	Title:        "Address Space Layout Randomization must be fully enabled",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "kernel",
	ResourceType: linuxcol.HostType,
	Description: "ASLR randomizes the address space of running " +
		"processes, raising the cost of memory-corruption exploits. " +
		"kernel.randomize_va_space=2 is the full-strength setting " +
		"(stack + heap + brk + vdso + mmap). 0 disables; 1 is a " +
		"weakened subset. CIS Ubuntu 3.2.1.",
	Remediation: "sysctl -w kernel.randomize_va_space=2 (runtime) and " +
		"add the line to /etc/sysctl.conf or a drop-in under " +
		"/etc/sysctl.d/ for persistence.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.6"},
		"iso27001": {"A.8.8"},
		"cis-v8":   {"4.1"},
	},
	Tags:    []string{"kernel", "exploit-mitigation"},
	Scanner: "kernel.ASLREnabled",
}

CheckASLREnabled requires kernel.randomize_va_space=2.

View Source
var CheckAppArmorActive = compliancekit.Check{
	ID:           "linux-mac-apparmor-active",
	Title:        "AppArmor must be active on Debian-family hosts",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "mac",
	ResourceType: docol.HostType,
	Description: "AppArmor is the Debian/Ubuntu MAC layer. Active = kernel module loaded " +
		"AND at least one profile loaded. CIS Linux Server v8 §1.7.2.",
	Remediation: "sudo apt-get install -y apparmor apparmor-utils\nsudo systemctl enable --now apparmor\nsudo aa-enforce /etc/apparmor.d/*",
	Frameworks: map[string][]string{
		"soc2":             {"CC6.6"},
		"iso27001":         {"A.8.7"},
		"cis-v8":           {"1.7.2"},
		"cis-linux-server": {"1.7.2"},
	},
	Tags:    []string{"mac", "apparmor"},
	Scanner: "linux.mac.AppArmorActive",
}
View Source
var CheckAuditdRunning = compliancekit.Check{
	ID:           "linux-auditd-running",
	Title:        "auditd must be running",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "audit",
	ResourceType: linuxcol.HostType,
	Description: "auditd captures syscall-level audit events that " +
		"satisfy 'log access to sensitive systems' controls. Without " +
		"it, evidence for SOC 2 CC7.2, ISO 27001 A.8.15, and CIS " +
		"Controls v8 8.5 is hard to produce.",
	Remediation: "Install and enable auditd: " +
		"'sudo apt install auditd && sudo systemctl enable --now auditd' " +
		"(Debian/Ubuntu) or the equivalent on your distro.",
	Frameworks: map[string][]string{
		"soc2":     {"CC7.2", "CC7.3"},
		"iso27001": {"A.8.15"},
		"cis-v8":   {"8.5"},
	},
	Tags:    []string{"audit", "logging"},
	Scanner: "audit.AuditdRunning",
}

CheckAuditdRunning requires auditd to be active.

View Source
var CheckDistroSupported = compliancekit.Check{
	ID:           "linux-distro-supported",
	Title:        "/etc/os-release ID must be on the supported-distro allowlist",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "distro",
	ResourceType: docol.HostType,
	Description: "v0.20 introduces per-distro behavior in many Linux checks " +
		"(package manager, init system, sysctl key names). The collector " +
		"reads /etc/os-release at the top of every gather pass; if the " +
		"ID isn't on the allowlist (debian, ubuntu, rhel, centos, rocky, " +
		"almalinux, fedora, alpine, amzn) downstream checks fall through " +
		"to generic defaults that may misclassify findings. Pin the host " +
		"to a supported distro OR open a tracking issue to extend the " +
		"allowlist.",
	Remediation: "Either migrate the workload to a supported distro " +
		"(Ubuntu LTS / Debian Stable / RHEL family / Alpine / Amazon " +
		"Linux 2 or 2023), or open an issue at " +
		"https://github.com/darpanzope/compliancekit/issues with the " +
		"target distro + /etc/os-release contents so it can be added to " +
		"`supportedDistros` in `internal/checks/linux/distro.go`.",
	Frameworks: map[string][]string{
		"soc2":     {"CC7.1"},
		"iso27001": {"A.8.8"},
		"cis-v8":   {"7.3"},
	},
	Tags:    []string{"distro", "platform"},
	Scanner: "linux.distro.Supported",
}
View Source
var CheckEncryptMethod = compliancekit.Check{
	ID:           "linux-login-defs-encrypt-method",
	Title:        "/etc/login.defs ENCRYPT_METHOD must be SHA512 or YESCRYPT",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "auth",
	ResourceType: docol.HostType,
	Description: "ENCRYPT_METHOD controls the hash algorithm used to store new " +
		"user passwords in /etc/shadow. SHA512 + YESCRYPT are the only " +
		"acceptable choices in 2026 (DES + MD5 are trivially crackable; " +
		"SHA256 is acceptable but SHA512 is the explicit CIS pick). " +
		"CIS Linux Server v8 §5.5.1.4.",
	Remediation: "/etc/login.defs:\n  ENCRYPT_METHOD YESCRYPT   # or SHA512\nRehash existing accounts on next password change.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.7"},
		"iso27001": {"A.8.24"},
		"cis-v8":   {"5.5.1.4"},
	},
	Tags:    []string{"auth", "password-hashing"},
	Scanner: "linux.login.EncryptMethod",
}
View Source
var CheckFirewallActive = compliancekit.Check{
	ID:           "linux-firewall-active",
	Title:        "A host firewall must be active",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "firewall",
	ResourceType: linuxcol.HostType,
	Description: "A host with no active firewall accepts every packet " +
		"its NIC sees. ufw and nftables are the two modern Linux " +
		"options; this check passes when either reports an active " +
		"state. SOC 2 CC6.6, ISO 27001 A.8.20, and CIS Controls v8 " +
		"4.4 all require network access controls on production hosts.",
	Remediation: "Enable ufw ('sudo ufw enable' on Debian/Ubuntu) or " +
		"nftables ('sudo systemctl enable --now nftables'). Verify " +
		"with 'sudo ufw status' or 'sudo nft list ruleset'.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.6", "CC6.1"},
		"iso27001": {"A.8.20"},
		"cis-v8":   {"4.4", "12.2"},
	},
	Tags:    []string{"firewall", "network"},
	Scanner: "firewall.Active",
}

CheckFirewallActive requires ufw or nftables to be active.

View Source
var CheckFirewallDefaultDeny = compliancekit.Check{
	ID:           "linux-firewall-default-deny",
	Title:        "Firewall default-incoming policy must be deny",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "firewall",
	ResourceType: linuxcol.HostType,
	Description: "An active firewall whose default policy is allow is " +
		"only slightly safer than no firewall at all -- every port " +
		"without an explicit deny rule is reachable. Default-deny " +
		"with explicit allows is the only defensible posture. SOC 2 " +
		"CC6.6, ISO 27001 A.8.20, and CIS Controls v8 4.4 require this.",
	Remediation: "On ufw: 'sudo ufw default deny incoming'. On nftables, " +
		"set the inet filter input chain policy to drop.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.6", "CC6.1"},
		"iso27001": {"A.8.20"},
		"cis-v8":   {"4.4", "12.2"},
	},
	Tags:    []string{"firewall", "network", "default-policy"},
	Scanner: "firewall.DefaultDeny",
}

CheckFirewallDefaultDeny requires ufw's default-incoming policy to be "deny". This is a ufw-specific check; nftables-only hosts are Skipped because the equivalent assertion requires parsing nft rules.

View Source
var CheckFirewallNFTablesOnRHEL = compliancekit.Check{
	ID:           "linux-firewall-nftables-on-rhel",
	Title:        "RHEL-family hosts should run nftables (modern replacement for iptables)",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "firewall",
	ResourceType: docol.HostType,
	Description: "nftables is the upstream replacement for iptables; RHEL 8+ ships with " +
		"firewalld backed by nftables. Hosts in the RHEL family running iptables-only " +
		"miss the cleaner rule grammar + atomic rule replacement. Debian/Ubuntu still " +
		"defaults to ufw — this check skips there.",
	Remediation: "sudo systemctl enable --now nftables\nMigrate iptables rules via `iptables-restore-translate -f /etc/sysconfig/iptables`.",
	Frameworks: map[string][]string{
		"soc2":             {"CC6.6"},
		"iso27001":         {"A.8.20"},
		"cis-v8":           {"3.4.2"},
		"cis-linux-server": {"3.4.2"},
	},
	Tags:    []string{"firewall", "nftables", "rhel"},
	Scanner: "linux.firewall.NFTablesOnRHEL",
}
View Source
var CheckFirewallSomeActive = compliancekit.Check{
	ID:           "linux-firewall-some-active",
	Title:        "Some firewall must be active (ufw, nftables, or firewalld)",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "firewall",
	ResourceType: docol.HostType,
	Description: "A host with NO active firewall trusts the upstream cloud provider's " +
		"security groups entirely. Defense in depth wants both — at minimum a nftables " +
		"default-deny INPUT table on RHEL-family or ufw active on Debian-family.",
	Remediation: "Debian/Ubuntu: sudo ufw enable\nRHEL family: sudo systemctl enable --now nftables firewalld",
	Frameworks: map[string][]string{
		"soc2":             {"CC6.6"},
		"iso27001":         {"A.8.20"},
		"cis-v8":           {"3.4.1"},
		"cis-linux-server": {"3.4.1"},
	},
	Tags:    []string{"firewall", "must-active"},
	Scanner: "linux.firewall.SomeActive",
}
View Source
var CheckFirewallUFWDefaultDenyOutgoing = compliancekit.Check{
	ID:           "linux-firewall-ufw-default-deny-outgoing",
	Title:        "ufw default policy: outgoing must be deny on egress-controlled hosts",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "firewall",
	ResourceType: docol.HostType,
	Description: "Default-deny egress is the modern way to constrain a compromised process " +
		"from beacons / data-exfil. CIS Linux Server v8 §3.4.2.1 recommends explicit " +
		"egress allow-lists with default deny. Waive on hosts that need broad outbound " +
		"access (build runners, package mirrors).",
	Remediation: "sudo ufw default deny outgoing\n" +
		"sudo ufw allow out 443/tcp comment 'HTTPS'\n" +
		"sudo ufw allow out 53      comment 'DNS'\n" +
		"sudo ufw reload",
	Frameworks: map[string][]string{
		"soc2":             {"CC6.6"},
		"iso27001":         {"A.8.20"},
		"cis-v8":           {"3.4.2.1"},
		"cis-linux-server": {"3.4.2.1"},
	},
	Tags:    []string{"firewall", "ufw", "egress"},
	Scanner: "linux.firewall.UFWDefaultDenyOutgoing",
}
View Source
var CheckJournaldPersistent = compliancekit.Check{
	ID:           "linux-journald-persistent",
	Title:        "journald must use persistent storage",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "audit",
	ResourceType: linuxcol.HostType,
	Description: "systemd's journald default ('auto') writes to disk " +
		"only if /var/log/journal exists, and falls back to a " +
		"volatile ramdisk otherwise. A reboot wipes the latter and " +
		"breaks the audit trail. Setting Storage=persistent forces " +
		"disk storage and creates the directory if missing.",
	Remediation: "Set 'Storage=persistent' in /etc/systemd/journald.conf " +
		"and 'systemctl restart systemd-journald'. Confirm with " +
		"'journalctl --header | head'.",
	Frameworks: map[string][]string{
		"soc2":     {"CC7.2"},
		"iso27001": {"A.8.15"},
		"cis-v8":   {"8.5", "8.10"},
	},
	Tags:    []string{"audit", "logging", "journald"},
	Scanner: "audit.JournaldPersistent",
}

CheckJournaldPersistent requires journald Storage=persistent so logs survive reboots and produce auditor-acceptable evidence.

View Source
var CheckNoEmptyPasswords = compliancekit.Check{
	ID:           "linux-no-empty-passwords",
	Title:        "No account may have an empty password",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "users",
	ResourceType: linuxcol.HostType,
	Description: "An account whose /etc/shadow password field is " +
		"literally empty can be logged in to with any password (or " +
		"no password, depending on PAM config). CIS Ubuntu 7.2.4 " +
		"requires that no entry have an empty hash; locked accounts " +
		"use '!' or '*' instead.",
	Remediation: "passwd -l <user> to lock the account, or set a " +
		"strong password.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.5"},
		"cis-v8":   {"5.2"},
	},
	Tags:    []string{"users", "passwords"},
	Scanner: "users.NoEmptyPasswords",
}

CheckNoEmptyPasswords requires no /etc/shadow entry to have an empty password hash field.

View Source
var CheckNoSourceRouting = compliancekit.Check{
	ID:           "linux-no-source-routing",
	Title:        "Kernel must not accept source-routed packets",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "kernel",
	ResourceType: linuxcol.HostType,
	Description: "Source-routed packets let a sender dictate the path " +
		"taken across the network, defeating egress filtering and " +
		"enabling spoofing. Modern Linux defaults to 0 (drop); this " +
		"check confirms the default has not been overridden. " +
		"CIS Ubuntu 3.3.1.",
	Remediation: "sysctl -w net.ipv4.conf.all.accept_source_route=0 " +
		"and persist via /etc/sysctl.d/.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.6"},
		"iso27001": {"A.8.20"},
		"cis-v8":   {"12.2"},
	},
	Tags:    []string{"kernel", "network"},
	Scanner: "kernel.NoSourceRouting",
}

CheckNoSourceRouting requires net.ipv4.conf.all.accept_source_route=0.

View Source
var CheckPassMaxDays = compliancekit.Check{
	ID:           "linux-login-defs-pass-max-days",
	Title:        "/etc/login.defs PASS_MAX_DAYS must be ≤ 365",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "auth",
	ResourceType: docol.HostType,
	Description: "PASS_MAX_DAYS bounds the maximum password lifetime for accounts " +
		"created from /etc/login.defs defaults. CIS Linux Server v8 §5.5.1.1 " +
		"requires ≤365 (NIST 800-63B aligned). Existing accounts may need " +
		"`chage --maxdays` separately.",
	Remediation: "Edit /etc/login.defs:\n  PASS_MAX_DAYS   365\nApply to existing users:\n  awk -F: '($3>=1000 && $3<60000) {print $1}' /etc/passwd | xargs -I{} chage --maxdays 365 {}",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.5.17"},
		"cis-v8":   {"5.5.1.1"},
	},
	Tags:    []string{"auth", "password-age"},
	Scanner: "linux.login.PassMaxDays",
}
View Source
var CheckPassMinDays = compliancekit.Check{
	ID:           "linux-login-defs-pass-min-days",
	Title:        "/etc/login.defs PASS_MIN_DAYS must be ≥ 1",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "auth",
	ResourceType: docol.HostType,
	Description: "PASS_MIN_DAYS prevents a user from cycling through their password " +
		"history in a single sitting (defeats reuse-prevention). CIS §5.5.1.2 requires ≥1.",
	Remediation: "/etc/login.defs:\n  PASS_MIN_DAYS   1",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.5.17"},
		"cis-v8":   {"5.5.1.2"},
	},
	Tags:    []string{"auth", "password-age"},
	Scanner: "linux.login.PassMinDays",
}
View Source
var CheckPassWarnAge = compliancekit.Check{
	ID:           "linux-login-defs-pass-warn-age",
	Title:        "/etc/login.defs PASS_WARN_AGE must be ≥ 7",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "auth",
	ResourceType: docol.HostType,
	Description: "PASS_WARN_AGE controls how many days ahead of expiry the user " +
		"sees a warning at login. ≥7 days gives the user a meaningful chance " +
		"to rotate before being locked out. CIS §5.5.1.3.",
	Remediation: "/etc/login.defs:\n  PASS_WARN_AGE   7",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.5.17"},
		"cis-v8":   {"5.5.1.3"},
	},
	Tags:    []string{"auth", "password-age"},
	Scanner: "linux.login.PassWarnAge",
}
View Source
var CheckPasswdPerms = compliancekit.Check{
	ID:           "linux-passwd-perms",
	Title:        "/etc/passwd must be 0644 or stricter",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "filesystem",
	ResourceType: linuxcol.HostType,
	Description: "/etc/passwd must be world-readable (login commands " +
		"need it) but must not be writable by anyone but root. CIS " +
		"Ubuntu 7.1.2 prescribes mode 0644 exactly; we accept 0644 " +
		"or stricter (0640, 0600).",
	Remediation: "chmod 0644 /etc/passwd && chown root:root /etc/passwd.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.3"},
		"cis-v8":   {"3.3"},
	},
	Tags:    []string{"filesystem", "passwd"},
	Scanner: "filesystem.PasswdPerms",
}

CheckPasswdPerms requires /etc/passwd to be mode 0644 or stricter.

View Source
var CheckSELinuxEnforcing = compliancekit.Check{
	ID:           "linux-mac-selinux-enforcing",
	Title:        "SELinux must be enforcing on RHEL-family hosts",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "mac",
	ResourceType: docol.HostType,
	Description: "SELinux 'enforcing' is the production posture — 'permissive' logs " +
		"violations without blocking them (useful only during policy tuning); " +
		"'disabled' removes the MAC layer entirely. CIS Linux Server v8 §1.7.1.4 " +
		"requires enforcing on RHEL-family hosts.",
	Remediation: "sudo setenforce 1                # live\nsudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config   # persist",
	Frameworks: map[string][]string{
		"soc2":             {"CC6.6"},
		"iso27001":         {"A.8.7"},
		"cis-v8":           {"1.7.1.4"},
		"cis-linux-server": {"1.7.1.4"},
	},
	Tags:    []string{"mac", "selinux"},
	Scanner: "linux.mac.SELinuxEnforcing",
}
View Source
var CheckSSHDLoginGraceTime = compliancekit.Check{
	ID:           "linux-sshd-login-grace-time",
	Title:        "SSH LoginGraceTime should be 60 seconds or less",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "sshd",
	ResourceType: linuxcol.HostType,
	Description: "LoginGraceTime is the window between connection " +
		"and authentication completion. A long window lets a misbehaving " +
		"client (or attacker) hold a connection slot open, enabling " +
		"slowloris-style resource exhaustion. OpenSSH default is 2 " +
		"minutes; CIS recommends 60 seconds or less.",
	Remediation: "Set 'LoginGraceTime 60' in /etc/ssh/sshd_config and " +
		"reload sshd.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.20", "A.8.21"},
		"cis-v8":   {"5.2", "8.5"},
	},
	Tags:    []string{"sshd", "resource-exhaustion"},
	Scanner: "sshd.LoginGraceTime",
}

CheckSSHDLoginGraceTime flags LoginGraceTime > 60s.

View Source
var CheckSSHDMaxAuthTries = compliancekit.Check{
	ID:           "linux-sshd-max-auth-tries",
	Title:        "SSH MaxAuthTries should be 4 or less",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "sshd",
	ResourceType: linuxcol.HostType,
	Description: "MaxAuthTries caps the number of authentication " +
		"attempts per connection; a low value frustrates online " +
		"brute-force. The OpenSSH default is 6; CIS Controls v8 " +
		"recommends 4 or less.",
	Remediation: "Set 'MaxAuthTries 4' (or lower) in /etc/ssh/sshd_config " +
		"and reload sshd.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.21"},
		"cis-v8":   {"5.2"},
	},
	Tags:    []string{"sshd", "brute-force"},
	Scanner: "sshd.MaxAuthTries",
}

CheckSSHDMaxAuthTries flags MaxAuthTries > MaxAuthTriesCeiling.

View Source
var CheckSSHDNoPasswordAuth = compliancekit.Check{
	ID:           "linux-sshd-no-password-auth",
	Title:        "SSH must not accept password authentication",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "sshd",
	ResourceType: linuxcol.HostType,
	Description: "Password authentication exposes SSH to credential " +
		"stuffing and online brute-force. Public-key authentication " +
		"is the modern baseline. SOC 2 CC6.1 and CIS Controls v8 5.2 " +
		"both require strong authentication for remote administrative " +
		"access.",
	Remediation: "Set 'PasswordAuthentication no' in /etc/ssh/sshd_config " +
		"(and confirm operators have working public-key access first to " +
		"avoid lockout). Reload sshd to apply.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1", "CC6.6"},
		"iso27001": {"A.8.5", "A.8.21"},
		"cis-v8":   {"5.2", "6.5"},
	},
	Tags:    []string{"sshd", "authentication"},
	Scanner: "sshd.NoPasswordAuth",
}

CheckSSHDNoPasswordAuth requires PasswordAuthentication=no.

View Source
var CheckSSHDNoRootLogin = compliancekit.Check{
	ID:           "linux-sshd-no-root-login",
	Title:        "SSH must not permit root login",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "sshd",
	ResourceType: linuxcol.HostType,
	Description: "Direct root SSH logins bypass per-user auditability " +
		"and remove the speed bump that catches automated brute-force. " +
		"SOC 2 CC6.1 / CC6.6, ISO 27001 A.8.21, and CIS Controls v8 " +
		"5.4 all require unique attribution for privileged access.",
	Remediation: "Set 'PermitRootLogin no' in /etc/ssh/sshd_config and " +
		"reload sshd (systemctl reload sshd). Operators should use a " +
		"named user + sudo instead.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1", "CC6.6"},
		"iso27001": {"A.8.21"},
		"cis-v8":   {"5.4"},
	},
	Tags:    []string{"sshd", "access-control"},
	Scanner: "sshd.NoRootLogin",
}

CheckSSHDNoRootLogin requires PermitRootLogin=no.

View Source
var CheckSSHDProtocol2 = compliancekit.Check{
	ID:           "linux-sshd-protocol-2",
	Title:        "SSH must use protocol version 2 only",
	Severity:     compliancekit.SeverityLow,
	Provider:     "linux",
	Service:      "sshd",
	ResourceType: linuxcol.HostType,
	Description: "SSH-1 was retired in 2017 and is cryptographically " +
		"broken. Modern OpenSSH defaults to Protocol 2 and refuses to " +
		"build SSH-1 without explicit flags; this check confirms the " +
		"observed config has not been weakened. Mostly an audit-trail " +
		"check at this point.",
	Remediation: "Remove any 'Protocol 1' line from /etc/ssh/sshd_config " +
		"(or set 'Protocol 2' explicitly). Reload sshd to apply.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.20"},
		"cis-v8":   {"3.10"},
	},
	Tags:    []string{"sshd", "crypto"},
	Scanner: "sshd.Protocol2",
}

CheckSSHDProtocol2 requires Protocol 2 (SSH-1 is ancient and broken).

View Source
var CheckShadowPerms = compliancekit.Check{
	ID:           "linux-shadow-perms",
	Title:        "/etc/shadow must be 0640 root:shadow",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "filesystem",
	ResourceType: linuxcol.HostType,
	Description: "/etc/shadow holds the password hashes for every local " +
		"account. Read access for non-root, non-shadow users enables " +
		"offline cracking and is the textbook CIS Ubuntu 7.1.3 finding. " +
		"Correct ownership is root:shadow with mode 0640.",
	Remediation: "chmod 0640 /etc/shadow && chown root:shadow /etc/shadow.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.3"},
		"cis-v8":   {"3.3", "5.1"},
	},
	Tags:    []string{"filesystem", "shadow"},
	Scanner: "filesystem.ShadowPerms",
}

CheckShadowPerms requires /etc/shadow to be mode 0640 and owned root:shadow (CIS Ubuntu 22.04 benchmark 7.1.3).

View Source
var CheckUIDZeroOnlyRoot = compliancekit.Check{
	ID:           "linux-uid-zero-only-root",
	Title:        "Only the root account may have UID 0",
	Severity:     compliancekit.SeverityHigh,
	Provider:     "linux",
	Service:      "users",
	ResourceType: linuxcol.HostType,
	Description: "A second account with UID 0 is a stealth backdoor: " +
		"sudo / auditd see the username but every privilege check " +
		"resolves to root. CIS Ubuntu 5.4.3 requires that only the " +
		"literal 'root' user holds UID 0.",
	Remediation: "userdel <hidden-root-account> or change its UID to a " +
		"non-zero value with usermod -u <uid> <name>.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1", "CC6.6"},
		"iso27001": {"A.8.2"},
		"cis-v8":   {"5.4", "6.8"},
	},
	Tags:    []string{"users", "privilege"},
	Scanner: "users.UIDZeroOnlyRoot",
}

CheckUIDZeroOnlyRoot requires that only the "root" account has UID 0.

View Source
var CheckUmask = compliancekit.Check{
	ID:           "linux-login-defs-umask",
	Title:        "/etc/login.defs UMASK must be 027 or stricter",
	Severity:     compliancekit.SeverityMedium,
	Provider:     "linux",
	Service:      "auth",
	ResourceType: docol.HostType,
	Description: "Default UMASK 022 (group + world readable) is too permissive for " +
		"shared / multi-tenant systems. 027 (no group write, no world access) " +
		"is the CIS Linux Server v8 §5.5.5 recommendation.",
	Remediation: "/etc/login.defs:\n  UMASK   027\nAlso check /etc/profile.d/*.sh + /etc/bashrc for shell-level overrides.",
	Frameworks: map[string][]string{
		"soc2":     {"CC6.1"},
		"iso27001": {"A.8.7"},
		"cis-v8":   {"5.5.5"},
	},
	Tags:    []string{"auth", "umask"},
	Scanner: "linux.login.Umask",
}

Functions

func ASLREnabled

ASLREnabled is the CheckFunc for CheckASLREnabled.

func AppArmorActive added in v0.20.0

func AuditdRunning

AuditdRunning is the CheckFunc for CheckAuditdRunning.

func DistroSupported added in v0.20.0

func EncryptMethod added in v0.20.0

func FirewallActive

FirewallActive is the CheckFunc for CheckFirewallActive.

func FirewallDefaultDeny

func FirewallDefaultDeny(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

FirewallDefaultDeny is the CheckFunc for CheckFirewallDefaultDeny.

Behavior:

  • host unreachable / firewall probe failed -> Skip
  • ufw active and default_incoming == "deny" -> Pass
  • ufw active and default_incoming == anything else -> Fail
  • nftables active but no ufw -> Skip (we don't parse nft rules yet)
  • neither active -> Fail (covered better by FirewallActive, but this check also fires for completeness)

func FirewallNFTablesOnRHEL added in v0.20.0

func FirewallNFTablesOnRHEL(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

func FirewallSomeActive added in v0.20.0

func FirewallSomeActive(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

func FirewallUFWDefaultDenyOutgoing added in v0.20.0

func FirewallUFWDefaultDenyOutgoing(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

func JournaldPersistent

func JournaldPersistent(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

JournaldPersistent is the CheckFunc for CheckJournaldPersistent.

func NoEmptyPasswords

NoEmptyPasswords is the CheckFunc for CheckNoEmptyPasswords.

func NoSourceRouting

NoSourceRouting is the CheckFunc for CheckNoSourceRouting.

func PassMaxDays added in v0.20.0

func PassMinDays added in v0.20.0

func PassWarnAge added in v0.20.0

func PasswdPerms

PasswdPerms is the CheckFunc for CheckPasswdPerms.

func SELinuxEnforcing added in v0.20.0

func SSHDLoginGraceTime

func SSHDLoginGraceTime(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

SSHDLoginGraceTime is the CheckFunc for CheckSSHDLoginGraceTime.

func SSHDMaxAuthTries

SSHDMaxAuthTries is the CheckFunc for CheckSSHDMaxAuthTries.

func SSHDNoPasswordAuth

func SSHDNoPasswordAuth(_ context.Context, g *compliancekit.ResourceGraph) ([]compliancekit.Finding, error)

SSHDNoPasswordAuth is the CheckFunc for CheckSSHDNoPasswordAuth.

func SSHDNoRootLogin

SSHDNoRootLogin is the CheckFunc for CheckSSHDNoRootLogin.

func SSHDProtocol2

SSHDProtocol2 is the CheckFunc for CheckSSHDProtocol2.

func ShadowPerms

ShadowPerms is the CheckFunc for CheckShadowPerms.

func UIDZeroOnlyRoot

UIDZeroOnlyRoot is the CheckFunc for CheckUIDZeroOnlyRoot.

func UmaskCheck added in v0.20.0

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL