SSH Allows Many Authentication Attempts
Checks whether MaxAuthTries is above 4.
- Why It Matters
- Each connection may try this many passwords or keys. A low limit slows guessing and makes attacks show up in the logs sooner.
- How It Detects
- Reads MaxAuthTries (OpenSSH default 6); a value above 4 fails.
- How to Fix
- Set MaxAuthTries 4 (or lower) in /etc/ssh/sshd_config and reload sshd. Consider fail2ban or sshguard for rate limiting.
- How to Verify
sshd -T | grep -i maxauthtries should print 4 or lower.- CVSS v3.1 Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N- Control Category
- Identity and Authentication: CIS Controls v8 5, 6; NIST CSF 2.0 PR.AA
- Fix Effort
- Low
- CIS Controls v8 Safeguard
- 4.1
- NIST CSF 2.0 Subcategory
- PR.PS-01
- CWE
- CWE-307
- NIST SP 800-53 Rev. 5
- AC-7
- Benchmark Topic
- SSH server configuration: MaxAuthTries (topic only, no benchmark text)
- References
- OpenBSD, sshd_config(5) manual page
Source Code
The complete file that defines this check. Run it with openvapt scan --only HOST-SSH-006, or read it offline with openvapt explain HOST-SSH-006.
internal/checks/host/ssh_misc.go · Lines 1-71View on GitHub at This Commit
| 1 | package host |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "strconv" |
| 6 | |
| 7 | "github.com/openvapt/openvapt/internal/check" |
| 8 | "github.com/openvapt/openvapt/internal/checks/collect" |
| 9 | "github.com/openvapt/openvapt/internal/sys" |
| 10 | ) |
| 11 | |
| 12 | func init() { |
| 13 | check.Register(&check.Check{ |
| 14 | ID: "HOST-SSH-005", |
| 15 | Title: "SSH X11 Forwarding Enabled", |
| 16 | Domain: check.DomainHost, |
| 17 | Severity: check.Low, |
| 18 | CVSS: "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:N", |
| 19 | Summary: "Checks whether SSH forwards graphical X11 sessions.", |
| 20 | Rationale: "Servers rarely need X11. Forwarding it exposes the connecting user's display to anyone with root on the server, and widens the attack surface of sshd.", |
| 21 | Detection: "Reads X11Forwarding from the effective sshd configuration; 'yes' fails. A risky value set inside a Match block in the config files fails as a conditional finding, with the Match condition in the evidence.", |
| 22 | Fix: "Set X11Forwarding no in /etc/ssh/sshd_config and reload sshd.", |
| 23 | Verify: "sshd -T | grep -i x11forwarding should print 'no'.", |
| 24 | Refs: []check.Ref{refSSHDManual}, |
| 25 | Standards: check.Standards{CWE: []string{"CWE-1188"}, NIST: []string{"CM-7"}, CISTopic: "SSH server configuration: X11 forwarding"}, |
| 26 | Run: func(ctx context.Context, s sys.System) []check.Result { |
| 27 | cfg, ok := collect.SSHD(ctx, s) |
| 28 | if !ok { |
| 29 | return []check.Result{check.SkipR("sshd", "SSH daemon configuration not found")} |
| 30 | } |
| 31 | if cfg["x11forwarding"] == "yes" { |
| 32 | return []check.Result{check.FailR("sshd", "X11 forwarding is enabled", "x11forwarding yes")} |
| 33 | } |
| 34 | if r, bad := sshMatchFail(cfg, "X11 forwarding is enabled", "x11forwarding"); bad { |
| 35 | return []check.Result{r} |
| 36 | } |
| 37 | return []check.Result{check.PassR("sshd", "X11 forwarding is disabled")} |
| 38 | }, |
| 39 | }) |
| 40 | |
| 41 | check.Register(&check.Check{ |
| 42 | ID: "HOST-SSH-006", |
| 43 | Title: "SSH Allows Many Authentication Attempts", |
| 44 | Domain: check.DomainHost, |
| 45 | Severity: check.Low, |
| 46 | CVSS: "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N", |
| 47 | Summary: "Checks whether MaxAuthTries is above 4.", |
| 48 | Rationale: "Each connection may try this many passwords or keys. A low limit slows guessing and makes attacks show up in the logs sooner.", |
| 49 | Detection: "Reads MaxAuthTries (OpenSSH default 6); a value above 4 fails.", |
| 50 | Fix: "Set MaxAuthTries 4 (or lower) in /etc/ssh/sshd_config and reload sshd. Consider fail2ban or sshguard for rate limiting.", |
| 51 | Verify: "sshd -T | grep -i maxauthtries should print 4 or lower.", |
| 52 | Refs: []check.Ref{refSSHDManual}, |
| 53 | Standards: check.Standards{CWE: []string{"CWE-307"}, NIST: []string{"AC-7"}, CISTopic: "SSH server configuration: MaxAuthTries"}, |
| 54 | Run: func(ctx context.Context, s sys.System) []check.Result { |
| 55 | cfg, ok := collect.SSHD(ctx, s) |
| 56 | if !ok { |
| 57 | return []check.Result{check.SkipR("sshd", "SSH daemon configuration not found")} |
| 58 | } |
| 59 | n := 6 |
| 60 | if v, set := cfg["maxauthtries"]; set { |
| 61 | if x, err := strconv.Atoi(v); err == nil { |
| 62 | n = x |
| 63 | } |
| 64 | } |
| 65 | if n > 4 { |
| 66 | return []check.Result{check.FailR("sshd", "MaxAuthTries is "+strconv.Itoa(n)+" (recommended 4 or lower)")} |
| 67 | } |
| 68 | return []check.Result{check.PassR("sshd", "MaxAuthTries is "+strconv.Itoa(n))} |
| 69 | }, |
| 70 | }) |
| 71 | } |
Also available as plain Markdown for notes, scripts and AI tools. Same facts, same source, no styling.
Cite This Page
If this page helped your work, please cite it. The version and web address are filled in; the access date is today's date in your browser. Every other style, and when credit is required, is on How to Cite OpenVAPT.
OpenVAPT. (2026). HOST-SSH-006 SSH Allows Many Authentication Attempts (Version 0.1.0-alpha.6). OpenVAPT Check Catalogue. Retrieved October 16, 2026, from https://openvapt.com/checks/HOST-SSH-006.html
In text: (OpenVAPT, 2026). Accessed: the date shown is today's date from your own browser (the site's build date without JavaScript); change it to the day you read the page.
@misc{openvapt_host_ssh_006,
author = {{OpenVAPT}},
title = {{HOST-SSH-006 SSH Allows Many Authentication Attempts}},
year = {2026},
howpublished = {\url{https://openvapt.com/checks/HOST-SSH-006.html}},
note = {OpenVAPT Check Catalogue, version 0.1.0-alpha.6. Accessed 16 October 2026}
}
Accessed: the date shown is today's date from your own browser (the site's build date without JavaScript); change it to the day you read the page.
Citing OpenVAPT does not mean OpenVAPT endorses, approves or has reviewed your work.