BaselineWatch
Desk

os_ssh_fips_compliant Limit SSH to FIPS Compliant Connections

NIST macOS Security Compliance Project Sequoia Guidance, Revision 4.0 (be5491f)
All changes in this version
first version loaded macOS

Title

Limit SSH to FIPS Compliant Connections

Control

fips_ssh_config=("Ciphers [email protected]" "HostbasedAcceptedAlgorithms ecdsa-sha2-nistp256,[email protected]" "HostKeyAlgorithms [email protected],[email protected],ecdsa-sha2-nistp256,[email protected]" "KexAlgorithms ecdh-sha2-nistp256" "MACs [email protected],hmac-sha2-256" "PubkeyAcceptedAlgorithms ecdsa-sha2-nistp256,[email protected],[email protected]" "CASignatureAlgorithms ecdsa-sha2-nistp256,[email protected]")
total=0
ret="pass"
for config in $fips_ssh_config; do
if [[ "$ret" == "fail" ]]; then
break
fi
for u in $(/usr/bin/dscl . list /users shell | /usr/bin/egrep -v '(^_)|(root)|(/usr/bin/false)' | /usr/bin/awk '{print $1}'); do
sshCheck=$(/usr/bin/sudo -u $u /usr/bin/ssh -G . | /usr/bin/grep -ci "$config")
if [[ "$sshCheck" == "0" ]]; then
ret="fail"
break
fi
done
done
echo $ret

Discussion

SSH _MUST_ be configured to limit the Ciphers, HostbasedAcceptedAlgorithms, HostKeyAlgorithms, KexAlgorithms, MACs, PubkeyAcceptedAlgorithms, CASignatureAlgorithms to algorithms that are FIPS 140 validated.

FIPS 140-3 is the current standard for validating that mechanisms used to access cryptographic modules utilize authentication that meet federal requirements.

Operating systems utilizing encryption _MUST_ use FIPS validated mechanisms for authenticating to cryptographic modules.

NOTE: For more information on FIPS compliance with the version of SSH included in the macOS, the manual page apple_ssh_and_fips has additional information.

NOTE: On macOS 15.2 and higher the SSH configuration can be reset to the macOS default by running /usr/libexec/reset-ssh-configuration.

Related controls

ac-17.2, ia-7, sc-13, sc-8.1

Fix

[source,bash]
----
if [ -f /etc/ssh/crypto.conf ] && /usr/bin/grep -q "Include /etc/ssh/crypto.conf" /etc/ssh/ssh_config.d/100-macos.conf 2>/dev/null; then
/bin/ln -fs /etc/ssh/crypto/fips.conf /etc/ssh/crypto.conf
fi
include_dir=$(/usr/bin/awk '/^Include/ {print $2}' /etc/ssh/ssh_config | /usr/bin/tr -d '*')

fips_ssh_config=("Ciphers [email protected]" "HostbasedAcceptedAlgorithms ecdsa-sha2-nistp256,[email protected]" "HostKeyAlgorithms [email protected],[email protected],ecdsa-sha2-nistp256,[email protected]" "KexAlgorithms ecdh-sha2-nistp256" "MACs [email protected],hmac-sha2-256" "PubkeyAcceptedAlgorithms ecdsa-sha2-nistp256,[email protected],[email protected]" "CASignatureAlgorithms ecdsa-sha2-nistp256,[email protected]")
for ssh_config in $fips_ssh_config; do
ssh_setting=$(echo $ssh_config | /usr/bin/cut -d " " -f1)
/usr/bin/grep -qEi "^$ssh_setting" "${include_dir}01-mscp-ssh.conf" && /usr/bin/sed -i "" "s/^$ssh_setting.*/${ssh_config}/" "${include_dir}01-mscp-ssh.conf" || echo "$ssh_config" >> "${include_dir}01-mscp-ssh.conf"
for u in $(/usr/bin/dscl . list /users shell | /usr/bin/egrep -v '(^_)|(root)|(/usr/bin/false)' | /usr/bin/awk '{print $1}'); do
config=$(/usr/bin/sudo -u $u /usr/bin/ssh -Gv . 2>&1)
configfiles=$(echo "$config" | /usr/bin/awk '/Reading configuration data/ {print $NF}'| /usr/bin/tr -d '\r')
configarray=( ${(f)configfiles} )
if ! echo $config | /usr/bin/grep -q -i "$ssh_config" ; then
for c in $configarray; do
if [[ "$c" == "/etc/ssh/crypto.conf" ]]; then
continue
fi

/usr/bin/sudo -u $u /usr/bin/grep -qEi "^$ssh_setting" "$c" && /usr/bin/sed -i "" "s/^$ssh_setting.*/${ssh_config}/I" "$c"
if [[ "$c" =~ ".ssh/config" ]]; then
if /usr/bin/grep -qEi "$ssh_setting" "$c" 2> /dev/null; then
old_file=$(cat ~$u/.ssh/config)
echo "$ssh_config" > ~$u/.ssh/config
echo "$old_file" >> ~$u/.ssh/config
fi
fi
done
fi
done
done
----