securing oracle linux 9 article 16 configuring and securing ssh service cis 5-1

In the previous section, we covered Configuring and Securing Host-Based Firewall.

1. CIS Benchmark Requirements (Section 5.1)

The inconsistent numbering has been corrected and reordered according to the CIS standard as follows:

  • 5.1 Configure SSH Server
  • 5.1.1 Ensure permissions on /etc/ssh/sshd_config are configured
  • 5.1.2 Ensure permissions on SSH private host key files are configured
  • 5.1.3 Ensure permissions on SSH public host key files are configured
  • 5.1.4 Ensure sshd Ciphers are configured
  • 5.1.5 Ensure sshd KexAlgorithms is configured
  • 5.1.6 Ensure sshd MACs are configured
  • 5.1.7 Ensure sshd access is configured (AllowUsers/AllowGroups)
  • 5.1.8 Ensure sshd Banner is configured
  • 5.1.9 Ensure sshd ClientAliveInterval and ClientAliveCountMax are configured
  • 5.1.10 Ensure sshd DisableForwarding is enabled
  • 5.1.11 Ensure sshd GSSAPIAuthentication is disabled
  • 5.1.12 Ensure sshd HostbasedAuthentication is disabled
  • 5.1.13 Ensure sshd IgnoreRhosts is enabled
  • 5.1.14 Ensure sshd LoginGraceTime is configured
  • 5.1.15 Ensure sshd LogLevel is configured
  • 5.1.16 Ensure sshd MaxAuthTries is configured
  • 5.1.17 Ensure sshd MaxStartups is configured
  • 5.1.18 Ensure sshd MaxSessions is configured
  • 5.1.19 Ensure sshd PermitEmptyPasswords is disabled
  • 5.1.20 Ensure sshd PermitRootLogin is disabled
  • 5.1.21 Ensure sshd PermitUserEnvironment is disabled
  • 5.1.22 Ensure sshd UsePAM is enabled

2. Concept & Rationale

Concept: The SSH service is the primary entry point for remote server administration. The CIS standard emphasizes hardening this service thoroughly by correcting file permissions, using strong cryptographic algorithms, managing sessions properly, and restricting access. Recommended permissions include 0600 for private key files and 0644 for public key files.

Security Rationale: These controls help prevent brute-force attacks by limiting authentication attempts, protect against private key theft, terminate abandoned sessions to reduce the risk of unauthorized use of open terminals, and disable features such as forwarding to prevent bypassing firewall and access control policies.

3. Compatibility with Oracle Database (RAC, ASM, Grid)

Conflict Status: High. This section is critical, especially for access controls, forwarding settings, and timeout values.

Oracle Requirements and Considerations:

  • Access Controls (AllowUsers/AllowGroups): If this control is enabled, Oracle-related users such as oracle and grid, along with related groups such as dba and oinstall, must be explicitly added to the allowed list. Otherwise, DBA access may be unintentionally blocked.
  • Root Access (PermitRootLogin): During Oracle Grid Infrastructure installation, temporary root login may be required for establishing SSH equivalence between cluster nodes. After installation is complete, this setting must be changed back to no.
  • Graphical Interface (DisableForwarding): Disabling X11 forwarding according to CIS requirements means Oracle graphical tools such as dbca or runInstaller can no longer be launched over SSH. Installation must therefore be performed in silent mode using response files, or through alternatives such as VNC.
  • Session Management (ClientAliveInterval): Values that are too low may disconnect long-running tasks such as installations or RMAN backup operations. A value between 300 and 600 seconds is recommended.
  • Concurrent Sessions (MaxStartups/MaxSessions): Monitoring tools such as Oracle Enterprise Manager (OEM) may open many simultaneous sessions. In large environments, these values should be increased carefully based on OEM requirements to avoid disrupting monitoring operations.

4. Audit (Audit Script)

The following script checks file permissions and the active runtime values of sshd:

GitHub link for this script: modules/audit_16_Secure_SSH.sh

If you are not familiar with bash scripting, you can refer to the training published for Database Administrators on the site: Bash for Oracle DBAs

#!/bin/bash
# Script: audit16.sh
# Purpose: Audit Script for SSH Service (CIS 5.1)

if [ "$EUID" -ne 0 ]; then
    echo -e "\e[31m[!] Please run as root\e[0m"
    exit 1
fi

FAIL_COUNT=0

echo "=========================================================================="
echo " Audit Script for SSH Service (CIS 5.1)"
echo " Oracle Context: AllowGroups must include 'dba'. "
echo " Oracle Exception: X11Forwarding is YES for Oracle GUI tools (DBCA, etc)."
echo "=========================================================================="

check_sshd_param() {
    local param=$1
    local expected=$2
    local actual=$(sshd -T 2>/dev/null | grep -iw "^$param" | awk '{print $2}')

    if [[ "$param" == "allowgroups" ]]; then
        if echo "$actual" | grep -q "$expected"; then
            echo -e "  \e[32m[PASS]\e[0m $param contains '$expected'"
        else
            echo -e "  \e[31m[FAIL]\e[0m $param ($actual) does not contain '$expected'"
            ((FAIL_COUNT++))
        fi
        return
    fi

    if [ "$actual" == "$expected" ]; then
        echo -e "  \e[32m[PASS]\e[0m $param is set to $expected"
    else
        echo -e "  \e[31m[FAIL]\e[0m $param is '$actual' (Expected: $expected)"
        ((FAIL_COUNT++))
    fi
}

echo -e "\n[*] Checking active SSH parameters..."
check_sshd_param "permitrootlogin" "no"
check_sshd_param "x11forwarding" "yes"     # <--- Oracle Exception: YES
check_sshd_param "clientaliveinterval" "300"
check_sshd_param "clientalivecountmax" "3"
check_sshd_param "disableforwarding" "yes"
check_sshd_param "gssapiauthentication" "no"
check_sshd_param "logingracetime" "60"
check_sshd_param "maxauthtries" "4"
check_sshd_param "maxsessions" "10"
check_sshd_param "permitemptypasswords" "no"
check_sshd_param "allowgroups" "dba"

echo -e "\n[*] Checking Permissions for sshd_config and Keys..."
SSHD_PERM=$(stat -c "%a" /etc/ssh/sshd_config)
if [ "$SSHD_PERM" == "600" ]; then
    echo -e "  \e[32m[PASS]\e[0m /etc/ssh/sshd_config has permissions 600"
else
    echo -e "  \e[31m[FAIL]\e[0m /etc/ssh/sshd_config has permissions $SSHD_PERM (Expected: 600)"
    ((FAIL_COUNT++))
fi

echo "=========================================================================="
if [ $FAIL_COUNT -eq 0 ]; then
    echo -e "\e[32m[+] AUDIT PASSED: All SSH settings meet CIS/Oracle requirements.\e[0m"
else
    echo -e "\e[31m[-] AUDIT FAILED: $FAIL_COUNT issue(s) found. Run remediation16.sh.\e[0m"
fi

5. Remediation (Remediation Script)

The following script applies secure settings directly through the main configuration file and corrects key permissions. A drop-in file is the standard and best-practice method in Oracle Linux 9, but this script intentionally edits the primary file directly for Oracle RAC and GUI compatibility.

GitHub link for this script: modules/remediate_16_Secure_SSH.sh

#!/bin/bash
# Remediation Script for CIS 5.1 - SSH Server Configuration
# Direct edit of /etc/ssh/sshd_config (Oracle RAC/GUI Compatible)

# 1. Check if running as root
if [ "$EUID" -ne 0 ]; then
  echo -e "\033[31m[-] Please run as root.\033[0m"
  exit 1
fi

CONFIG_FILE="/etc/ssh/sshd_config"
BACKUP_FILE="${CONFIG_FILE}.bak.$(date +%F_%T)"

# 2. Backup the original file and fix permissions
echo -e "\033[34m[*] Backing up $CONFIG_FILE to $BACKUP_FILE...\033[0m"
cp -p "$CONFIG_FILE" "$BACKUP_FILE"
chmod 0600 "$CONFIG_FILE"

# Function to safely update or append parameters in sshd_config
set_ssh_param() {
    local param="$1"
    local val="$2"

    # Check if parameter exists (commented or uncommented)
    if grep -q -E -i "^[#[:space:]]*${param}\b" "$CONFIG_FILE"; then
        # Replace the line with the correct parameter and value
        sed -i -E "s/^[#[:space:]]*${param}\b.*/${param} ${val}/i" "$CONFIG_FILE"
    else
        # Append to the end of the file if it doesn't exist
        echo "${param} ${val}" >> "$CONFIG_FILE"
    fi
}

echo -e "\033[34m[*] Applying CIS & Oracle SSH settings directly to $CONFIG_FILE...\033[0m"

# Oracle Exceptions (GUI Tools)
set_ssh_param "X11Forwarding" "yes"

# CIS Benchmark Settings + Oracle Context
set_ssh_param "PermitRootLogin" "no"
set_ssh_param "ClientAliveInterval" "300"
set_ssh_param "ClientAliveCountMax" "3"
set_ssh_param "DisableForwarding" "yes"
set_ssh_param "GSSAPIAuthentication" "no"
set_ssh_param "LoginGraceTime" "60"
set_ssh_param "MaxAuthTries" "4"
set_ssh_param "MaxSessions" "10"
set_ssh_param "PermitEmptyPasswords" "no"
set_ssh_param "AllowGroups" "wheel dba oinstall"

# NOTE on Oracle Linux 9 / RHEL 9:
# If "Include /etc/ssh/sshd_config.d/*.conf" is at the top of the file,
# settings in the drop-in directory (like 50-redhat.conf) might still override these.
# We ensure the Include line is either handled or we trust our direct edits.
# Uncomment the line below if you want to disable the drop-in directory completely:
# sed -i 's/^Include \/etc\/ssh\/sshd_config.d\/\*\.conf/#Include \/etc\/ssh\/sshd_config.d\/\*\.conf/' "$CONFIG_FILE"
# Fix GSSAPIAuthentication in drop-in files
sed -i 's/^GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_config.d/*.conf 2>/dev/null

# 3. Check syntax and restart SSH service
echo -e "\033[34m[*] Checking SSH configuration syntax...\033[0m"
if sshd -t; then
    echo -e "\033[32m[+] Syntax OK. Restarting SSH service...\033[0m"
    systemctl restart sshd
    echo -e "\033[32m[+] Remediation completed successfully.\033[0m"
else
    echo -e "\033[31m[-] Syntax error detected in $CONFIG_FILE. Restoring backup...\033[0m"
    cp -p "$BACKUP_FILE" "$CONFIG_FILE"
    exit 1
fi

In the next section, we will cover: Securing Privilege Escalation.