Ensure SSH MaxStartups is configured
Description
The MaxStartups parameter specifies the maximum number of concurrent
unauthenticated connections to the SSH daemon. Additional connections will be
dropped until authentication succeeds or the LoginGraceTime expires for a
connection. To confgure MaxStartups, you should add or correct the following
line in the
/etc/ssh/sshd_config
file:
CIS recommends a MaxStartups value of ‘10:30:60’, or more restrictive where
dictated by site policy.
Rationale
To protect a system from denial of service due to a large number of pending
authentication connection attempts, use the rate limiting function of MaxStartups
to protect availability of sshd logins and prevent overwhelming the daemon.
Shell script
The following script can be run on the host to remediate the issue.
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then
var\_sshd\_set\_maxstartups='10:30:60'
if [ -e "/etc/ssh/sshd\_config" ] ; then
LC\_ALL=C sed -i "/^\s\*MaxStartups\s\+/Id" "/etc/ssh/sshd\_config"
else
touch "/etc/ssh/sshd\_config"
fi
# make sure file has newline at the end
sed -i -e '$a\' "/etc/ssh/sshd\_config"
cp "/etc/ssh/sshd\_config" "/etc/ssh/sshd\_config.bak"
# Insert before the line matching the regex '^Match'.
line\_number="$(LC\_ALL=C grep -n "^Match" "/etc/ssh/sshd\_config.bak" | LC\_ALL=C sed 's/:.\*//g')"
if [ -z "$line\_number" ]; then
# There was no match of '^Match', insert at
# the end of the file.
printf '%s\n' "MaxStartups $var\_sshd\_set\_maxstartups" >> "/etc/ssh/sshd\_config"
else
head -n "$(( line\_number - 1 ))" "/etc/ssh/sshd\_config.bak" > "/etc/ssh/sshd\_config"
printf '%s\n' "MaxStartups $var\_sshd\_set\_maxstartups" >> "/etc/ssh/sshd\_config"
tail -n "+$(( line\_number ))" "/etc/ssh/sshd\_config.bak" >> "/etc/ssh/sshd\_config"
fi
# Clean up after ourselves.
rm "/etc/ssh/sshd\_config.bak"
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
Ansible playbook
The following playbook can be run with Ansible to remediate the issue.
- name: XCCDF Value var\_sshd\_set\_maxstartups # promote to variable
set\_fact:
var\_sshd\_set\_maxstartups: !!str 10:30:60
tags:
- always
- name: Ensure SSH MaxStartups is configured
block:
- name: Check for duplicate values
lineinfile:
path: /etc/ssh/sshd\_config
create: false
regexp: (?i)^\s\*MaxStartups\s+
state: absent
check\_mode: true
changed\_when: false
register: dupes
- name: Deduplicate values from /etc/ssh/sshd\_config
lineinfile:
path: /etc/ssh/sshd\_config
create: false
regexp: (?i)^\s\*MaxStartups\s+
state: absent
when: dupes.found is defined and dupes.found > 1
- name: Insert correct line to /etc/ssh/sshd\_config
lineinfile:
path: /etc/ssh/sshd\_config
create: true
regexp: (?i)^\s\*MaxStartups\s+
line: MaxStartups {{ var\_sshd\_set\_maxstartups }}
state: present
insertbefore: ^[#\s]\*Match
validate: /usr/sbin/sshd -t -f %s
when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- PCI-DSSv4-2.2.6
- low\_complexity
- low\_disruption
- medium\_severity
- no\_reboot\_needed
- restrict\_strategy
- sshd\_set\_maxstartups