For nearly two decades, CentOS (Community ENTerprise Operating System) was the go-to free, binary-compatible clone of Red Hat Enterprise Linux (RHEL).
On December 8, 2020, Red Hat and the CentOS project announced that CentOS 8 would reach EOL on December 31, 2021 — cutting its life short by nearly a decade.
CentOS would pivot to CentOS Stream, a rolling-release distro that sits upstream of RHEL rather than being a downstream clone.
This meant CentOS Stream would receive changes before RHEL, making it a preview/testing ground — not the stable, production-ready clone the community relied on.
The announcement sent shockwaves through the Linux community. Millions of servers worldwide ran CentOS. Businesses, universities, and developers suddenly needed an alternative.
Gregory Kurtzer Steps Up
Gregory Kurtzer — one of the original co-founders of CentOS — announced on the same day (December 8, 2020) that he would create a new community-driven, RHEL-compatible distribution.
He posted in the CentOS forum: “If this is true, I would like to announce that I will be starting a new project to fill the void that CentOS is leaving behind.”
The project was named Rocky Linux — a tribute to Rocky McGaugh, the other CentOS co-founder who had passed away before seeing CentOS reach its full potential.
Development moved at remarkable speed. A community of thousands rallied around the project within weeks.
Timeline
Dec 8, 2020 → CentOS shift announced; Rocky Linux project announced same day
Dec 2020 → Rocky Linux GitHub org created; community forms
Jan 2021 → Rocky Linux Enterprise Software Foundation (RESF) established
Apr 2021 → Rocky Linux 8.3 Release Candidate published
Jun 21, 2021 → Rocky Linux 8.4 — first stable release (GA)
Nov 2021 → Rocky Linux 8.5 released
Jul 2022 → Rocky Linux 9.0 released (RHEL 9 compatible)
2023-2024 → Rocky Linux 8.x and 9.x point releases continue
Rocky Linux Enterprise Software Foundation (RESF)
Rocky Linux is governed by the RESF — a Public Benefit Corporation (PBC) in Delaware, USA.
Designed to ensure the project remains community-owned and cannot be “pulled” by any single company.
Sponsors include CIQ (Gregory Kurtzer’s company), AWS, Google Cloud, Microsoft Azure, ARM, and others.
Competing alternative: AlmaLinux (created by CloudLinux, also announced in Dec 2020).
Introduction
What is Rocky Linux?
Rocky Linux is a free, open-source, community-driven enterprise Linux distribution that is 1:1 binary compatible with Red Hat Enterprise Linux (RHEL).
It is designed as a drop-in replacement for CentOS — every RPM package, library, and binary behaves identically to its RHEL counterpart.
Targets production servers, enterprise workloads, HPC clusters, cloud deployments, and anyone who needs long-term stability without paying for RHEL subscriptions.
Uses DNF package manager, RPM packages, SELinux enforcing by default, firewalld, systemd — the full RHEL stack.
Rocky Linux vs RHEL vs CentOS Stream vs AlmaLinux
Feature
Rocky Linux
RHEL
CentOS Stream
AlmaLinux
Cost
Free
Paid (free ≤16 systems)
Free
Free
RHEL compatibility
1:1 binary
Source
Upstream preview
1:1 binary
Support lifecycle
10 years
10 years
~5 years
10 years
Governed by
RESF (community)
Red Hat (IBM)
Red Hat (IBM)
AlmaLinux OS Foundation
Release model
Downstream RHEL clone
Enterprise
Rolling (pre-RHEL)
Downstream RHEL clone
Package manager
DNF/RPM
DNF/RPM
DNF/RPM
DNF/RPM
SELinux
Enforcing default
Enforcing default
Enforcing default
Enforcing default
Target
Servers, enterprise
Enterprise
CI/CD, testing
Servers, enterprise
Cloud images
Yes
Yes
Yes
Yes
Sponsor
CIQ, AWS, Google
IBM/Red Hat
Red Hat
CloudLinux
Rocky Linux Editions
Rocky Linux DVD ISO → Full installer with all packages (~10 GB)
Rocky Linux Boot ISO → Minimal network installer (~800 MB)
Rocky Linux Minimal ISO → Minimal offline install (~2 GB)
Rocky Linux Cloud → AWS AMI, Azure, GCP, OpenStack images
Rocky Linux Container → Docker/OCI container images
Rocky Linux Vagrant → Vagrant boxes for dev environments
Rocky Linux Live → Live desktop (GNOME/KDE/XFCE spins)
Advantages
Free RHEL clone — identical binaries, no licensing cost, 10-year support lifecycle.
Enterprise stability — conservative package updates, long-term ABI compatibility.
RHEL skills transfer — everything you learn on Rocky applies directly to RHEL.
SELinux enforcing — strong mandatory access control out of the box.
Large ecosystem — EPEL, PowerTools/CRB, thousands of RPM packages.
Community governed — RESF structure prevents corporate capture.
Excellent cloud support — official images on all major cloud providers.
Cockpit web UI — browser-based server management included.
Disadvantages
Older packages — ships with older (but stable) software versions vs Fedora/Ubuntu.
No rolling updates — major version upgrades require a migration process.
Smaller desktop community — primarily server-focused, desktop experience is secondary.
RHEL source dependency — Rocky rebuilds from RHEL sources; Red Hat’s source access policies can affect rebuild timelines.
Less cutting-edge — not suitable if you need the latest kernel or toolchain versions.
DVD ISO (~10 GB) → Complete offline installer; all package groups included
Best for: air-gapped installs, full control
Boot ISO (~800 MB) → Minimal; downloads packages from internet during install
Best for: always-fresh packages, small download
Minimal ISO (~2 GB) → Offline minimal install; no GUI packages
Best for: servers, containers, scripted installs
Download from: https://rockylinux.org/download
Verify checksum:
# Download the CHECKSUM file alongside the ISOsha256sum -c CHECKSUM --ignore-missing# Or manually:sha256sum Rocky-9.x-x86_64-dvd.iso
Creating Bootable USB
# Linux — using ddsudo dd if=Rocky-9.x-x86_64-dvd.iso of=/dev/sdX bs=4M status=progress oflag=sync# Windows — use Rufus (https://rufus.ie) or Ventoy# macOSsudo dd if=Rocky-9.x-x86_64-dvd.iso of=/dev/rdiskX bs=4m
Anaconda Installer Steps
Rocky Linux uses the Anaconda installer (same as Fedora and RHEL).
1. Boot from USB → select "Install Rocky Linux 9"
2. Language & Keyboard → choose your locale
3. Installation Summary screen (hub-and-spoke model):
┌─ Software Selection ──────────────────────────────┐
│ Base Environment: │
│ • Server with GUI → GNOME + server tools │
│ • Server → CLI only (recommended) │
│ • Minimal Install → bare minimum │
│ • Workstation → desktop environment │
│ • Custom OS → you choose everything │
└───────────────────────────────────────────────────┘
4. Installation Destination → select disk
- Automatic partitioning (recommended):
/boot/efi → 600 MB (EFI, FAT32)
/boot → 1 GB (ext4)
/ → rest (XFS — Rocky default)
swap → auto (or zram on modern systems)
- Custom: LVM is common for enterprise flexibility
5. Network & Hostname → set hostname (e.g., server01.example.com)
6. Root Password → set strong root password (or lock root, use sudo user)
7. User Creation → create admin user, check "Make this user administrator"
8. Begin Installation → ~10-20 minutes
9. Reboot → remove USB
Default Filesystem: XFS
Rocky Linux (like RHEL) defaults to XFS for the root filesystem.
XFS advantages:
• High performance for large files and parallel I/O
• Excellent scalability (supports up to 8 exabytes)
• Online defragmentation and resizing (grow only)
• Journaling for crash recovery
• Default in RHEL/Rocky since RHEL 7
Note: XFS cannot shrink — plan partition sizes carefully.
LVM is recommended for flexibility (can add space later).
First Boot Setup
# Update all packages immediatelysudo dnf update -y# Enable EPEL (Extra Packages for Enterprise Linux)sudo dnf install epel-release -y# Enable CRB (CodeReady Builder) — needed by many EPEL packagessudo dnf config-manager --set-enabled crb# Install common toolssudo dnf install -y vim curl wget git htop net-tools bash-completion \ tar unzip zip bind-utils lsof strace tcpdump# Check SELinux statusgetenforce # should say "Enforcing"sestatus # detailed SELinux status# Check firewall statussudo systemctl status firewalld# Set timezonesudo timedatectl set-timezone Asia/Kolkata # adjust to your zonetimedatectl status# Set hostnamesudo hostnamectl set-hostname myserver.example.com
Kernel & Architecture
RHEL-Compatible Kernel
Rocky Linux ships the same kernel version as RHEL — stable, heavily patched, and enterprise-tested.
Unlike Fedora (which ships the latest upstream kernel), Rocky’s kernel is conservative and backport-heavy.
uname -r # current kernel versionuname -a # full system inforpm -q kernel # all installed kernelssudo dnf list installed kernel*# Rocky 9 ships kernel 5.14.x (RHEL 9 baseline)# Rocky 8 ships kernel 4.18.x (RHEL 8 baseline)# GRUB2 — manage boot entriessudo grub2-mkconfig -o /boot/grub2/grub.cfgsudo grubby --default-kernel # show default kernelsudo grubby --set-default /boot/vmlinuz-<version>sudo grubby --info=ALL # all boot entries
Boot Process
flowchart TD
A[Power On / Reset] --> B[UEFI/BIOS POST]
B --> C[UEFI reads EFI partition\n/boot/efi/EFI/rocky/]
C --> D[GRUB2 Bootloader\n/boot/grub2/grub.cfg]
D --> E[Kernel selected\nvmlinuz-x.x.x]
E --> F[initramfs loaded\ndracut-generated]
F --> G[Kernel decompresses\nand initializes hardware]
G --> H[systemd PID 1 starts]
H --> I[sysinit.target\nmount filesystems, udev]
I --> J[basic.target\nlogging, sockets]
J --> K{Boot target?}
K -->|Server| L[multi-user.target\nCLI login]
K -->|Workstation| M[graphical.target\nGDM login]
Linux File System Hierarchy (FHS) on Rocky
/ Root filesystem (XFS by default)
├── /bin → symlink to /usr/bin (merged-usr since Rocky 9)
├── /boot Kernel, initramfs, GRUB2 config
├── /dev Device files (managed by udev)
├── /etc System-wide configuration files
├── /home User home directories
├── /lib → symlink to /usr/lib
├── /lib64 → symlink to /usr/lib64
├── /media Auto-mount removable media
├── /mnt Manual temporary mount point
├── /opt Optional/third-party software
├── /proc Virtual FS: process and kernel info
├── /root Root user's home directory
├── /run Runtime data (tmpfs, cleared on reboot)
├── /sbin → symlink to /usr/sbin
├── /srv Data served by this system
├── /sys Virtual FS: hardware/driver info (sysfs)
├── /tmp Temporary files (tmpfs or XFS)
├── /usr User programs, libraries, docs
│ ├── /usr/bin User executables
│ ├── /usr/lib Libraries
│ ├── /usr/local Locally compiled software
│ └── /usr/share Architecture-independent data
└── /var Variable data (logs, spool, cache)
├── /var/log System logs
├── /var/lib Application state data
└── /var/spool Print/mail queues
GRUB2 Management
# Edit GRUB defaultssudo vim /etc/default/grub# Key options:# GRUB_TIMEOUT=5 → boot menu timeout in seconds# GRUB_DEFAULT=saved → remember last selection# GRUB_CMDLINE_LINUX="" → kernel parameters# Regenerate GRUB config after changes# UEFI systems:sudo grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg# BIOS/Legacy systems:sudo grub2-mkconfig -o /boot/grub2/grub.cfg# List all kernelssudo grubby --info=ALL# Set default kernelsudo grubby --set-default /boot/vmlinuz-5.14.0-xxx.el9.x86_64# Add kernel parameter (e.g., disable IPv6)sudo grubby --update-kernel=ALL --args="ipv6.disable=1"# Remove kernel parametersudo grubby --update-kernel=ALL --remove-args="ipv6.disable=1"
DNF Package Management
DNF Overview
DNF (Dandified YUM) is the default package manager for Rocky Linux, inherited from RHEL/Fedora.
Handles dependency resolution, transaction history, module streams, and repository management.
flowchart LR
A[User: dnf install nginx] --> B[DNF reads repo metadata]
B --> C[Resolves dependencies]
C --> D[Downloads RPMs\nfrom enabled repos]
D --> E[GPG signature check]
E --> F[RPM transaction\ninstall/upgrade/erase]
F --> G[Run scriptlets\npost-install hooks]
G --> H[Package installed ✓]
Essential DNF Commands
# ── SEARCH & INFO ──────────────────────────────────────dnf search nginx # search by name/descriptiondnf info nginx # detailed package infodnf list available # all available packagesdnf list installed # all installed packagesdnf list updates # available updatesdnf provides /usr/bin/python3 # which package owns a filednf repoquery --list nginx # list files in a packagednf repoquery --requires nginx # show dependencies# ── INSTALL & REMOVE ───────────────────────────────────sudo dnf install nginx # install packagesudo dnf install nginx-1.20.1 # install specific versionsudo dnf install ./local.rpm # install local RPM filesudo dnf remove nginx # remove packagesudo dnf autoremove # remove unused dependenciessudo dnf reinstall nginx # reinstall package# ── UPDATE ─────────────────────────────────────────────sudo dnf update # update all packagessudo dnf update nginx # update specific packagesudo dnf upgrade # alias for updatesudo dnf check-update # check without installing# ── GROUPS ─────────────────────────────────────────────dnf group list # list all package groupsdnf group info "Development Tools" # group detailssudo dnf group install "Development Tools"sudo dnf group remove "Development Tools"# ── HISTORY ────────────────────────────────────────────dnf history # transaction historydnf history info 5 # details of transaction #5sudo dnf history undo 5 # undo transaction #5sudo dnf history rollback 3 # rollback to transaction #3# ── CACHE ──────────────────────────────────────────────sudo dnf clean all # clean all cached datasudo dnf clean packages # clean cached packages onlysudo dnf makecache # rebuild metadata cache
DNF Modules (AppStream)
Rocky Linux uses Application Streams (AppStream) — allows multiple versions of the same software to coexist.
# List all available modulesdnf module list# List specific module streamsdnf module list nodejs# Enable a specific streamsudo dnf module enable nodejs:18# Install module (default profile)sudo dnf module install nodejs:18# Install specific profilesudo dnf module install nodejs:18/development# Switch streams (e.g., PHP 7.4 → 8.1)sudo dnf module reset phpsudo dnf module enable php:8.1sudo dnf module install php:8.1# Disable a modulesudo dnf module disable nodejs:18# Show active module infodnf module info nodejs
Repository Management
# List all reposdnf repolistdnf repolist all # including disabled repos# Enable/disable a reposudo dnf config-manager --set-enabled powertools # Rocky 8sudo dnf config-manager --set-enabled crb # Rocky 9sudo dnf config-manager --set-disabled crb# Add a repo manuallysudo dnf config-manager --add-repo https://example.com/repo.repo# Repo files locationls /etc/yum.repos.d/
Rocky Linux Default Repos
baseos → Core OS packages (kernel, glibc, systemd)
appstream → Application packages + module streams
extras → Extra packages not in RHEL
crb → CodeReady Builder (Rocky 9) / PowerTools (Rocky 8)
→ Needed for EPEL and development headers
# Query installed packagesrpm -qa # list all installed packagesrpm -qi nginx # package inforpm -ql nginx # list files in packagerpm -qf /etc/nginx/nginx.conf # which package owns this filerpm -qR nginx # package dependencies# Install/verify RPM filessudo rpm -ivh package.rpm # install with verbose + hashsudo rpm -Uvh package.rpm # upgradesudo rpm -e nginx # erase/removerpm -V nginx # verify package integrityrpm -Va # verify all packages# GPG keysrpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficialrpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
Shell & Terminal
Default Shell: Bash
Rocky Linux uses Bash (Bourne Again Shell) as the default shell — same as RHEL.
echo $SHELL # /bin/bashbash --version # GNU bash versioncat /etc/shells # all available shellschsh -s /bin/zsh # change your shell to zsh
Essential Commands
# ── NAVIGATION ─────────────────────────────────────────pwd # print working directoryls -la # list with hidden files + detailsls -lh # human-readable sizescd /etc # change directorycd ~ # go to homecd - # go to previous directory# ── FILE OPERATIONS ────────────────────────────────────cp -r src/ dest/ # copy recursivelymv file.txt /tmp/ # move/renamerm -rf dir/ # remove recursively (careful!)mkdir -p a/b/c # create nested directoriestouch file.txt # create empty file / update timestampln -s /etc/nginx nginx_link # symbolic linkln /etc/hosts hosts_hard # hard link# ── VIEWING FILES ───────────────────────────────────────cat /etc/os-release # view fileless /var/log/messages # paginated viewhead -20 file.log # first 20 linestail -f /var/log/messages # follow log in real timegrep -r "error" /var/log/ # recursive searchgrep -i "failed" auth.log # case-insensitive# ── DISK & SYSTEM ───────────────────────────────────────df -h # disk usage (human-readable)du -sh /var/log/ # directory sizefree -h # memory usagetop # process monitorhtop # better process monitor (install via EPEL)ps aux # all running processesps aux | grep nginx # find specific processkill -9 PID # force kill processkillall nginx # kill by name# ── ARCHIVES ────────────────────────────────────────────tar -czf archive.tar.gz dir/ # create gzip archivetar -xzf archive.tar.gz # extract gzip archivetar -cjf archive.tar.bz2 dir/ # create bzip2 archivetar -xjf archive.tar.bz2 # extract bzip2 archivezip -r archive.zip dir/ # create zipunzip archive.zip # extract zip
File Permissions
# Permission format: [type][owner][group][others]# Example: -rwxr-xr-- 1 root wheel 4096 Jan 1 12:00 script.sh# d = directory, - = file, l = symlink# r=4, w=2, x=1chmod 755 script.sh # rwxr-xr-xchmod 644 config.conf # rw-r--r--chmod +x script.sh # add execute for allchmod u+x,g-w file # symbolic modechmod -R 755 /var/www/ # recursivechown user:group file # change owner and groupchown -R nginx:nginx /var/www/html/chgrp wheel file # change group only# Special permissionschmod 4755 file # setuid (runs as owner)chmod 2755 dir/ # setgid (new files inherit group)chmod 1777 /tmp # sticky bit (only owner can delete)# View permissionsls -la filestat file # detailed file info including permissions
Shell Scripting Basics
#!/bin/bash# Rocky Linux bash script example# VariablesNAME="Rocky"VERSION=9echo "Welcome to $NAME Linux $VERSION"# Conditionalsif [ -f /etc/rocky-release ]; then echo "This is Rocky Linux"elif [ -f /etc/redhat-release ]; then echo "This is a RHEL-family distro"else echo "Unknown distro"fi# Loopsfor pkg in nginx vim curl; do sudo dnf install -y "$pkg"done# Functionscheck_service() { if systemctl is-active --quiet "$1"; then echo "$1 is running" else echo "$1 is NOT running" fi}check_service nginxcheck_service sshd# Read user inputread -p "Enter hostname: " HOSTNAMEsudo hostnamectl set-hostname "$HOSTNAME"
User & Group Management
User Account Types
root (UID 0) → superuser, full system access
System users → UID 1-999, for services (nginx, postgres, etc.)
Regular users → UID 1000+, human users
User Commands
# Create usersudo useradd username # basic user creationsudo useradd -m -s /bin/bash -c "Full Name" username # with home + shellsudo useradd -u 1500 -g developers username # specific UID/GID# Set passwordsudo passwd username# Modify usersudo usermod -aG wheel username # add to wheel (sudo) groupsudo usermod -aG docker,nginx username # add to multiple groupssudo usermod -s /bin/zsh username # change shellsudo usermod -l newname oldname # rename usersudo usermod -L username # lock accountsudo usermod -U username # unlock account# Delete usersudo userdel username # keep home directorysudo userdel -r username # remove home + mail spool# View user infoid username # UID, GID, groupswhoami # current userwho # logged-in usersw # who + what they're doinglast # login historycat /etc/passwd # user databasegetent passwd username # user entry
Group Commands
sudo groupadd developers # create groupsudo groupadd -g 2000 developers # with specific GIDsudo groupmod -n devs developers # rename groupsudo groupdel developers # delete group# View groupsgroups username # user's groupscat /etc/group # group databasegetent group wheel # specific group
The wheel Group & sudo
On Rocky Linux (like RHEL), the wheel group grants sudo access.
# Add user to wheel groupsudo usermod -aG wheel username# Verifygroups username # should show "wheel"# sudo configurationsudo visudo # safely edit /etc/sudoers# /etc/sudoers key lines:# %wheel ALL=(ALL) ALL → wheel group can sudo (with password)# %wheel ALL=(ALL) NOPASSWD: ALL → no password (less secure)# User-specific sudo rule (in /etc/sudoers.d/)echo "username ALL=(ALL) NOPASSWD: /usr/bin/dnf" | sudo tee /etc/sudoers.d/username
Password Policies
# View password aging infosudo chage -l username# Set password expiry (90 days)sudo chage -M 90 username# Force password change on next loginsudo chage -d 0 username# Set minimum days between changessudo chage -m 7 username# Password policy in /etc/login.defsgrep -E "PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_WARN_AGE" /etc/login.defs
Systemd & Service Management
systemctl Essentials
# ── SERVICE CONTROL ────────────────────────────────────sudo systemctl start nginx # start servicesudo systemctl stop nginx # stop servicesudo systemctl restart nginx # stop + startsudo systemctl reload nginx # reload config (no downtime)sudo systemctl enable nginx # start on bootsudo systemctl disable nginx # don't start on bootsudo systemctl enable --now nginx # enable + start immediatelysudo systemctl disable --now nginx # disable + stop immediately# ── STATUS & INFO ───────────────────────────────────────systemctl status nginx # service status + recent logssystemctl is-active nginx # active/inactivesystemctl is-enabled nginx # enabled/disabledsystemctl is-failed nginx # failed/not-failedsystemctl list-units --type=service # all active servicessystemctl list-units --type=service --all # including inactivesystemctl list-unit-files --type=service # all + enabled state# ── SYSTEM TARGETS ──────────────────────────────────────systemctl get-default # current default targetsudo systemctl set-default multi-user.target # set CLI defaultsudo systemctl set-default graphical.target # set GUI defaultsudo systemctl isolate rescue.target # switch to rescue mode# ── SYSTEM POWER ────────────────────────────────────────sudo systemctl reboot # rebootsudo systemctl poweroff # shutdownsudo systemctl halt # halt (no power off)sudo systemctl suspend # suspend to RAM
journalctl — Log Management
# View all logsjournalctl # all logs (oldest first)journalctl -r # reverse (newest first)journalctl -f # follow (like tail -f)journalctl -n 50 # last 50 lines# Filter by servicejournalctl -u nginx # nginx logs onlyjournalctl -u nginx -f # follow nginx logsjournalctl -u nginx --since today # today's nginx logs# Filter by timejournalctl --since "2024-01-01 00:00:00"journalctl --since "1 hour ago"journalctl --since yesterday --until today# Filter by priorityjournalctl -p err # errors onlyjournalctl -p warning # warnings and above# Priorities: emerg, alert, crit, err, warning, notice, info, debug# Filter by bootjournalctl -b # current bootjournalctl -b -1 # previous bootjournalctl --list-boots # all boot sessions# Kernel messagesjournalctl -k # kernel messages (like dmesg)dmesg | tail -20 # recent kernel messages# Disk usagejournalctl --disk-usagesudo journalctl --vacuum-size=500M # keep only 500MB of logssudo journalctl --vacuum-time=30d # keep only last 30 days
# List all booleansgetsebool -agetsebool -a | grep httpd# Common booleanssudo setsebool -P httpd_can_network_connect on # allow Apache to connect to networksudo setsebool -P httpd_can_network_connect_db on # allow Apache → databasesudo setsebool -P httpd_use_nfs on # allow Apache to use NFSsudo setsebool -P httpd_execmem on # allow Apache to execute memorysudo setsebool -P allow_user_exec_content on # allow users to run content# -P flag makes the change persistent across reboots
SELinux Port Management
# List ports for a typesudo semanage port -l | grep httpsudo semanage port -l | grep ssh# Add a custom port (e.g., Nginx on port 8080)sudo semanage port -a -t http_port_t -p tcp 8080# Modify existing port labelsudo semanage port -m -t http_port_t -p tcp 8080# Remove custom portsudo semanage port -d -t http_port_t -p tcp 8080
# Install AIDE (Advanced Intrusion Detection Environment)sudo dnf install aide -y# Initialize the database (takes a few minutes)sudo aide --initsudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz# Run a check (compare current state vs baseline)sudo aide --check# Update database after legitimate changessudo aide --updatesudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz# Schedule daily checks via cronecho "0 3 * * * root /usr/sbin/aide --check | mail -s 'AIDE Report' admin@example.com" \ | sudo tee /etc/cron.d/aide
dnf-automatic — Automatic Security Updates
sudo dnf install dnf-automatic -y# Configuresudo vim /etc/dnf/automatic.conf
# /etc/dnf/automatic.conf[commands]upgrade_type = security # only security updates (or 'default' for all)apply_updates = yes # auto-apply (or 'no' to just download)download_updates = yes[emitters]emit_via = email[email]email_from = root@localhostemail_to = admin@example.comemail_host = localhost
# Enable the timersudo systemctl enable --now dnf-automatic.timersudo systemctl status dnf-automatic.timer
Lynis — Security Auditing
# Install Lynis (from EPEL)sudo dnf install lynis -y# Run full system auditsudo lynis audit system# View reportcat /var/log/lynis.logcat /var/log/lynis-report.dat# Lynis gives a hardening index score and specific recommendations# Focus on "Suggestions" and "Warnings" in the output
-- Create database and userCREATE DATABASE myapp;CREATE USER myuser WITH ENCRYPTED PASSWORD 'strongpassword';GRANT ALL PRIVILEGES ON DATABASE myapp TO myuser;\q
# Configure remote accesssudo vim /var/lib/pgsql/data/postgresql.conf# listen_addresses = 'localhost' → change to '*' for remotesudo vim /var/lib/pgsql/data/pg_hba.conf# Add: host myapp myuser 192.168.1.0/24 md5sudo systemctl restart postgresqlsudo firewall-cmd --permanent --add-service=postgresqlsudo firewall-cmd --reload
Cockpit is a browser-based server management interface — included in Rocky Linux.
# Install Cockpitsudo dnf install cockpit -ysudo systemctl enable --now cockpit.socket# Open firewallsudo firewall-cmd --permanent --add-service=cockpitsudo firewall-cmd --reload# Access at: https://your-server-ip:9090# Login with your system username and password# Install additional Cockpit modulessudo dnf install cockpit-machines # VM management (libvirt)sudo dnf install cockpit-podman # container managementsudo dnf install cockpit-storaged # storage managementsudo dnf install cockpit-networkmanager # network management
Podman — Rootless Containers
# Podman is available in Rocky Linux repossudo dnf install podman podman-compose -y# Run a container (rootless — no sudo needed)podman run -d --name nginx -p 8080:80 nginx:latest# List containerspodman pspodman ps -a # including stopped# Manage containerspodman stop nginxpodman start nginxpodman rm nginxpodman logs nginx# Pull imagespodman pull rockylinux:9podman images# Run Rocky Linux containerpodman run -it rockylinux:9 bash# Generate systemd unit for containerpodman generate systemd --name nginx --files --new