Set SSH Client Alive Count Max
Description
The SSH server sends at most ClientAliveCountMax
messages
during a SSH session and waits for a response from the SSH client.
The option ClientAliveInterval
configures timeout after
each ClientAliveCountMax
message. If the SSH server does not
receive a response from the client, then the connection is considered unresponsive
and terminated.
For SSH earlier than v8.2, a ClientAliveCountMax
value of 0
causes a timeout precisely when the ClientAliveInterval
is set.
Starting with v8.2, a value of 0
disables the timeout functionality
completely. If the option is set to a number greater than 0
, then
the session will be disconnected after
ClientAliveInterval * ClientAliveCountMax
seconds without receiving
a keep alive message.
Rationale
This ensures a user login will be terminated as soon as the ClientAliveInterval
is reached.
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\_keepalive='3'
if [ -e "/etc/ssh/sshd\_config" ] ; then
LC\_ALL=C sed -i "/^\s\*ClientAliveCountMax\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' "ClientAliveCountMax $var\_sshd\_set\_keepalive" >> "/etc/ssh/sshd\_config"
else
head -n "$(( line\_number - 1 ))" "/etc/ssh/sshd\_config.bak" > "/etc/ssh/sshd\_config"
printf '%s\n' "ClientAliveCountMax $var\_sshd\_set\_keepalive" >> "/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\_keepalive # promote to variable
set\_fact:
var\_sshd\_set\_keepalive: !!str 3
tags:
- always
- name: Set SSH Client Alive Count Max
block:
- name: Check for duplicate values
lineinfile:
path: /etc/ssh/sshd\_config
create: false
regexp: (?i)^\s\*ClientAliveCountMax\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\*ClientAliveCountMax\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\*ClientAliveCountMax\s+
line: ClientAliveCountMax {{ var\_sshd\_set\_keepalive }}
state: present
insertbefore: ^[#\s]\*Match
validate: /usr/sbin/sshd -t -f %s
when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- CJIS-5.5.6
- DISA-STIG-UBTU-20-010036
- NIST-800-171-3.1.11
- NIST-800-53-AC-12
- NIST-800-53-AC-17(a)
- NIST-800-53-AC-2(5)
- NIST-800-53-CM-6(a)
- NIST-800-53-SC-10
- PCI-DSS-Req-8.1.8
- PCI-DSSv4-8.2.8
- low\_complexity
- low\_disruption
- medium\_severity
- no\_reboot\_needed
- restrict\_strategy
- sshd\_set\_keepalive