{
  "id": "CB-UBU-AUDIT-012",
  "standard": "ubuntu",
  "version": "0.1.0",
  "url": "https://baselines.cirsec.org/b/ubuntu/v0.1.0/CB-UBU-AUDIT-012",
  "json": "https://baselines.cirsec.org/b/ubuntu/v0.1.0/CB-UBU-AUDIT-012.json",
  "yaml": "https://baselines.cirsec.org/b/ubuntu/v0.1.0/CB-UBU-AUDIT-012.yml",
  "profiles_effective": [
    "server-hardened",
    "desktop-hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-UBU-AUDIT-012",
    "title": "Enable auditing from boot with a large enough backlog",
    "finding": {
      "title": "Processes started before auditd are not audited",
      "description": "Programs started early in the boot, and events lost when the audit queue overflows, leave no audit record."
    },
    "status": "active",
    "profiles": [
      "server-hardened",
      "desktop-hardened"
    ],
    "risk": {
      "severity": "low"
    },
    "assessment": "automated",
    "tags": [
      "auditd",
      "boot",
      "grub"
    ],
    "description": "Two kernel command line parameters:\n\n- `audit=1` turns auditing on as soon as the kernel starts, so every process gets an audit\n  context, including those started before `auditd`;\n- `audit_backlog_limit={{ backlog_limit }}` sizes the kernel queue of records waiting for\n  `auditd`. The default of 64 overflows during boot, and records are then lost.\n\nThe fix adds both to `GRUB_CMDLINE_LINUX` through `/etc/default/grub.d/60-cirsec-audit.cfg` and\nregenerates the GRUB configuration. They apply at the next boot.\n",
    "rationale": "An attacker who gets code to run early in the boot, or who floods the audit queue, escapes\nauditing. Turning it on at boot and sizing the queue closes both gaps.\n",
    "impact": "A reboot is needed. The backlog uses kernel memory only when records pile up.\n",
    "notes": "The check reads the running command line (`/proc/cmdline`) and, when GRUB is the boot loader,\nthe generated `/boot/grub/grub.cfg`. Right after the fix the first check fails until the reboot.\n",
    "setting": {
      "location": "/etc/default/grub.d/60-cirsec-audit.cfg, kernel command line",
      "default_value": "Not set (auditing starts with auditd, backlog 64)",
      "recommended_value": "audit=1 audit_backlog_limit={{ backlog_limit }} or more"
    },
    "parameters": [
      {
        "name": "backlog_limit",
        "type": "integer",
        "description": "Minimum size of the kernel audit backlog queue (audit_backlog_limit).",
        "unit": "records",
        "default": 8192,
        "minimum": 8192,
        "maximum": 1048576
      }
    ],
    "audit": {
      "manual": "1. Run `cat /proc/cmdline`. It must contain `audit=1` and `audit_backlog_limit=` with a value of\n   at least {{ backlog_limit }}.\n2. Run `grep -E '^\\s*linux' /boot/grub/grub.cfg`. Every line must contain the same two\n   parameters, so they survive the next reboot.\n",
      "checks": [
        {
          "id": "running",
          "engine": "shell",
          "description": "Parameters of the running kernel.",
          "spec": {
            "script": "c=$(cat /proc/cmdline)\nb=$(printf '%s\\n' \"$c\" | tr ' ' '\\n' | sed -n 's/^audit_backlog_limit=//p' | tail -n 1)\na=$(printf '%s\\n' \"$c\" | tr ' ' '\\n' | sed -n 's/^audit=//p' | tail -n 1)\necho \"audit=${a:-unset} audit_backlog_limit=${b:-unset}\"\n[ \"$a\" = 1 ] && [ -n \"$b\" ] && [ \"$b\" -ge \"$CB_BACKLOG_LIMIT\" ]\n"
          }
        },
        {
          "id": "grub",
          "engine": "shell",
          "description": "Parameters in every kernel entry of /boot/grub/grub.cfg.",
          "facts": [
            "grub"
          ],
          "spec": {
            "script": "n=0 bad=0\nwhile IFS= read -r l; do\n  [ -n \"$l\" ] || continue\n  n=$((n + 1))\n  b=$(printf '%s\\n' $l | sed -n 's/^audit_backlog_limit=//p' | tail -n 1)\n  case \" $l \" in *\" audit=1 \"*) ;; *) b= ;; esac\n  if [ -z \"$b\" ] || [ \"$b\" -lt \"$CB_BACKLOG_LIMIT\" ]; then bad=$((bad + 1)); fi\ndone <<EOF\n$(grep -E '^[[:space:]]*linux[[:space:]]' /boot/grub/grub.cfg 2>/dev/null)\nEOF\necho \"$n kernel entries, $bad without audit=1 audit_backlog_limit>=$CB_BACKLOG_LIMIT\"\n[ \"$n\" -gt 0 ] && [ \"$bad\" = 0 ]\n"
          }
        }
      ]
    },
    "remediation": {
      "manual": "1. Create `/etc/default/grub.d/60-cirsec-audit.cfg` with:\n   ```\n   GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE_LINUX audit=1 audit_backlog_limit={{ backlog_limit }}\"\n   ```\n2. Run `update-grub`, then reboot.\n",
      "effects": {
        "restart": "reboot",
        "disruption": "low",
        "lockout_risk": false
      },
      "rollback": "Delete `/etc/default/grub.d/60-cirsec-audit.cfg`, run `update-grub` and reboot.\n",
      "scripts": [
        {
          "id": "grub",
          "engine": "shell",
          "facts": [
            "grub"
          ],
          "content": "f=/etc/default/grub.d/60-cirsec-audit.cfg\nmkdir -p /etc/default/grub.d\ncb_backup \"$f\"\nprintf '%s\\n' '# Written by CIRSEC Baselines CB-UBU-AUDIT-012' \\\n  \"GRUB_CMDLINE_LINUX=\\\"\\$GRUB_CMDLINE_LINUX audit=1 audit_backlog_limit=$CB_BACKLOG_LIMIT\\\"\" >\"$f\"\ncb_backup /boot/grub/grub.cfg\nupdate-grub 2>&1\n"
        }
      ]
    },
    "references": [
      {
        "title": "The kernel's command-line parameters (audit, audit_backlog_limit)",
        "url": "https://docs.kernel.org/admin-guide/kernel-parameters.html",
        "publisher": "The Linux Kernel Organization",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "update-grub(8), Ubuntu manual pages",
        "url": "https://manpages.ubuntu.com/manpages/noble/man8/update-grub.8.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      }
    ],
    "mappings": [
      {
        "framework": "anssi-linux",
        "framework_version": "2.0",
        "id": "R73",
        "relation": "related"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AU-14(1)",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1562.012"
      }
    ],
    "related_controls": [
      {
        "id": "CB-UBU-AUDIT-011",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "verified": [
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "20.04"
        ],
        "environment": "Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic",
        "notes": "Fails on stock image; fix writes grub.d drop-in and runs update-grub; running check passes after reboot (audit=1 audit_backlog_limit=8192), lost 0."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "22.04"
        ],
        "environment": "Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic",
        "notes": "Fails on stock image; fix writes grub.d drop-in and runs update-grub; running check passes after reboot (audit=1 audit_backlog_limit=8192), lost 0."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "24.04"
        ],
        "environment": "Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic",
        "notes": "Fails on stock image; fix writes grub.d drop-in and runs update-grub; running check passes after reboot (audit=1 audit_backlog_limit=8192), lost 0."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "26.04"
        ],
        "environment": "Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic",
        "notes": "Fails on stock image; fix writes grub.d drop-in and runs update-grub; running check passes after reboot (audit=1 audit_backlog_limit=8192), lost 0."
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-19",
    "updated": "2026-10-19"
  }
}