#!/bin/bash set -e set -o pipefail # ====================================================================== # Variables TZ="US/Eastern" NAMED_CONF_URL="https://cache.cne.mcnc.org/named.tar.gz" NGINX_CONF_URL="https://cache.cne.mcnc.org/nginx.tar.gz" # ====================================================================== # 0. Pre-flight Checks # ====================================================================== echo ">>> Starting Pre-flight checks..." # Check if running as root if [ "$EUID" -ne 0 ]; then echo "Error: Please run as root (sudo)." exit 1 fi # OS Compatibility Check if [ -f /etc/os-release ]; then . /etc/os-release case "$ID" in rhel|rocky|almalinux|fedora|centos) echo "OS Check: Supported system detected ($NAME)." ;; *) echo "Error: This script is only for RHEL, Rocky, AlmaLinux, or Fedora." echo "Detected: $NAME ($ID)" exit 1 ;; esac else echo "Error: /etc/os-release not found. Unknown OS." exit 1 fi # Function to check URL reachability without downloading check_url() { echo -n "Checking availability of $1 ... " if curl --output /dev/null --silent --head --fail "$1"; then echo "OK" else echo "FAILED" echo "Error: Cannot reach $1. Stopping execution." exit 1 fi } check_url "$NAMED_CONF_URL" check_url "$NGINX_CONF_URL" echo ">>> All checks passed." # ====================================================================== # 1. Virtualization Detection # ====================================================================== # Detect virtualization technology to install specific guest agents VIRT_TYPE=$(systemd-detect-virt) VM_AGENT="" echo ">>> Checking Virtualization Environment..." case "$VIRT_TYPE" in vmware) echo " Detected: VMware. Queueing 'open-vm-tools'." VM_AGENT="open-vm-tools" ;; kvm|qemu) echo " Detected: KVM/QEMU. Queueing 'qemu-guest-agent'." VM_AGENT="qemu-guest-agent" ;; microsoft) echo " Detected: Hyper-V. Queueing 'hyperv-daemons'." VM_AGENT="hyperv-daemons" ;; none) echo " Detected: Bare Metal (Physical). No agents needed." ;; *) echo " Detected: $VIRT_TYPE. No standard RHEL agent package identified." ;; esac # ====================================================================== # 2. System Setup & Package Installation # ====================================================================== echo ">>> Setting timezone and updating system..." timedatectl set-timezone $TZ # Combine installs to save transaction time. # We include $VM_AGENT in this list to avoid a separate DNF transaction. echo ">>> Installing required packages..." dnf upgrade -y dnf install -y \ cockpit tar tuned dnf-automatic \ nginx nginx-mod-stream \ bind bind-utils \ policycoreutils-python-utils \ $VM_AGENT # Enable basic services systemctl enable --now cockpit.socket # If we installed a VM agent, ensure it's enabled and started if [ ! -z "$VM_AGENT" ]; then echo ">>> Enabling Guest Agent ($VM_AGENT)..." # Identify service name (usually matches package name, but qemu-guest-agent is different) if [ "$VM_AGENT" == "qemu-guest-agent" ]; then systemctl enable --now qemu-guest-agent elif [ "$VM_AGENT" == "open-vm-tools" ]; then systemctl enable --now vmtoolsd elif [ "$VM_AGENT" == "hyperv-daemons" ]; then # Hyper-V daemons are often socket-activated or split services, # but enabling the package install usually triggers the presets. : fi fi # ====================================================================== # 3. Security (Zscaler Root CA) # ====================================================================== echo ">>> Injecting Zscaler CA..." tee /etc/pki/ca-trust/source/anchors/ZscalerRootCertificate-2048-SHA256.crt > /dev/null << 'EOF' -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIJANu+mC2Jt3uTMA0GCSqGSIb3DQEBCwUAMIGhMQswCQYD VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2Ux FTATBgNVBAoTDFpzY2FsZXIgSW5jLjEVMBMGA1UECxMMWnNjYWxlciBJbmMuMRgw FgYDVQQDEw9ac2NhbGVyIFJvb3QgQ0ExIjAgBgkqhkiG9w0BCQEWE3N1cHBvcnRA enNjYWxlci5jb20wHhcNMTQxMjE5MDAyNzU1WhcNNDIwNTA2MDAyNzU1WjCBoTEL MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBK b3NlMRUwEwYDVQQKEwxac2NhbGVyIEluYy4xFTATBgNVBAsTDFpzY2FsZXIgSW5j LjEYMBYGA1UEAxMPWnNjYWxlciBSb290IENBMSIwIAYJKoZIhvcNAQkBFhNzdXBw b3J0QHpzY2FsZXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA qT7STSxZRTgEFFf6doHajSc1vk5jmzmM6BWuOo044EsaTc9eVEV/HjH/1DWzZtcr fTj+ni205apMTlKBW3UYR+lyLHQ9FoZiDXYXK8poKSV5+Tm0Vls/5Kb8mkhVVqv7 LgYEmvEY7HPY+i1nEGZCa46ZXCOohJ0mBEtB9JVlpDIO+nN0hUMAYYdZ1KZWCMNf 5J/aTZiShsorN2A38iSOhdd+mcRM4iNL3gsLu99XhKnRqKoHeH83lVdfu1XBeoQz z5V6gA3kbRvhDwoIlTBeMa5l4yRdJAfdpkbFzqiwSgNdhbxTHnYYorDzKfr2rEFM dsMU0DHdeAZf711+1CunuQIDAQABo4IBCjCCAQYwHQYDVR0OBBYEFLm33UrNww4M hp1d3+wcBGnFTpjfMIHWBgNVHSMEgc4wgcuAFLm33UrNww4Mhp1d3+wcBGnFTpjf oYGnpIGkMIGhMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8G A1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFpzY2FsZXIgSW5jLjEVMBMGA1UECxMM WnNjYWxlciBJbmMuMRgwFgYDVQQDEw9ac2NhbGVyIFJvb3QgQ0ExIjAgBgkqhkiG 9w0BCQEWE3N1cHBvcnRAenNjYWxlci5jb22CCQDbvpgtibd7kzAMBgNVHRMEBTAD AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAw0NdJh8w3NsJu4KHuVZUrmZgIohnTm0j+ RTmYQ9IKA/pvxAcA6K1i/LO+Bt+tCX+C0yxqB8qzuo+4vAzoY5JEBhyhBhf1uK+P /WVWFZN/+hTgpSbZgzUEnWQG2gOVd24msex+0Sr7hyr9vn6OueH+jj+vCMiAm5+u kd7lLvJsBu3AO3jGWVLyPkS3i6Gf+rwAp1OsRrv3WnbkYcFf9xjuaf4z0hRCrLN2 xFNjavxrHmsH8jPHVvgc1VD0Opja0l/BRVauTrUaoW6tE+wFG5rEcPGS80jjHK4S pB5iDj2mUZH1T8lzYtuZy0ZPirxmtsk3135+CKNa2OCAhhFjE0xd -----END CERTIFICATE----- EOF update-ca-trust extract # ====================================================================== # 4. Unattended Upgrades # ====================================================================== echo ">>> Configuring dnf-automatic..." sed -i 's/reboot = never/reboot = when-needed/' /etc/dnf/automatic.conf mkdir -p /etc/systemd/system/dnf-automatic-install.timer.d tee /etc/systemd/system/dnf-automatic-install.timer.d/time.conf > /dev/null <>> Applying Sysctl tweaks..." tee /etc/sysctl.d/90-nginx-tuning.conf > /dev/null <>> Configuring Nginx..." mkdir -p /var/cache/nginx/cache chown -R nginx:nginx /var/cache/nginx/cache mkdir -p /etc/nginx/stream.d mkdir -p /etc/systemd/system/nginx.service.d tee /etc/systemd/system/nginx.service.d/nofile_limit.conf > /dev/null << 'EOF' [Service] LimitNOFILE=200000 EOF echo "Downloading Nginx config..." curl -fL "$NGINX_CONF_URL" -o /tmp/nginx.tar.gz tar xvf /tmp/nginx.tar.gz -C / rm -f /tmp/nginx.tar.gz systemctl daemon-reload systemctl enable --now nginx.service # ====================================================================== # 7. SELinux & Firewall # ====================================================================== echo ">>> Applying Firewall and SELinux rules..." # Consolidate firewall calls firewall-cmd --add-service=http \ --add-service=https \ --add-service=http3 \ --add-service=dns firewall-cmd --runtime-to-permanent # SELinux semanage import <>> Configuring Bind9..." tee -a /etc/sysconfig/named > /dev/null << 'EOF' OPTIONS="-4" EOF echo "Downloading Named config..." curl -fL "$NAMED_CONF_URL" -o /tmp/named.tar.gz tar xvf /tmp/named.tar.gz -C / rm -f /tmp/named.tar.gz systemctl enable --now named.service echo ">>> Installation Complete."