securing oracle linux 9 article 15 configuring and securing host based firewall

In the previous section, we covered Securing Network Configuration and Kernel Parameters.

1. CIS Benchmark Requirements (Section 4)

  • 4.1 Configure a firewall utility
  • 4.1.1 Ensure nftables is installed (Automated)
  • 4.1.2 Ensure a single firewall configuration utility is in use (Automated)
  • 4.2 Configure FirewallD
  • 4.2.1 Ensure firewalld drops unnecessary services and ports (Manual)
  • 4.2.2 Ensure firewalld loopback traffic is configured (Automated)

2. Concept & Rationale

Concept: The CIS standard emphasizes that the system must have a Host-Based Firewall, and to prevent rule conflicts, only one firewall management tool should be active. In Oracle Linux 9, the firewalld service is the default tool, using nftables as the processing engine (Backend).

Security Rationale: Closing unnecessary ports and configuring Loopback traffic (blocking spoofed 127.0.0.0/8 requests from outside) protects the system against IP address spoofing attacks and unauthorized network access.

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

Conflict Status: None (provided that Public network ports are accurately configured and the Private network is explicitly Trusted).

Oracle Requirements and Considerations:

The firewall service (firewalld) blocks all incoming communications by default. For stable operation of the database, Grid Infrastructure, client connectivity, and monitoring tools, adhering to the following firewall requirements is critical:

1. Public Network: The following ports must be allowed in the firewall:

  • SSH Ports: Standard port 22 and any custom ports (e.g., 22022).
  • Listener Ports: Local Listener and SCAN Listener (default ports 1521 and 1522, or custom ports like 7654).
  • ONS Service Port: Oracle Notification Service (typically port 6200).
  • OEM Agent Port: Oracle Enterprise Manager (typically port 3872).

2. RAC Private Interconnect Network:

Oracle uses a wide and dynamic range of TCP and UDP ports for internal communication between cluster nodes (Interconnect). In RAC environments, it is mandatory to place the private network interface (e.g., eth1 or ens192) in the trusted firewall zone. This allows cluster traffic to flow unrestricted between nodes; otherwise, nodes will experience communication timeouts, leading to Node Eviction and cluster failure.

4. Audit (Audit Script)

The following script audits the status of the firewall tool, the configured Backend, and currently open ports:

GitHub link for this script: modules/audit_15_Host_Based_Firewall.sh

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

#!/bin/bash
# Script: audit15.sh
# Purpose: Audit Script for Firewall (CIS 4)

echo "=========================================================================="
echo " CIS Requirement: 4 Firewall Configuration"
echo " - Ensure firewalld is active and using nftables backend."
echo " Oracle Context:"
echo " - CRITICAL: Oracle RAC requires specific public ports (1521, 1522, 6200)."
echo " - CRITICAL: RAC Private Interconnect interface MUST be trusted."
echo "=========================================================================="

FAIL_COUNT=0

echo -e "\n[*] Checking firewalld service status..."
if systemctl is-active firewalld.service &>/dev/null; then
    echo -e "  \e[32m[PASS]\e[0m firewalld is active and running."
else
    echo -e "  \e[31m[FAIL]\e[0m firewalld is not active."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] Checking FirewallBackend in firewalld.conf..."
BACKEND=$(grep -i '^FirewallBackend' /etc/firewalld/firewalld.conf | cut -d= -f2)
if [ "$BACKEND" == "nftables" ]; then
    echo -e "  \e[32m[PASS]\e[0m FirewallBackend is set to nftables."
else
    echo -e "  \e[31m[FAIL]\e[0m FirewallBackend is set to $BACKEND (Expected: nftables)."
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

echo -e "\n[*] Checking currently open ports (Public Zone)..."
PORTS=$(firewall-cmd --list-ports 2>/dev/null)
if [ -n "$PORTS" ]; then
    echo -e "  \e[34m[INFO]\e[0m Open ports: $PORTS"
else
    echo -e "  \e[34m[INFO]\e[0m No ports explicitly opened in default zone."
fi

echo -e "\n[*] Checking Trusted Interfaces (For RAC Private Interconnect)..."
TRUSTED_IFACES=$(firewall-cmd --zone=trusted --list-interfaces 2>/dev/null)
if [ -n "$TRUSTED_IFACES" ]; then
    echo -e "  \e[32m[PASS]\e[0m Trusted interfaces found: $TRUSTED_IFACES"
else
    echo -e "  \e[33m[WARN]\e[0m No interfaces in 'trusted' zone. (Ensure RAC interconnect is trusted!)"
fi

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

5. Remediation (Remediation Script)

The following script configures the firewalld service, enforces the Backend, and opens the necessary ports for Oracle and system management.

GitHub link for this script: modules/remediate_15_Host_Based_Firewall.sh

#!/bin/bash
# Script: remediation15.sh
# Purpose: Configure firewalld with nftables and Oracle RAC Rules (CIS 4)

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

echo "=========================================================================="
echo " Applying Remediation for CIS 4 (Firewall)"
echo " Oracle Context: Setting nftables, opening RAC Public ports,"
echo " and prompting for RAC Private Interconnect setup."
echo "=========================================================================="

echo -e "\n[*] Configuring firewalld..."

# 1. Ensure firewalld is running
systemctl unmask firewalld >/dev/null 2>&1
systemctl enable --now firewalld >/dev/null 2>&1
echo -e "  \e[32m[OK]\e[0m Enabled and started firewalld."

# 2. Enforce FirewallBackend=nftables
sed -i 's/^FirewallBackend=.*/FirewallBackend=nftables/' /etc/firewalld/firewalld.conf
systemctl restart firewalld
echo -e "  \e[32m[OK]\e[0m FirewallBackend set to nftables."

# 3. Add Required Oracle RAC/Grid and SSH ports
# 1521 (Listener), 1522 (SCAN), 6200 (ONS), 3872 (OEM), 7654 (Custom), 22/22022 (SSH)
PORTS=("22/tcp" "22022/tcp" "1521/tcp" "1522/tcp" "6200/tcp" "7654/tcp" "3872/tcp")

for PORT in "${PORTS[@]}"; do
    firewall-cmd --permanent --add-port="$PORT" >/dev/null 2>&1
done
echo -e "  \e[32m[OK]\e[0m Added standard Oracle RAC and admin ports."

# 4. RAC Private Interconnect Handling
echo -e "\n\e[33m[?] Do you want to add a Private Interface (Interconnect) to the 'trusted' zone for RAC? (y/n)\e[0m"
read -r add_trusted
if [[ "$add_trusted" =~ ^[Yy]$ ]]; then
    echo -e "Enter the private interface name (e.g., eth1, ens192):"
    read -r priv_iface
    if [ -n "$priv_iface" ]; then
        firewall-cmd --permanent --zone=trusted --add-interface="$priv_iface" >/dev/null 2>&1
        echo -e "  \e[32m[OK]\e[0m Added $priv_iface to trusted zone."
    fi
fi

# 5. Reload and Show
firewall-cmd --reload >/dev/null 2>&1
echo -e "\n\e[32m[+] REMEDIATION APPLIED SUCCESSFULLY\e[0m"

echo -e "\nActive Ports in default zone:"
firewall-cmd --list-ports
echo "Trusted Interfaces:"
firewall-cmd --zone=trusted --list-interfaces

In the next section, we will cover:
Configuring and Securing SSH Service (CIS 5.1)