{
  "id": "CB-UBU-NET-021",
  "standard": "ubuntu",
  "version": "0.1.1",
  "url": "https://baselines.cirsec.org/b/ubuntu/v0.1.1/CB-UBU-NET-021",
  "json": "https://baselines.cirsec.org/b/ubuntu/v0.1.1/CB-UBU-NET-021.json",
  "yaml": "https://baselines.cirsec.org/b/ubuntu/v0.1.1/CB-UBU-NET-021.yml",
  "profiles_effective": [
    "core",
    "server",
    "server-hardened",
    "desktop",
    "desktop-hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-UBU-NET-021",
    "title": "Limit SSH logins to the users and groups that need them",
    "finding": {
      "title": "Every account with a valid credential can log in over SSH",
      "description": "Service accounts, temporary users or accounts with a leaked key can open a shell remotely although they never should."
    },
    "status": "active",
    "profiles": [
      "core"
    ],
    "risk": {
      "severity": "medium"
    },
    "assessment": "manual",
    "tags": [
      "ssh",
      "access-control"
    ],
    "applicability": {
      "facts": [
        "openssh-server"
      ]
    },
    "description": "The OpenSSH server options `AllowGroups`, `AllowUsers`, `DenyGroups` and `DenyUsers` restrict\nwhich accounts may log in, whatever credentials they hold. A typical setup allows one group,\nfor example `AllowGroups ssh-users`, and adds the people who administer or use the host to it.\n",
    "rationale": "Many accounts exist on a system for services, applications or past projects. An allow list makes\nSSH access a deliberate decision per account, so that a key or password left on an account that\nshould not log in remotely is useless to an attacker.\n",
    "impact": "Accounts outside the list, including automation accounts, cannot log in anymore. The list must\nbe kept up to date with arrivals and departures. The right list depends on the host, which is\nwhy there is no automatic fix.\n",
    "audit": {
      "manual": "Run `sshd -T | grep -E '^(allowusers|allowgroups|denyusers|denygroups) '`. At least one of\nthese options must be set, and the accounts or groups it allows must match the list of\npeople and tools that need SSH access to this host.\n"
    },
    "remediation": {
      "manual": "1. Create a group (`groupadd ssh-users`) and add the accounts that need SSH access\n   (`usermod -aG ssh-users <account>`), starting with your own.\n2. Add `AllowGroups ssh-users` to `/etc/ssh/sshd_config.d/00-cirsec.conf`.\n3. Check with `sshd -t`, run `systemctl reload ssh`, and test a new connection before closing\n   the current one.\n",
      "rollback": "Remove the `AllowGroups` line and run `systemctl reload ssh`.\n"
    },
    "references": [
      {
        "title": "sshd_config(5), Ubuntu manual pages",
        "url": "https://manpages.ubuntu.com/manpages/noble/man5/sshd_config.5.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "NIST IR 7966 - Security of Interactive and Automated Access Management Using Secure Shell (SSH)",
        "url": "https://csrc.nist.gov/pubs/ir/7966/final",
        "publisher": "NIST",
        "kind": "guide",
        "accessed": "2026-10-19"
      }
    ],
    "mappings": [
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-17",
        "relation": "partial"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-3",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1021.004"
      },
      {
        "framework": "mitre-attack",
        "id": "T1078"
      },
      {
        "framework": "cwe",
        "id": "CWE-284"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-19",
    "updated": "2026-10-19"
  }
}