securing oracle linux 9 article 21 system user accounts root user and default environment

In the previous part, Configuring Shadow Password Suite Parameters was completed.

1. CIS Benchmark Requirements (Sections 5.4.2 and 5.4.3)

  • 5.4.2 Configure root and system accounts and environment
  • 5.4.2.1 Ensure root is the only UID 00 account (Automated)
  • 5.4.2.2 Ensure root is the only GID 00 account (Automated)
  • 5.4.2.3 Ensure group root is the only GID 00 group (Automated)
  • 5.4.2.4 Ensure root account access is controlled (Automated)
  • 5.4.2.5 Ensure root path integrity (Automated)
  • 5.4.2.6 Ensure root user umask is configured (Automated)
  • 5.4.2.7 Ensure system accounts do not have a valid login shell (Automated)
  • 5.4.2.8 Ensure accounts without a valid login shell are locked (Automated)
  • 5.4.3 Configure user default environment
  • 5.4.3.1 Ensure nologin is not listed in /etc/shells (Automated)
  • 5.4.3.2 Ensure default user shell timeout is configured (Automated)
  • 5.4.3.3 Ensure default user umask is configured (Automated)

2. Concept and Security Rationale

  • Root uniqueness: No user other than root should have a UID or GID equal to 0. This prevents hidden administrative access.
  • System accounts: Accounts used by services, usually with a UID below 1000, should not have an interactive shell and should be locked to prevent direct login.
  • TMOUT: Automatically terminates idle sessions after a specified period, usually 900 seconds, to prevent misuse of abandoned sessions.
  • umask: Defines the default permissions for newly created files and directories. The CIS-recommended value for secure environments is usually 027.

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

Conflict level: High; exceptions are required.

Oracle requirements and considerations:

  • umask conflict (Critical): The CIS standard recommends a global umask value of 027. However, Oracle Database and Grid Infrastructure installation and operation explicitly require a value of 022. If this value is not overridden in the profiles of the oracle and grid users, such as ~/.bash_profile, software installation, database file creation, and cluster communication may fail with Permission Denied errors.
  • TMOUT conflict (Moderate): Setting a timeout of 900 seconds, or 15 minutes, may terminate DBA SSH or terminal sessions while long-running scripts are executing, such as patching, backups, or heavy queries. For database administration users, this restriction should be adjusted or the TMOUT variable should be temporarily unset during sensitive operations.

4. Audit Procedure

The path of this script in GitHub is: modules/audit_21_System_Accounts_Root_Env.sh

If you are not familiar with Bash scripting, you can refer to the training course published on the website for database administrators: Bash for Oracle DBAs

#!/bin/bash
# Script: audit21.sh
# Purpose: Audit System Accounts, Umask, TMOUT & UID 0 (CIS 5.4.2 & 5.4.3)

echo "=========================================================================="
echo " CIS Requirement: User Accounts and Environment"
echo " - Ensure only 'root' has UID 0."
echo " - Ensure system accounts are non-login (shell /sbin/nologin)."
echo " - Ensure default user umask is 027."
echo " - Ensure TMOUT is 900 or less."
echo " Oracle Context & Exceptions:"
echo " - EXCEPTION: Oracle/Grid users require umask 022 for installation/operation."
echo " - WARNING: TMOUT=900 may disconnect long-running DBA scripts."
echo "=========================================================================="

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

FAIL_COUNT=0

echo -e "\n[*] Checking for UID 0 Accounts..."
UID_0_USERS=$(awk -F: '($3 == 0) { print $1 }' /etc/passwd)
if [ "$UID_0_USERS" == "root" ]; then
    echo -e "  \e[32m[PASS]\e[0m Only 'root' has UID 0."
else
    echo -e "  \e[31m[FAIL]\e[0m Non-root accounts with UID 0 found: $UID_0_USERS"
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] Checking System Accounts (Interactive Shell)..."
MIN_UID=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)
SYS_USERS_WITH_SHELL=$(awk -F: -v min_uid="$MIN_UID" '
    $3 < min_uid && $1 != "root" && $1 != "sync" && $1 != "shutdown" && $1 != "halt" && $7 != "/sbin/nologin" && $7 != "/bin/false" {print $1}
' /etc/passwd)

if [ -z "$SYS_USERS_WITH_SHELL" ]; then
    echo -e "  \e[32m[PASS]\e[0m No system accounts have an interactive shell."
else
    echo -e "  \e[31m[FAIL]\e[0m System accounts with valid shell: $(echo $SYS_USERS_WITH_SHELL | tr '\n' ' ')"
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] Checking Global Umask..."
if grep -q "umask 027" /etc/profile.d/umask.sh 2>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m Default umask 027 is configured."
else
    echo -e "  \e[31m[FAIL]\e[0m Default umask 027 not found in /etc/profile.d/umask.sh."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] Checking TMOUT..."
if grep -Eq "^\s*readonly TMOUT=900" /etc/profile.d/tmout.sh 2>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m TMOUT is securely configured to 900 seconds."
else
    echo -e "  \e[31m[FAIL]\e[0m TMOUT is not correctly set to 900 in /etc/profile.d/tmout.sh."
    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. Bash Remediation Procedure

The path of this script in GitHub is: modules/remediate_21_System_Accounts_Root_Env.sh

#!/bin/bash

# 5.4.3.1 Remove nologin from /etc/shells
sed -i '/nologin/d' /etc/shells

# 5.4.3.2 Configure TMOUT (900 seconds) in a profile drop-in
cat << 'EOF' > /etc/profile.d/tmout.sh
readonly TMOUT=900
export TMOUT
EOF
chmod 0644 /etc/profile.d/tmout.sh

# 5.4.3.3 Configure default umask
cat << 'EOF' > /etc/profile.d/umask.sh
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 027
fi
EOF
chmod 0644 /etc/profile.d/umask.sh

# 5.4.2.7 & 5.4.2.8 Lock system accounts and set shell to nologin
MIN_UID=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)
for user in $(awk -F: -v uid="$MIN_UID" '$3 < uid && $1 != "root" && $1 != "sync" && $1 != "shutdown" && $1 != "halt" {print $1}' /etc/passwd); do
    usermod -s /sbin/nologin "$user"
    usermod -L "$user"
done

# Ensure oracle/grid umask bypass (Oracle DBA Note)
for o_user in oracle grid; do
    if id "$o_user" &>/dev/null; then
        grep -q "umask 022" /home/$o_user/.bash_profile || echo "umask 022" >> /home/$o_user/.bash_profile
    fi
done

echo "System accounts and default environment secured."

In the next part, we will cover Configuring System Integrity Check with AIDE .