Add report-only Lynis host audit
This commit is contained in:
parent
c8be38a213
commit
adb2b921ed
|
|
@ -142,6 +142,10 @@ baseline passive scans for targets in `security/targets.txt`.
|
||||||
`security-k8s`
|
`security-k8s`
|
||||||
: Run kube-bench CIS checks against the Debian kubeadm host.
|
: Run kube-bench CIS checks against the Debian kubeadm host.
|
||||||
|
|
||||||
|
`security-host`
|
||||||
|
: Run a Lynis host audit on Debian and print only warnings and suggestions.
|
||||||
|
This command is report-only.
|
||||||
|
|
||||||
`security-trivy`
|
`security-trivy`
|
||||||
: Run only Trivy filesystem and IaC/config scans.
|
: Run only Trivy filesystem and IaC/config scans.
|
||||||
|
|
||||||
|
|
@ -219,6 +223,10 @@ smoke test. Defaults to `cloudflare.com`.
|
||||||
`SECURITY_NUCLEI_TARGET`
|
`SECURITY_NUCLEI_TARGET`
|
||||||
: Optional single URL override for `security-nuclei`.
|
: Optional single URL override for `security-nuclei`.
|
||||||
|
|
||||||
|
`lynis`
|
||||||
|
: `security-host` requires Lynis to be installed on the Debian host. Install it
|
||||||
|
explicitly with `sudo apt install lynis`.
|
||||||
|
|
||||||
`LAB_AUTO_APPROVE=false`
|
`LAB_AUTO_APPROVE=false`
|
||||||
: Disable automatic OpenTofu approval for apply paths that support confirmation.
|
: Disable automatic OpenTofu approval for apply paths that support confirmation.
|
||||||
|
|
||||||
|
|
@ -328,6 +336,12 @@ Run a ZAP baseline scan against one URL:
|
||||||
SECURITY_ZAP_TARGET=https://lab2025.duckdns.org/ ./jeannie security-zap
|
SECURITY_ZAP_TARGET=https://lab2025.duckdns.org/ ./jeannie security-zap
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run a report-only Lynis host audit:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./jeannie security-host
|
||||||
|
```
|
||||||
|
|
||||||
Run the blocking pre-apply doctor directly:
|
Run the blocking pre-apply doctor directly:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
|
||||||
10
jeannie
10
jeannie
|
|
@ -5780,6 +5780,11 @@ security_k8s() {
|
||||||
"${REPO_ROOT}/scripts/security-scan" kube-bench
|
"${REPO_ROOT}/scripts/security-scan" kube-bench
|
||||||
}
|
}
|
||||||
|
|
||||||
|
security_host() {
|
||||||
|
require_debian_server "security-host"
|
||||||
|
"${REPO_ROOT}/scripts/security-scan" host
|
||||||
|
}
|
||||||
|
|
||||||
security_trivy() {
|
security_trivy() {
|
||||||
require_debian_server "security-trivy"
|
require_debian_server "security-trivy"
|
||||||
"${REPO_ROOT}/scripts/security-scan" trivy
|
"${REPO_ROOT}/scripts/security-scan" trivy
|
||||||
|
|
@ -5903,6 +5908,9 @@ case "${1:-}" in
|
||||||
security-k8s)
|
security-k8s)
|
||||||
security_k8s
|
security_k8s
|
||||||
;;
|
;;
|
||||||
|
security-host)
|
||||||
|
security_host
|
||||||
|
;;
|
||||||
security-trivy)
|
security-trivy)
|
||||||
security_trivy
|
security_trivy
|
||||||
;;
|
;;
|
||||||
|
|
@ -5920,7 +5928,7 @@ case "${1:-}" in
|
||||||
echo "Log: ${JEANNIE_LOG_FILE}"
|
echo "Log: ${JEANNIE_LOG_FILE}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-gitea-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-trivy|security-nuclei|openwrt|nuke}"
|
echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-gitea-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-nuclei|openwrt|nuke}"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ NUCLEI_IMAGE="${NUCLEI_IMAGE:-projectdiscovery/nuclei:latest}"
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
Usage: scripts/security-scan {all|prepare|trivy|zap|kube-bench|nuclei}
|
Usage: scripts/security-scan {all|prepare|trivy|zap|kube-bench|nuclei|host}
|
||||||
|
|
||||||
Environment:
|
Environment:
|
||||||
SECURITY_REPORT_DIR Report output directory.
|
SECURITY_REPORT_DIR Report output directory.
|
||||||
|
|
@ -182,6 +182,71 @@ run_kube_bench() {
|
||||||
"${KUBE_BENCH_IMAGE}" run --targets master,node | tee "${SECURITY_REPORT_DIR}/kube-bench-${stamp}.txt"
|
"${KUBE_BENCH_IMAGE}" run --targets master,node | tee "${SECURITY_REPORT_DIR}/kube-bench-${stamp}.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_lynis_recommendations() {
|
||||||
|
local report_file="$1"
|
||||||
|
local warnings
|
||||||
|
local suggestions
|
||||||
|
local hardening_index
|
||||||
|
|
||||||
|
hardening_index="$(awk -F= '$1 == "hardening_index" { print $2; exit }' "${report_file}" 2>/dev/null || true)"
|
||||||
|
warnings="$(sed -n 's/^warning\[\]=//p' "${report_file}" 2>/dev/null | awk -F'|' '{ print $1 (NF > 1 ? " [" $NF "]" : "") }')"
|
||||||
|
suggestions="$(sed -n 's/^suggestion\[\]=//p' "${report_file}" 2>/dev/null | awk -F'|' '{ print $1 (NF > 1 ? " [" $NF "]" : "") }')"
|
||||||
|
|
||||||
|
printf '\n== Lynis Host Recommendations ==\n'
|
||||||
|
if [[ -n "${hardening_index}" ]]; then
|
||||||
|
printf 'Hardening index: %s\n' "${hardening_index}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '\n-- Warnings\n'
|
||||||
|
if [[ -n "${warnings}" ]]; then
|
||||||
|
printf '%s\n' "${warnings}" | sed 's/^/- /'
|
||||||
|
else
|
||||||
|
printf 'none\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '\n-- Suggestions\n'
|
||||||
|
if [[ -n "${suggestions}" ]]; then
|
||||||
|
printf '%s\n' "${suggestions}" | sed 's/^/- /'
|
||||||
|
else
|
||||||
|
printf 'none\n'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
run_lynis_host() {
|
||||||
|
local stamp
|
||||||
|
local report_file
|
||||||
|
local log_file
|
||||||
|
stamp="$(timestamp)"
|
||||||
|
ensure_report_dir
|
||||||
|
report_file="${SECURITY_REPORT_DIR}/lynis-host-${stamp}.dat"
|
||||||
|
log_file="${SECURITY_REPORT_DIR}/lynis-host-${stamp}.log"
|
||||||
|
|
||||||
|
if ! command -v lynis >/dev/null 2>&1; then
|
||||||
|
cat >&2 <<'EOF'
|
||||||
|
lynis is not installed on this host.
|
||||||
|
|
||||||
|
Install it on Debian with:
|
||||||
|
|
||||||
|
sudo apt install lynis
|
||||||
|
|
||||||
|
Jeannie does not install Lynis automatically because host hardening audits should
|
||||||
|
remain explicit and report-only.
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running Lynis host audit in report-only mode..."
|
||||||
|
sudo lynis audit system \
|
||||||
|
--no-colors \
|
||||||
|
--quiet \
|
||||||
|
--report-file "${report_file}" \
|
||||||
|
--log-file "${log_file}" >/dev/null
|
||||||
|
|
||||||
|
print_lynis_recommendations "${report_file}"
|
||||||
|
printf '\nFull Lynis report: %s\n' "${report_file}"
|
||||||
|
printf 'Full Lynis log: %s\n' "${log_file}"
|
||||||
|
}
|
||||||
|
|
||||||
case "${1:-all}" in
|
case "${1:-all}" in
|
||||||
all)
|
all)
|
||||||
run_trivy
|
run_trivy
|
||||||
|
|
@ -202,6 +267,9 @@ case "${1:-all}" in
|
||||||
kube-bench)
|
kube-bench)
|
||||||
run_kube_bench
|
run_kube_bench
|
||||||
;;
|
;;
|
||||||
|
host)
|
||||||
|
run_lynis_host
|
||||||
|
;;
|
||||||
-h | --help | help)
|
-h | --help | help)
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ Use Jeannie from the Debian homelab host:
|
||||||
./jeannie security-scan
|
./jeannie security-scan
|
||||||
./jeannie security-zap
|
./jeannie security-zap
|
||||||
./jeannie security-k8s
|
./jeannie security-k8s
|
||||||
|
./jeannie security-host
|
||||||
```
|
```
|
||||||
|
|
||||||
The default `security-scan` runs:
|
The default `security-scan` runs:
|
||||||
|
|
@ -23,6 +24,8 @@ The focused commands are:
|
||||||
images.
|
images.
|
||||||
- `security-zap`: OWASP ZAP baseline scan only.
|
- `security-zap`: OWASP ZAP baseline scan only.
|
||||||
- `security-k8s`: kube-bench CIS checks against the kubeadm host.
|
- `security-k8s`: kube-bench CIS checks against the kubeadm host.
|
||||||
|
- `security-host`: Lynis host audit summary for Debian. This command is
|
||||||
|
report-only and prints warnings/suggestions.
|
||||||
- `security-trivy`: Trivy repo and IaC/config scans only.
|
- `security-trivy`: Trivy repo and IaC/config scans only.
|
||||||
- `security-nuclei`: low-rate nuclei HTTP exposure scans only.
|
- `security-nuclei`: low-rate nuclei HTTP exposure scans only.
|
||||||
|
|
||||||
|
|
@ -38,3 +41,8 @@ understand the traffic it will generate.
|
||||||
|
|
||||||
`security/targets.txt` is the public target allowlist. Keep it limited to
|
`security/targets.txt` is the public target allowlist. Keep it limited to
|
||||||
services you own.
|
services you own.
|
||||||
|
|
||||||
|
`security-host` intentionally does not self-fix Lynis findings. Some hardening
|
||||||
|
recommendations can break SSH access, Docker networking, kubeadm, or public edge
|
||||||
|
routing. Use Lynis output to choose one narrow remediation at a time, then add an
|
||||||
|
explicit Jeannie command for that specific change.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue