securing oracle linux 9 article 12 configuring time synchronization chrony

In the previous part

Removing Unnecessary Service Clients

was completed.

1. CIS Benchmark Requirements (Section 2.3)

This section of the standard focuses on the secure and precise configuration of the time synchronization service:

  • 2.3.1 Ensure time synchronization is in use (Automated)
  • 2.3.2 Ensure chrony is configured (Automated)
  • 2.3.3 Ensure chrony is not run as the root user (Automated)

 

2. Concept & Rationale

Concept: Accurate time synchronization is vital for log auditing, correlating security events across the network, and the proper functioning of authentication protocols such as Kerberos. In Oracle Linux 9, the default service for this task is chronyd.

Security Reason: Running the time synchronization service as a non-root user (such as the dedicated chrony user) reduces its privilege level. If a vulnerability in this service is discovered and exploited, the entire system is not compromised, and the Principle of Least Privilege is maintained.

 

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

  • Critical for Oracle RAC: Time synchronization is extremely critical for Oracle clusters (Grid Infrastructure). If the chrony service is running on the operating system, Oracle's cluster time synchronization service—CTSS—automatically enters Observer Mode, which is a completely standard and Oracle-recommended behavior.
  • No Conflict: Running chrony as a non-root user does not create any conflict with Oracle, because Oracle reads the system time directly from the kernel.
  • Important Cluster Note: The NTP servers defined in the /etc/chrony.conf file must be exactly identical across all RAC cluster nodes to prevent time synchronization errors, Split-Brain phenomena, or node eviction from the cluster.

 

4. Checking the Current Status (Audit Script)

The following script checks whether chrony is installed, whether NTP servers are configured, and whether the service runs as the chrony user:

GitHub link:

modules/audit_12_Time_Synchronization_Chrony.sh

If you are not familiar with bash scripts, you can refer to the training material I have published on the site for database administrators.

Bash for Oracle DBAs

 

#!/bin/bash
# Script: audit12.sh
# Purpose: Audit Script for Time Sync (CIS 2.3)

echo "=========================================================================="
echo " CIS Requirement: 2.3 Time Synchronization"
echo " - Ensure time synchronization is in use and properly configured (Chrony)."
echo " Oracle Context:"
echo " - Time sync is CRITICAL for Oracle RAC/Grid Infrastructure."
echo " - 'chronyd' is the recommended time service for Oracle DB 19c/23ai on OL9."
echo " - When chronyd is active, Oracle CTSS automatically runs in Observer mode."
echo "=========================================================================="

FAIL_COUNT=0

echo -e "\n[*] Auditing Time Synchronization (Chrony)..."

# 1. Check if chrony is installed
if rpm -q chrony &>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m 'chrony' package is installed."
else
    echo -e "  \e[31m[FAIL]\e[0m 'chrony' package is NOT installed."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# 2. Check chrony configuration for servers/pools
if grep -E '^(server|pool)' /etc/chrony.conf &>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m Remote time servers are configured in /etc/chrony.conf."
else
    echo -e "  \e[31m[FAIL]\e[0m No remote time servers (server/pool) configured."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# 3. Check if chrony runs as non-root (user 'chrony')
if grep -q 'OPTIONS.*-u chrony' /etc/sysconfig/chronyd 2>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m chronyd is configured to run as user 'chrony'."
else
    echo -e "  \e[31m[FAIL]\e[0m chronyd is NOT explicitly configured to run as user 'chrony'."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# 4. Check service status
if systemctl is-enabled chronyd &>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m chronyd service is enabled."
else
    echo -e "  \e[31m[FAIL]\e[0m chronyd service is NOT enabled."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

if [ "$FAIL_COUNT" -eq 0 ]; then
    echo -e "\n\e[32m[+] AUDIT RESULT: PASS\e[0m"
else
    echo -e "\n\e[31m[-] AUDIT RESULT: FAIL ($FAIL_COUNT issues found)\e[0m"
fi

5. Applying the Configuration (Remediation Bash Script)

In this script, the user is first prompted for the NTP server address, then the chrony package is installed, the server address is placed in the configuration file, and the non-root user settings are applied:

GitHub link:

modules/remediate_12_Time_Synchronization_Chrony.sh

 

#!/bin/bash
# Script: remediation12.sh
# Purpose: Configure Time Synchronization via Chrony (CIS 2.3)

if [ "$EUID" -ne 0 ]; then
    echo "Please run as root"
    exit 1
fi

echo "=========================================================================="
echo " Applying Remediation for CIS 2.3 (Time Synchronization)"
echo " Oracle Context: chronyd setup is fully supported and required for Oracle."
echo "=========================================================================="

echo -e "\n[*] Configuring Time Synchronization (Chrony)..."

# Ask user for NTP Server IP/Hostname
read -p "Enter your primary NTP server address (e.g., 192.168.1.50 or pool.ntp.org): " NTP_SERVER

if [ -z "$NTP_SERVER" ]; then
    echo -e "\n\e[31m[-] NTP Server address cannot be empty. Exiting.\e[0m"
    exit 1
fi

# 1. Install chrony if not present
dnf install -y chrony > /dev/null 2>&1

# 2. Configure NTP Server in chrony.conf
cp /etc/chrony.conf /etc/chrony.conf.bak
# Remove existing default pools/servers to avoid conflicts
sed -i '/^pool /d' /etc/chrony.conf
sed -i '/^server /d' /etc/chrony.conf
# Add the user-provided NTP server
echo "server $NTP_SERVER iburst" >> /etc/chrony.conf
echo -e "  \e[32m[OK]\e[0m Set NTP server to $NTP_SERVER in /etc/chrony.conf"

# 3. Ensure it does not run as root
SYSCONFIG_FILE="/etc/sysconfig/chronyd"
if grep -q "^OPTIONS" "$SYSCONFIG_FILE"; then
    if ! grep -q 'OPTIONS.*-u chrony' "$SYSCONFIG_FILE"; then
        sed -i 's/^OPTIONS="\(.*\)"/OPTIONS="\1 -u chrony"/' "$SYSCONFIG_FILE"
    fi
else
    echo 'OPTIONS="-u chrony"' >> "$SYSCONFIG_FILE"
fi
echo -e "  \e[32m[OK]\e[0m Configured chronyd to run as 'chrony' user."

# 4. Enable and restart the service
systemctl enable --now chronyd > /dev/null 2>&1
systemctl restart chronyd
echo -e "  \e[32m[OK]\e[0m chronyd service enabled and restarted."

echo -e "\n\e[32m[+] REMEDIATION APPLIED SUCCESSFULLY\e[0m"

In the next part, we will move on to:

Configuring Job Schedulers (Cron & At)