Enhancing Linux Kernel Security: The kernel.sh Script

In this script, we aim to enhance Linux kernel security by setting critical parameters and applying safeguards across multiple distributions. Kernel hardening is an essential step in securing any Linux environment, reducing vulnerabilities, and adding layers of defense against potential attacks.

Enhancing Linux Kernel Security: The kernel.sh Script

In this post, we’ll dive into another of my Linux automation scripts from my GitHub repository. This kernel.sh script is part of a series focused on configuring Linux systems automatically. With this script, we aim to enhance Linux kernel security by setting critical parameters and applying safeguards across multiple distributions. Kernel hardening is an essential step in securing any Linux environment, reducing vulnerabilities, and adding layers of defense against potential attacks.

1. Purpose of the kernel.sh Script

The purpose of kernel.sh is to implement basic kernel security hardening through:

  • Setting system kernel parameters for enhanced protection
  • Configuring security modules (e.g., AppArmor, SELinux)
  • Installing essential security tools
  • Running rootkit scans for immediate vulnerability detection

Let’s break down each part of the script and explain how these measures contribute to a more secure system.

2. Script Breakdown

Here’s the full code:

#!/bin/bash

# Function to check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as root" 
        exit 1
    fi
}

# Function to check the distribution and set appropriate package manager
set_package_manager() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        case "$ID" in
            ubuntu|debian)
                PACKAGE_MANAGER="apt"
                ;;
            centos|rhel|fedora)
                PACKAGE_MANAGER="dnf"
                ;;
            arch|manjaro)
                PACKAGE_MANAGER="pacman"
                ;;
            suse|opensuse)
                PACKAGE_MANAGER="zypper"
                ;;
            *)
                echo "Unsupported distribution: $ID"
                exit 1
                ;;
        esac
    else
        echo "Unable to detect the Linux distribution."
        exit 1
    fi
}

# Function to update kernel parameters in /etc/sysctl.conf
update_sysctl() {
    echo "==> Updating kernel parameters in /etc/sysctl.conf"
    # Example kernel hardening parameters
    cat <<EOL >> /etc/sysctl.conf
# Kernel Hardening Parameters
kernel.randomize_va_space = 2
kernel.kptr_restrict = 1
kernel.dmesg_restrict = 1
kernel.panic = 10
kernel.exec-shield = 1
kernel.suid_dumpable = 0
kernel.pty.max = 1024
fs.protected_symlinks = 1
fs.protected_regular = 1
EOL
    sysctl -p
}

# Function to configure AppArmor or SELinux based on distribution
configure_security_modules() {
    echo "==> Configuring security modules"
    case "$ID" in
        ubuntu|debian)
            systemctl enable apparmor
            systemctl start apparmor
            ;;
        centos|rhel|fedora)
            setenforce 1
            sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
            ;;
        *)
            echo "No specific security module configuration for this distribution."
            ;;
    esac
}

# Function to install necessary security packages
install_security_packages() {
    echo "==> Installing necessary security packages"
    case "$PACKAGE_MANAGER" in
        apt)
            apt update
            apt install -y rkhunter chkrootkit
            ;;
        dnf)
            dnf install -y rkhunter chkrootkit
            ;;
        pacman)
            pacman -Syu --noconfirm rkhunter chkrootkit
            ;;
        zypper)
            zypper install -y rkhunter chkrootkit
            ;;
    esac
}

# Function to run rootkit checks
run_rootkit_checks() {
    echo "==> Running rootkit checks"
    rkhunter --update
    rkhunter --check
    chkrootkit
}

# Main script execution
check_root
set_package_manager
update_sysctl
configure_security_modules
install_security_packages
run_rootkit_checks

echo "Kernel hardening and configuration completed successfully."

3. Step-by-Step Explanation

Step 1: Ensuring Root Privileges

The first function, check_root, confirms that the script is being executed with root privileges. Many kernel-level configurations require root access, so we halt execution if the script isn’t run as root:

check_root() {
    if [[ $EUID -ne 0 ]]; then
        echo "This script must be run as root" 
        exit 1
    fi
}

Step 2: Setting the Package Manager Based on Distribution

The set_package_manager function identifies the package manager based on the system’s Linux distribution. It reads the ID field from /etc/os-release, which contains the system’s identification information:

set_package_manager() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        case "$ID" in
            ubuntu|debian)
                PACKAGE_MANAGER="apt"
                ;;
            centos|rhel|fedora)
                PACKAGE_MANAGER="dnf"
                ;;
            arch|manjaro)
                PACKAGE_MANAGER="pacman"
                ;;
            suse|opensuse)
                PACKAGE_MANAGER="zypper"
                ;;
            *)
                echo "Unsupported distribution: $ID"
                exit 1
                ;;
        esac
    else
        echo "Unable to detect the Linux distribution."
        exit 1
    fi
}

Step 3: Updating Kernel Hardening Parameters in sysctl.conf

The update_sysctl function sets specific kernel parameters to tighten security. It appends a list of parameters to /etc/sysctl.conf and then applies them using sysctl -p. Key parameters include:

  • kernel.randomize_va_space = 2: Enables full address space layout randomization (ASLR).
  • kernel.dmesg_restrict = 1: Limits access to kernel messages.
  • fs.protected_symlinks = 1: Helps prevent symbolic link attacks.
update_sysctl() {
    echo "==> Updating kernel parameters in /etc/sysctl.conf"
    cat <<EOL >> /etc/sysctl.conf
# Kernel Hardening Parameters
kernel.randomize_va_space = 2
kernel.kptr_restrict = 1
kernel.dmesg_restrict = 1
kernel.panic = 10
kernel.exec-shield = 1
kernel.suid_dumpable = 0
kernel.pty.max = 1024
fs.protected_symlinks = 1
fs.protected_regular = 1
EOL
    sysctl -p
}

Step 4: Configuring Security Modules (AppArmor or SELinux)

The configure_security_modules function detects the distribution and configures either AppArmor (for Debian-based systems) or SELinux (for Red Hat-based systems). For example, it sets SELinux to enforcing mode on CentOS and RHEL:

configure_security_modules() {
    echo "==> Configuring security modules"
    case "$ID" in
        ubuntu|debian)
            systemctl enable apparmor
            systemctl start apparmor
            ;;
        centos|rhel|fedora)
            setenforce 1
            sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
            ;;
    esac
}

Step 5: Installing Security Tools (rkhunter and chkrootkit)

The install_security_packages function installs rkhunter and chkrootkit to detect rootkits and signs of unauthorized activity:

install_security_packages() {
    echo "==> Installing necessary security packages"
    case "$PACKAGE_MANAGER" in
        apt)
            apt update
            apt install -y rkhunter chkrootkit
            ;;
        dnf)
            dnf install -y rkhunter chkrootkit
            ;;
    esac
}

Step 6: Running Rootkit Checks

The run_rootkit_checks function executes rkhunter and chkrootkit scans to detect any potential rootkits or vulnerabilities:

run_rootkit_checks() {
    echo "==> Running rootkit checks"
    rkhunter --update
    rkhunter --check
    chkrootkit
}

Final Step: Execution and Completion Message

After calling each function, the script displays a success message:

echo "Kernel hardening and configuration completed successfully."

Conclusion

This kernel hardening script provides a reliable baseline for securing Linux systems across distributions. By standardizing kernel parameters, configuring security modules, and installing essential monitoring tools, this script helps to create a more secure operating environment.

Read next

Automating GRUB Configuration Across Linux Distributions

In this post, we’re going to explore the grub.sh script, which is designed to handle the configuration and hardening of GRUB across various Linux distributions. We’ll go over each line of the script to understand what it does and how it contributes to the overall configuration.