History

The S.u.S.E. Genesis (1992)

  • In November 1992, three German mathematicians — Roland Dyroff, Thomas Fehr, Burchard Steinbild — and physics student Hubert Mantel founded S.u.S.E. GmbH (Software und System-Entwicklung) in Nuremberg, Germany.
  • Originally, the company did not build its own Linux distribution; it sold support services, UNIX manuals, and distributed Slackware Linux CD-ROMs.
  • In 1994, S.u.S.E. released its first customized German translation of Slackware Linux, known as S.u.S.E. Linux 1.0.
  • Seeking to build an independent distribution, S.u.S.E. collaborated with the Florian La Roche project (Jurix Linux) and released S.u.S.E. Linux 4.2 in 1996, moving away from Slackware to utilize Jurix’s advanced installer and directory structures.
  • The version number 4.2 was a reference to the Answer to the Ultimate Question of Life, the Universe, and Everything in Douglas Adams’ The Hitchhiker’s Guide to the Galaxy.

The Corporate Acquisitions and Open-Sourcing (2003-2005)

  • S.u.S.E. expanded globally and shortened its brand name to SUSE in the late 1990s.
  • In November 2003, Novell acquired SUSE Linux for $210 million.
  • Under Novell’s governance, the SUSE development model was democratized. Novell open-sourced the proprietary SUSE installation tool, YaST (Yet another Setup Tool), under the GPL license.
  • In August 2005, Novell announced the launch of the openSUSE Project, a community-driven development project backed by SUSE.
  • This marked the bifurcation of the OS into two tracks:
    • SUSE Linux Enterprise Server/Desktop (SLES/SLED): Commercial, certified enterprise versions with long support cycles.
    • openSUSE: Free, community-focused development distribution.

Leap and Tumbleweed: The Split (2014)

  • After Novell was acquired by Attachmate (2010), and later Attachmate merged into Micro Focus (2014), the openSUSE project redefined its release structures.
  • In 2014, openSUSE split its codebase into two distinct distributions to target different developer demographics:
    • openSUSE Tumbleweed: A pure rolling release distribution, updated continuously as upstream packages stabilize.
    • openSUSE Leap: A stable, hybrid release that shares its base source code with SUSE Linux Enterprise (SLE), combining enterprise stability with community packages.
  • SUSE is currently owned by EQT Partners (since 2018) and continues to actively sponsor and govern the openSUSE Project.

Mappings and Lifecycle Timeline

  • openSUSE Leap versions map directly to SUSE Linux Enterprise Server (SLES) Service Packs:
    openSUSE Leap Version   -->   SLES Base Codebase   -->   Release Date
    Leap 42.1               -->   SLES 12 SP1 Base     -->   November 2015
    Leap 15.0               -->   SLES 15 Base         -->   May 2018
    Leap 15.3               -->   SLES 15 SP3 Base     -->   June 2021
    Leap 15.5               -->   SLES 15 SP5 Base     -->   June 2023
    Leap 15.6               -->   SLES 15 SP6 Base     -->   June 2024
    
  • Tumbleweed utilizes no version numbers; it relies on snapshot timestamps representing the build completion dates (e.g., snapshot 20260530).

Introduction

What is openSUSE?

  • openSUSE is a community-driven, stable Linux operating system backed by SUSE Linux and independent sponsors.
  • It is offered in two main formats:
    • openSUSE Leap: A traditional point-release operating system built from the same stable enterprise sources as SUSE Linux Enterprise (SLE).
    • openSUSE Tumbleweed: A rolling-release operating system that updates continually, delivering the latest stable versions of kernels and applications.

Point-Release vs Rolling-Release Models

  • Developers must choose their release track depending on their requirements:
    openSUSE Leap (Point-Release):   [Stable Base 15.5] -------> [Upgrade Pack 15.6] -------> [Upgrade Pack 15.7]
    openSUSE Tumbleweed (Rolling):   [Daily Updates: Kernel, Libs, Apps, Compilers, Tools] (Rolling Snapshot)
    
    • Leap: Designed for production servers, legacy web hosting, and mission-critical applications where API/ABI stability is paramount. Major updates occur annually.
    • Tumbleweed: Designed for software developers, enthusiasts, and workstation power users who require the latest compilers, desktop packages, and hardware drivers. Testing is automated using openSUSE’s advanced openQA system, preventing broken rolling builds.

Advantages of openSUSE

  • YaST Control Center: A centralized, graphical and text-based system administration dashboard.
  • Snapper integration on Btrfs: Native snapshotting on Copy-on-Write Btrfs filesystems enables automatic rollbacks from broken updates.
  • openQA Validation: An automated graphical operating system testing framework that validates point releases and daily Tumbleweed snapshots before they are published.
  • Open Build Service (OBS): A public compile-and-package service that allows developers to build software for openSUSE, Fedora, Debian, Ubuntu, and Arch Linux from a single dashboard.
  • AppArmor Protection: Easy-to-manage path-based security sandboxing active out of the box.

Disadvantages of openSUSE

  • Slower Repository Metadata Loading: Zypper repository parsing can be noticeably slower than Apt or Pacman.
  • Smaller Desktop Ecosystem: Less widespread commercial software packaging (DEB/RPM targets are often tailored to Ubuntu/Red Hat first).
  • YaST Complexity: Centralizing system settings inside YaST can occasionally create conflicts if configurations are edited manually.

Core Use Cases

  • High-Availability Servers: Running Leap on virtualization hypervisors or storage networks.
  • Developer Workstations: Running Tumbleweed to access the latest GCC, Python, Rust, and Go toolchains.
  • Desktop Environments: High-quality implementation of KDE Plasma and GNOME desktops with polished configurations.

openSUSE Leap vs Tumbleweed Comparison

MetricopenSUSE LeapopenSUSE Tumbleweed
Release ModelPoint-Release (Point to Point)Rolling-Release (Continuous)
Software BaseSUSE Linux Enterprise (SLE)Upstream Factory / openQA verified
Kernel UpdatesBackported fixes / conservativeContinuous upstream kernel updates
Package ManagerZypper / RPMZypper / RPM
Target AudienceEnterprise Servers, HypervisorsDevelopers, Linux Enthusiasts
Stability FocusLong-term ABI/API consistencyHigh stability via automated openQA
Default FilesystemBtrfs (system), XFS (data option)Btrfs (Copy-on-Write)

Installation & Setup

System Requirements

  • openSUSE requires the following specifications:
    Metric             -->   Leap Server (Minimal CLI)  -->   Tumbleweed Workstation (GUI)
    CPU Architecture   -->   x86_64, aarch64, PowerPC   -->   x86_64, aarch64
    CPU Cores          -->   1 Core (2 recommended)     -->   2 Cores (4 recommended)
    RAM                -->   1 GB                       -->   4 GB+
    Disk Space         -->   10 GB (Btrfs metadata requires space) --> 40 GB+ (SSD highly recommended)
    Graphics Card      -->   None (Headless)            -->   1024x768 (3D acceleration preferred)
    

ISO Downloading and Verification

  • Download official ISOs from the openSUSE Portal. Verify signatures using gpg:
# Import the openSUSE Project public key
gpg --recv-keys 22C07BA534178C02
 
# Verify the SHA256SUMS file signature
gpg --verify openSUSE-Tumbleweed-DVD-x86_64-Current.iso.sha256.asc
 
# Calculate and match the ISO hash
sha256sum -c openSUSE-Tumbleweed-DVD-x86_64-Current.iso.sha256

The YaST Installer Partition Layout

  • The YaST installer defaults to partitioning the system disk with a standard Btrfs root structure and separate subvolumes to support system rollbacks.
  • Standard partition allocation recommendations for a 100 GB system disk:
    Partition   -->   Size     -->   Type   -->   Mount Point   -->   Description
    /dev/sda1   -->   500 MB   -->   FAT32  -->   /boot/efi     -->   EFI System Partition (ESP)
    /dev/sda2   -->   Rest     -->   Btrfs  -->   /             -->   System Root with subvolumes
    /dev/sda3   -->   8 GB     -->   Swap   -->   [SWAP]        -->   Swap space
    

Btrfs Root Subvolume Structure

  • Default subvolumes created by YaST to isolate user data and transient system paths from OS snapshots (so files like database states or user documents aren’t rolled back):
    Subvolume path       -->   Description
    @                    -->   System Root subvolume (Snapshotted)
    @/home               -->   User home directories (Excluded from rollbacks)
    @/var                -->   Logs, databases, and spools (Excluded from rollbacks)
    @/tmp                -->   Temporary files (Excluded)
    @/srv                -->   Web server root and NFS exports (Excluded)
    @/opt                -->   Third-party applications (Excluded)
    @/usr/local          -->   Custom local files (Excluded)
    @/boot/grub2/i386-pc -->   GRUB files for BIOS (Excluded)
    @/boot/grub2/x86_64  -->   GRUB files for UEFI (Excluded)
    

Copy-on-Write (CoW) Hardening

  • Databases (like MySQL/PostgreSQL) write data using random access in pre-allocated files. Copy-on-Write (CoW) on Btrfs fragments these files, causing performance degradation.
  • Disable CoW on directories containing database storage files:
# 1. Create a clean database storage directory
sudo mkdir -p /var/lib/mysql_nocow
 
# 2. Disable CoW attribute recursively prior to file initialization
sudo chattr +C /var/lib/mysql_nocow
 
# 3. Verify (+C indicates No-CoW is active)
lsattr -d /var/lib/mysql_nocow
# Output: ---------------C------ /var/lib/mysql_nocow

First Boot Configurations

# 1. Update Zypper package repositories database
sudo zypper refresh
 
# 2. Update all packages
sudo zypper dup -y   # Run 'dup' (distribution upgrade) on Tumbleweed
# or
sudo zypper update -y # Run 'update' on Leap
 
# 3. Configure network settings using wicked (if static server)
sudo wicked ifstatus all
 
# 4. Set hostnames
sudo hostnamectl set-hostname opensuse-server.local

Manual CLI Partitioning & Mount Options

  • For advanced headless deployments or custom volume configurations, administrators bypass YaST to partition disks and apply specialized mount parameters:
# 1. Initialize disk partitioning using parted
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart ESP fat32 1MiB 513MiB
sudo parted /dev/sdb --script set 1 esp on
sudo parted /dev/sdb --script mkpart primary btrfs 513MiB 100%
 
# 2. Format partitions
sudo mkfs.vfat -F 32 /dev/sdb1
sudo mkfs.btrfs -L opensuse_sys -f /dev/sdb2

Btrfs System Performance Mount Options

  • Optimize filesystem behavior in /etc/fstab to minimize write cycles, enable compression, and configure space cache version 2:
# Example /etc/fstab entry for SSD-backed openSUSE systems:
UUID=8f87a8b3-3a1a-4c22-9dfc-9b1b46a2a0e2  /  btrfs  defaults,subvol=@,compress=zstd:3,noatime,ssd,discard=async,space_cache=v2  0  0
  • Btrfs mount parameters explained:
    • compress=zstd:3: Utilizes Zstandard level 3 transparent filesystem compression, reducing disk usage and accelerating read/write times by transferring smaller blocks.
    • noatime: Disables modification of file access timestamps, preventing unnecessary write overhead on Btrfs metadata tables.
    • ssd: Directs Btrfs to optimize allocation patterns for solid-state storage device wear levels.
    • discard=async: Enables continuous, non-blocking background TRIM operations for SSD page reclamation.
    • space_cache=v2: Maintains a persistent free-space directory in memory to accelerate disk block search operations.

Kernel & Architecture

Kernel Architecture & SUSE Customizations

  • openSUSE runs custom kernels configured for high virtualization capacity (KVM/Xen integration), extensive storage systems support (Btrfs, XFS, multipath I/O), and security hardening (AppArmor enforcement active).
  • Kernel components:
    +--------------------------------------------------------------+
    |                        User Space Applications               |
    +--------------------------------------------------------------+
    |                    System Call Interface (glibc)             |
    +--------------------------------------------------------------+
    | openSUSE Custom Kernel Space:                                |
    |  [CFS Scheduler]     [Btrfs CoW Engine]   [AppArmor MAC]     |
    |  [Xen/KVM Hypervisor][dm-crypt Encryption][Network Filters]   |
    +--------------------------------------------------------------+
    |                           Hardware Layer                     |
    +--------------------------------------------------------------+
    

Btrfs Filesystem Mechanics

  • Copy-on-Write (CoW): When data in a file is modified, Btrfs does not overwrite the existing block. It writes the updated data block to a new, empty block on disk, and redirects the filesystem pointer metadata to the new location.
  • This ensures that if the system crashes during writing, the original block remains intact, preventing file corruption.
  • Subvolumes: Named internal trees within a Btrfs filesystem that act as independent partition layouts but share the same physical storage pool.
  • Snapshots: Read-only or read-write subvolumes that share the same data blocks as the parent subvolume. Because Btrfs is Copy-on-Write, snapshots are created in time and occupy virtually zero space initially.

The Boot Process with Btrfs Integration

    1. POST / UEFI: Firmware reads the EFI partition and loads the GRUB2 bootloader.
    1. GRUB2 Snapshot Selection: GRUB2 reads configuration files directly from the Btrfs filesystem. If configured, GRUB2 exposes a menu listing read-only system snapshots.
    1. Kernel Loading: GRUB2 loads vmlinuz and initrd directly from the selected Btrfs subvolume.
    1. initrd Execution: The system mounts the initial RAM disk, loads necessary storage drivers, and mounts the active Btrfs subvolume as / (Root).
    1. systemd Launch: systemd runs as PID 1, mounts subvolumes mapped in /etc/fstab, and transitions the system into target states.

GRUB2 Custom Boot Configurations

  • Adjust GRUB2 defaults in /etc/default/grub to enable system snapshot menus:
# Edit grub configuration defaults
sudo vim /etc/default/grub
 
# Key parameters:
# SUSE_BTRFS_SUBVOLUME_SUPPORTED="true"
# GRUB_DISABLE_OS_PROBER="false"
 
# Rebuild the GRUB configuration file
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Sysctl Kernel Network Hardening

  • Standard enterprise systems should apply hardened networking defaults. Write custom configurations to /etc/sysctl.d/90-network-hardening.conf:
# File: /etc/sysctl.d/90-network-hardening.conf
 
# Disable IP forwarding (only set to 1 if node is a router/firewall)
net.ipv4.ip_forward = 0
 
# Reject ICMP redirect packets (mitigates man-in-the-middle spoofing)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
 
# Enable TCP SYN Cookies (protects against SYN flood denial of service)
net.ipv4.tcp_syncookies = 1
 
# Ignore all incoming ICMP echo requests (ignores ping probes)
# net.ipv4.icmp_echo_ignore_all = 1
 
# Log martian packets (packets with impossible source addresses)
net.ipv4.conf.all.log_martians = 1
# Apply sysctl parameters immediately
sudo sysctl --system

Systemd Target Unit Sequences

  • System initialization flow is governed by hierarchical systemd target configurations:
[sysinit.target] (Init hardware, mount Btrfs root)
       |
       v
[basic.target]   (Init drivers, load AppArmor, sockets)
       |
       v
[network.target] (Wait for Wicked interface initializations)
       |
       v
[multi-user.target] (Start network daemons, multi-user console)
       |
       v
[graphical.target]  (Initialize Display Manager: sddm/gdm)

Shell & Terminal

Shell Types in openSUSE

  • bash: The default shell for both root and standard users in openSUSE.
  • zsh: Fully supported; can be configured easily using yast2 or zypper.
  • tcsh: C-shell variant, commonly found in scientific clusters.

Essential Commands Directory

File Operations

pwd                        # Print active directory path
ls -la                     # Detailed directory listing
mkdir -p /srv/www/vhosts/  # Create nested directories
cp -ar /srv/www/ /backup/  # Copy directory recursively preserving attributes
mv file.txt /tmp/          # Move file
rm -rf /tmp/test/          # Force delete directories recursively
ln -s /etc/apache2/ ap_link# Create symbolic link
find /var/log/ -mtime -3   # Find files modified in the last 3 days

Process Control

ps -ef                     # View all running processes
pgrep -u root sshd         # Find PIDs of sshd processes owned by root
kill -15 2045              # Terminate PID 2045 gracefully
kill -9 2045               # Terminate PID 2045 immediately
killall apache2            # Kill all apache2 processes
jobs                       # List background jobs
bg %1                      # Resume job in the background
fg %1                      # Bring job to the foreground

System Metrics

uname -a                   # Display kernel release and architecture info
free -h                    # Show RAM and swap metrics
df -hT                     # Output disk space usage showing filesystem type
du -sh /srv/               # Output disk space used by /srv
uptime                     # Print system running time and average load
lscpu                      # View CPU architecture details
lsblk                      # Display block device layout
ss -tulnp                  # Show listening TCP and UDP sockets with PIDs

Archiving

tar -cvjPf archive.tar.bz2 /etc/ # Create highly compressed bzip2 archive of /etc
tar -xvjPf archive.tar.bz2 -C /tmp/ # Extract bzip2 archive to /tmp
zip -r files.zip /home/user/     # Zip directory
unzip files.zip -d /tmp/         # Unzip file

File Permissions & Access Control Lists (ACLs)

  • Permissions control read (r), write (w), and execute (x) access.
# Set octal permissions: Owner (rwx), Group (r-x), Others (r--)
chmod 754 script.sh
 
# Set permissions symbolically
chmod u+x,go-w script.sh
 
# Change file ownership to user 'wwwrun' (openSUSE default web user) and group 'www'
chown wwwrun:www /srv/www/html/index.html

Granular ACLs using setfacl

# View ACL permissions on a directory
getfacl /srv/www/html/
 
# Grant read-write permissions to user 'developer' on a directory
sudo setfacl -m u:developer:rw- /srv/www/html/
 
# Set default ACL permissions on a directory (applies to future files created)
sudo setfacl -d -m u:developer:rwx /srv/www/html/
 
# Clear all ACL permissions from a directory
sudo setfacl -b /srv/www/html/

I/O Redirection & Pipes

# Redirect standard output (overwrites file)
ls -la /srv/ > /tmp/srv-files.txt
 
# Append standard output to file
echo "Backup finished" >> /var/log/backup.log
 
# Redirect standard error to file
sudo zypper dup -y 2> /tmp/upgrade-errors.log
 
# Redirect both standard output and standard error to file
sudo snapper cleanup &> /var/log/snapper-cleanup.log
 
# Discard error output
find / -name "config.sys" 2> /dev/null
 
# Pipe command output as input to another command
ss -tulnp | grep ":80"

Advanced Text Processing

grep

# Search recursively for "AppArmor" in /var/log
grep -rin "AppArmor" /var/log/
 
# Output count of lines matching search pattern
grep -c "DENIED" /var/log/audit/audit.log

sed

# Replace port 80 with 8080 in Apache's configuration file
sed -i 's/Listen 80/Listen 8080/g' /etc/apache2/listen.conf

awk

# Print system users and their home directories from /etc/passwd
awk -F':' '{print $1 " -> " $6}' /etc/passwd

Shell Scripting Basics

Script 1: openSUSE Service & Memory Auditor

  • Save as sys_audit.sh and make executable: chmod +x sys_audit.sh.
#!/bin/bash
# ==============================================================================
# Script: sys_audit.sh
# Description: Gathers openSUSE memory metrics and logs service status
# Author: VR-Rathod
# ==============================================================================
 
REPORT_FILE="/var/log/opensuse_audit.log"
MAX_MEMORY_PCT=85
 
echo "=== RUNNING SYSTEM AUDIT SCENARIO ==="
 
# Array of core openSUSE processes to audit
SERVICES=("sshd" "wicked" "apparmor")
 
audit_service() {
    local svc=$1
    if systemctl is-active --quiet "$svc"; then
        echo "[OK] Service [$svc] is running." >> "$REPORT_FILE"
    else
        echo "[ALERT] Service [$svc] is stopped!" >> "$REPORT_FILE"
    fi
}
 
# Initialize report file
echo "System Audit Report - $(date)" > "$REPORT_FILE"
echo "======================================" >> "$REPORT_FILE"
 
# Check running processes
for s in "${SERVICES[@]}"; do
    audit_service "$s"
done
 
# Analyze Memory Usage
TOTAL_MEM=$(free | awk '/Mem:/ {print $2}')
USED_MEM=$(free | awk '/Mem:/ {print $3}')
MEM_PCT=$((USED_MEM * 100 / TOTAL_MEM))
 
if [ "$MEM_PCT" -gt "$MAX_MEMORY_PCT" ]; then
    echo "[CRITICAL] Memory usage exceeds threshold: $MEM_PCT%" | tee -a "$REPORT_FILE"
else
    echo "[OK] Memory usage stable at: $MEM_PCT%" >> "$REPORT_FILE"
fi
 
echo "Audit complete. Report written to $REPORT_FILE."
exit 0

Script 2: Automated Snapper Backup & Btrfs snapshotting script

  • Save as /opt/scripts/snapper_backup.sh and configure as a cron task.
#!/bin/bash
# ==============================================================================
# Script: snapper_backup.sh
# Description: Automates Btrfs system snapshotting using Snapper
# Author: VR-Rathod
# ==============================================================================
 
CONFIG_NAME="root"
LOG_FILE="/var/log/snapper_backup.log"
LOCK_FILE="/var/run/snapper_backup.lock"
 
log_msg() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] - $2" | tee -a "$LOG_FILE"
}
 
# Lock file check to prevent concurrent executions
if [ -e "$LOCK_FILE" ]; then
    log_msg "ERROR" "Backup job already running. Exiting."
    exit 1
fi
touch "$LOCK_FILE"
 
# Release lock on exit
cleanup() {
    rm -f "$LOCK_FILE"
}
trap cleanup EXIT
 
log_msg "INFO" "Initializing automated Btrfs root snapshot..."
 
# Verify Snapper config exists
if ! snapper -c "$CONFIG_NAME" list-configs | grep -q "$CONFIG_NAME"; then
    log_msg "ERROR" "Snapper config '$CONFIG_NAME' not found!"
    exit 1
fi
 
# Create a pre-snapshot before cleaning files
PRE_SNAP_ID=$(snapper -c "$CONFIG_NAME" create -t pre -d "Automatic pre-backup maintenance snapshot" -p)
log_msg "INFO" "Created Pre-snapshot ID: $PRE_SNAP_ID"
 
# Perform maintenance (example: clear zypper caches)
log_msg "INFO" "Performing cache cleaning..."
sudo zypper clean -a >> "$LOG_FILE" 2>&1
 
# Create a post-snapshot referencing the pre-snapshot
POST_SNAP_ID=$(snapper -c "$CONFIG_NAME" create -t post --pre-number "$PRE_SNAP_ID" -d "Automatic post-backup maintenance snapshot")
log_msg "INFO" "Created Post-snapshot ID: $POST_SNAP_ID"
 
# Show changes between the snapshots
log_msg "INFO" "Summarizing modifications between states:"
snapper -c "$CONFIG_NAME" status "$PRE_SNAP_ID..$POST_SNAP_ID" >> "$LOG_FILE"
 
log_msg "INFO" "Btrfs snapshot maintenance completed."
exit 0

Script 3: Wicked Network Interface Diagnostic & Recovery Daemon

  • Save as /opt/scripts/wicked_diagnostics.sh to run periodic checks on Wicked interfaces, test network gateway round-trips, log response stats, and auto-restart interfaces on packet-loss thresholds.
#!/bin/bash
# ==============================================================================
# Script: wicked_diagnostics.sh
# Description: Network health monitor and automated recovery for openSUSE Wicked
# Author: VR-Rathod
# ==============================================================================
 
TARGET_IP="8.8.8.8"
INTERFACE="eth0"
LOG_FILE="/var/log/wicked_network.log"
PACKETS=5
LOSS_THRESHOLD=60
 
log_net() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] - $2" | tee -a "$LOG_FILE"
}
 
log_net "INFO" "Starting Wicked interface diagnosis for: $INTERFACE"
 
# Check link state using wicked
LINK_STATE=$(wicked ifstatus "$INTERFACE" | grep "link:" | awk '{print $2}')
log_net "INFO" "Interface Link State: $LINK_STATE"
 
if [ "$LINK_STATE" != "up" ]; then
    log_net "WARNING" "Interface link is DOWN. Attempting system reload..."
    sudo wicked ifup "$INTERFACE" >> "$LOG_FILE" 2>&1
    if [ $? -eq 0 ]; then
        log_net "INFO" "Successfully restored interface link via Wicked."
    else
        log_net "ERROR" "Failed to restore link state. Manual hardware inspection required."
        exit 1
    fi
fi
 
# Execute Ping Test and parse loss metrics
PING_RESULT=$(ping -c "$PACKETS" -I "$INTERFACE" "$TARGET_IP" 2>/dev/null)
if [ $? -ne 0 ]; then
    log_net "ERROR" "Gateway unreachable. Ping operation failed."
    sudo systemctl restart wickedd.service >> "$LOG_FILE" 2>&1
    exit 1
fi
 
LOSS_PCT=$(echo "$PING_RESULT" | grep -oP '\d+(?=% packet loss)')
log_net "INFO" "Gateway ping packet loss: ${LOSS_PCT}%"
 
if [ "$LOSS_PCT" -gt "$LOSS_THRESHOLD" ]; then
    log_net "WARNING" "Packet loss of ${LOSS_PCT}% exceeds threshold! Restarting interface..."
    sudo wicked ifdown "$INTERFACE" && sudo wicked ifup "$INTERFACE" >> "$LOG_FILE" 2>&1
    if [ $? -eq 0 ]; then
        log_net "INFO" "Interface $INTERFACE successfully cycled and recovered."
    else
        log_net "ERROR" "Interface cycle failed."
    fi
else
    log_net "INFO" "Network connection healthy."
fi
 
exit 0

User & Group Management

Account Types

  • Root (Superuser): UID 0. Complete control over operating system variables, filesystems, and security parameters.
  • System Users: UID 1 to 499. Created for running specific system services (e.g., bin, daemon, mail, wwwrun, squid). They do not have login shells.
  • Regular Users: UID 1000+. Created for standard human users and developers.

User Commands

# Create user 'admin-usr' with home directory, default shell, and comment description
sudo useradd -m -s /bin/bash -c "System Administrator Account" admin-usr
 
# Configure user password
sudo passwd admin-usr
 
# Add user to the administration group 'wheel'
sudo usermod -aG wheel admin-usr
 
# Change user shell to zsh
sudo usermod -s /bin/zsh admin-usr
 
# Lock the user account
sudo usermod -L admin-usr
 
# Unlock the user account
sudo usermod -U admin-usr
 
# Delete user and wipe their home directory and mailbox files
sudo userdel -r admin-usr

Group Commands

# Create a new group 'security'
sudo groupadd security
 
# Add user to the group
sudo gpasswd -a admin-usr security
 
# Remove user from the group
sudo gpasswd -d admin-usr security
 
# Delete the group
sudo groupdel security

Configuration Files

  • /etc/passwd: Stores user accounts parameters (read-accessible to all users).
    • Format: username:x:UID:GID:gecos:home_directory:login_shell
  • /etc/shadow: Stores encrypted password hashes and account expiration flags (accessible only by root).
  • /etc/group: Stores group definitions.

Wheel Group & Sudoers Hardening

  • Members of the wheel group are granted administrator privileges via sudo.
# Open the sudoers configuration file safely for editing
sudo visudo
 
# Key rules:
# %wheel ALL=(ALL:ALL) ALL
 
# Allow user 'admin-usr' to run wicked network status queries without password verification
# admin-usr ALL=(ALL) NOPASSWD: /usr/sbin/wicked show

Password Aging Policies

# View password expiration parameters for user 'admin-usr'
sudo chage -l admin-usr
 
# Force user to change password on their next login session
sudo chage -d 0 admin-usr
 
# Set maximum password validity period to 90 days
sudo chage -M 90 admin-usr

Pluggable Authentication Modules (PAM) Password Auditing

  • openSUSE authenticates system logins through PAM config files. Hardening password requirements is accomplished by editing /etc/pam.d/common-password to enforce length and complexity rules.
# Key line addition in /etc/pam.d/common-password:
password  requisite  pam_pwquality.so  retry=3 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 enforce_for_root
  • Parameter metrics:
    • retry=3: Limits user attempts to input a correct password sequence to three times before termination.
    • minlen=14: Requires passwords to contain a minimum of 14 characters.
    • dcredit=-1: Requires a minimum of one numeric character.
    • ucredit=-1: Requires a minimum of one uppercase character.
    • ocredit=-1: Requires a minimum of one special symbol.
    • lcredit=-1: Requires a minimum of one lowercase character.
    • enforce_for_root: Applies password validation rules directly to root (UID 0), preventing simple root credentials.

Package Management (Zypper & OBS)

Zypper Package Manager Architecture

  • Zypper is the default package manager for openSUSE, utilizing the libsolv library for dependency resolution.
  • libsolv: A highly optimized dependency resolver using SAT (satisfiability) algorithms. It parses repository metadata structures quickly, making calculations highly efficient.

Common Zypper Commands

# Search for a package
zypper search apache2
 
# Get details about a package
zypper info apache2
 
# Install a package from enabled repositories
sudo zypper install -y apache2
 
# Install a specific version of a package
sudo zypper install -y apache2-2.4.51
 
# Remove a package
sudo zypper remove -y apache2
 
# List all available repositories
zypper repos -u
 
# Refresh all enabled repositories
sudo zypper refresh
 
# Upgrade all packages (standard updates on Leap)
sudo zypper update -y
 
# Perform full distribution upgrade (required on rolling Tumbleweed)
sudo zypper dup -y
 
# Block a package from being updated
sudo zypper addlock apache2
 
# Remove update lock from a package
sudo zypper removelock apache2

Modularity via Software Patterns

  • openSUSE groups package sets into Patterns, allowing administrators to install entire development environments or server setups with a single command.
# List all available patterns
zypper patterns
 
# Install the LAMP (Linux Apache MySQL PHP) server pattern
sudo zypper install -t pattern lamp_server
 
# Install basis development tools pattern (equivalent to build-essential)
sudo zypper install -t pattern devel_basis

Managing Custom Repositories

# Add a custom repository file (e.g., Packman repository)
sudo zypper addrepo -f -p 90 https://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_Tumbleweed/ packman
 
# Enable auto-refresh on a repository
sudo zypper modifyrepo -r packman
 
# Disable a repository without removing it
sudo zypper modifyrepo -d packman
 
# Remove a repository
sudo zypper removerepo packman

Open Build Service (OBS)

  • The Open Build Service (OBS) is a development platform that automates the building and packaging of software source code into binary packages (RPM, DEB) for various Linux distributions.
  • Developers use the command-line client osc to interact with OBS:
# Install OBS command-line client
sudo zypper install osc -y
 
# Check out a package project from OBS
osc checkout home:developer1:branches/custom-pkg
 
# Commit modifications back to OBS
osc commit -m "Updated source dependencies to version 1.2"

OBS Development Collaboration Flow

  • Developers package applications collaboratively using branch and submit request models:
# 1. Branch an existing package to your namespace repository
osc branch openSUSE:Factory/nginx home:developer1:branches/nginx
 
# 2. Check out the branched files locally
osc checkout home:developer1:branches/nginx
 
# 3. Add custom local files and edit the spec configurations
cd home:developer1:branches/nginx/nginx
# (Make edits to nginx.spec or patches)
 
# 4. Run local build checks to verify compilation success
osc build openSUSE_Tumbleweed x86_64 nginx.spec
 
# 5. Commit modifications back to OBS and issue a submit request
osc commit -m "Added hardened AppArmor variables to build environment"
osc submitreq create home:developer1:branches/nginx openSUSE:Factory/nginx -m "Integrate AppArmor optimizations"

Creating a Custom RPM Spec File

  • Packaging software for openSUSE requires defining metadata, build phases, install directories, and files in a .spec file. Save this example configuration as custom-agent.spec:
# File: custom-agent.spec
Name:           custom-agent
Version:        1.2.0
Release:        1%{?dist}
Summary:        System diagnostics collection daemon
License:        GPLv3+
URL:            https://github.com/developer/custom-agent
Source0:        %{name}-%{version}.tar.gz
BuildRequires:  gcc, make
Requires:       systemd
 
%description
A lightweight diagnostics agent tailored to track CPU execution rates, memory mappings, and write report structures to log targets.
 
%prep
# Extract tarball source contents
%setup -q
 
%build
# Compile binaries using standard make rules
%make_build
 
%install
# Install binaries into target buildroot directories
mkdir -p %{buildroot}%{_bindir}
install -m 0755 bin/custom-agent %{buildroot}%{_bindir}/custom-agent
 
# Install systemd service configurations
mkdir -p %{buildroot}%{_unitdir}
install -m 0644 systemd/custom-agent.service %{buildroot}%{_unitdir}/custom-agent.service
 
%files
# Define files owned by the RPM package
%{_bindir}/custom-agent
%{_unitdir}/custom-agent.service
 
%changelog
* Sat May 30 2026 Developer <dev@enterprise.local> - 1.2.0-1
- Initial packaging build cycle

Networking

Wicked vs NetworkManager

  • openSUSE supports two network configuration systems:
    • Wicked: The default framework for servers, static virtualization nodes, and headless systems. It handles complex, persistent network bridges, bonding, and VLAN topologies through local XML configuration files.
    • NetworkManager: The default system for laptops, desktops, and machines that frequently switch network environments.

Network Commands

# View Wicked network status
sudo wicked show all
 
# Bring up interface 'eth0' using Wicked
sudo wicked ifup eth0
 
# View active IP interface addresses
ip addr show
 
# View active routing tables
ip route show
 
# Display active listening network ports
ss -tulnp
 
# Perform a DNS query lookup
dig opensuse.org

Wicked XML Configuration Files

  • Unlike traditional Debian or RedHat networking configuration directories, Wicked stores persistent interface profiles as XML files inside /etc/wicked/ifconfig/.
<!-- File: /etc/wicked/ifconfig/eth0.xml -->
<interface>
  <name>eth0</name>
  <control>
    <mode>boot</mode>
  </control>
  <connection>
    <type>ethernet</type>
  </connection>
  <ipv4>
    <enabled>true</enabled>
    <address>
<local>192.168.1.50/24</local>
    </address>
  </ipv4>
  <ipv4:route>
    <gateway>192.168.1.1</gateway>
  </ipv4:route>
  <dns>
    <server>8.8.8.8</server>
    <server>1.1.1.1</server>
  </dns>
</interface>
  • To reload or apply changes from these XML configurations:
# Verify the config validation and reload interface using Wicked
sudo wicked ifreload eth0

SSH Server Hardening

  • Secure the OpenSSH daemon by editing /etc/ssh/sshd_config:
# Edit configuration
sudo vim /etc/ssh/sshd_config
 
# Secure settings:
# Port 2233                 # Change port to prevent brute force scans
# PermitRootLogin no        # Force standard users to login and escalate
# PasswordAuthentication no  # Enforce SSH key logins only
# AllowUsers admin-usr      # Restrict login permission to specific user accounts
# MaxAuthTries 3            # Drop connection after 3 failed login attempts
 
# Restart SSH server daemon
sudo systemctl restart sshd

SSH Tunneling Configurations

Local Port Forwarding

ssh -L 8080:127.0.0.1:3306 sysadmin@dbserver.opensuse.local

Remote Port Forwarding

ssh -R 9090:127.0.0.1:80 sysadmin@publicgateway.local

Dynamic SOCKS Proxy

ssh -D 1080 sysadmin@jumpbox.opensuse.local

YaST & Btrfs Snapper Administration

YaST (Yet another Setup Tool) Control Center

  • YaST is openSUSE’s primary administration utility. It runs in three modes:
    • YaST2 GUI: Complete graphical interface for desktop environments.
    • YaST2 CLI: Ncurses-based text user interface (TUI) for SSH and console connections.
    • YaST2 Command Line: Non-interactive command interface for automation scripts.
# Launch the ncurses text-mode YaST interface (TUI)
sudo yast2
 
# Launch specific YaST modules directly:
sudo yast2 firewall       # Configure firewall settings
sudo yast2 bootloader     # Configure GRUB boot loader settings
sudo yast2 network        # Configure interfaces, hostname, routing
sudo yast2 printer        # Configure printing systems
sudo yast2 disk           # Launch Partitioner module (manage disk, LVM, partition mounts)
sudo yast2 software       # Graphical software installer module

Btrfs Snapper Snapshot Management

  • Snapper is the tool designed to manage Btrfs filesystem snapshots.
# Create a snapper configuration for the / mount point
sudo snapper -c root create-config /
 
# List all available snapshots on the root filesystem
snapper list
# Output:
# Single (#) | Type   | Pre # | Date                     | User | Cleanup | Description
# 0          | current|       |                          | root |         | current system state
# 1          | single |       | Wed May 27 10:00:00 2026 | root | timeline| Timeline snapshot
# 2          | pre    |       | Sat May 30 11:00:00 2026 | root | number  | zypper install apache2
# 3          | post   | 2     | Sat May 30 11:02:00 2026 | root | number  | apache2 installation done
 
# Create a manual system snapshot
sudo snapper -c root create -d "Manual snapshot before configurations"
 
# Compare files and directory states between snapshot 2 and snapshot 3
snapper -c root status 2..3
 
# Show text differences for a specific file between snapshot 2 and snapshot 3
snapper -c root diff 2..3 /etc/apache2/httpd.conf
 
# Rollback a single file to its state at snapshot 2
sudo snapper -c root undochange 2..3 /etc/apache2/httpd.conf

Snapper Configuration Retention Policies

  • Snapper configuration variables are managed in /etc/snapper/configs/<config_name>. These variables control how long snapshots are retained before automatic deletion:
# File: /etc/snapper/configs/root
 
# Allow non-root users in group 'wheel' to run snapper commands
ALLOW_GROUPS="wheel"
 
# Snapshots cleanup algorithm selection
NUMBER_CLEANUP="yes"
NUMBER_MIN_AGE="1800"        # Keep snapshots at least 30 minutes
NUMBER_LIMIT="50"            # Maximum number of system snapshots
NUMBER_LIMIT_IMPORTANT="10"
 
# Timeline snapshot parameters (hourly background daemon creation)
TIMELINE_CLEANUP="yes"
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="10"   # Keep last 10 hourly snapshots
TIMELINE_LIMIT_DAILY="7"     # Keep last 7 daily snapshots
TIMELINE_LIMIT_WEEKLY="4"    # Keep last 4 weekly snapshots
TIMELINE_LIMIT_MONTHLY="12"  # Keep last 12 monthly snapshots
TIMELINE_LIMIT_YEARLY="1"    # Keep last 1 yearly snapshot

Snapper System Filesystem Storage Topology

  • Snapper tracks snapshot trees directly under the Btrfs filesystem tree. Snapshot indices, subvolume mappings, and state descriptions are stored as follows:
/ (Root)
├── .snapshots/
│   ├── 1/ (Timeline Backup Node)
│   │   ├── info.xml (Tracks snapshot type, date, description)
│   │   └── snapshot/ (Read-only copy of root subvolume blocks)
│   ├── 2/ (Pre-upgrade Backup Node)
│   │   ├── info.xml
│   │   └── snapshot/
│   └── 3/ (Post-upgrade Backup Node)
│       ├── info.xml
│       └── snapshot/
  • Example info.xml metadata structure:
<!-- File: /.snapshots/2/info.xml -->
<snapshot>
  <type>pre</type>
  <date>2026-05-30 11:00:00</date>
  <description>zypper install apache2</description>
  <cleanup>number</cleanup>
</snapshot>

Full System Recovery Rollback Walkthrough

  • If a system update (or package installation) breaks the operating system boot flow, you can perform a full system rollback:
    System Crash --> Reboot --> Select "Start bootloader from a read-only snapshot" --> Select Snapshot --> System Boots --> Run "snapper rollback" --> Reboot --> System Restored ✓
    
      1. Reboot the system.
      1. In the GRUB2 boot menu, select Start bootloader from a read-only snapshot.
      1. Select a known working snapshot from the chronological list.
      1. The system will boot into the selected snapshot. Note that because Btrfs snapshots are read-only, you cannot write modifications to / at this time.
      1. Log in as root (UID 0).
      1. Execute the rollback command:
    sudo snapper rollback
    # This command makes the current read-only snapshot the default read-write Btrfs root subvolume
      1. Reboot the system normally: sudo reboot.
      1. The system boots into the restored, read-write state.

Enterprise Services

Web Servers Setup (Nginx & PHP-FPM)

  • Deploy a LEMP architecture on openSUSE Leap:
# 1. Install Nginx and PHP-FPM
sudo zypper install -y nginx php8-fpm php8-mysql
 
# 2. Configure PHP-FPM to listen on a Unix socket
# File: /etc/php8/fpm/php-fpm.d/www.conf
# listen = /run/php8-fpm/php-fpm.sock
# listen.owner = nginx
# listen.group = nginx
# listen.mode = 0660
 
# 3. Configure Nginx Server block
# File: /etc/nginx/vhosts.d/site.conf
# server {
#     listen 80;
#     server_name site.opensuse.local;
#     root /srv/www/html;
#     index index.php index.html;
#     location ~ \.php$ {
#         fastcgi_pass unix:/run/php8-fpm/php-fpm.sock;
#         fastcgi_index index.php;
#         include fastcgi_params;
#     }
# }
 
# 4. Enable and start services
sudo systemctl enable --now nginx php-fpm

Production Nginx Virtual Host Configuration with Hardened TLS

  • Write Nginx configurations under /etc/nginx/vhosts.d/ to manage domains and load SSL parameters:
# File: /etc/nginx/vhosts.d/enterprise_app.conf
upstream php_sockets {
    server unix:/run/php8-fpm/php-fpm.sock;
    keepalive 16;
}
 
server {
    listen 80;
    server_name app.opensuse.local;
    return 301 https://$host$request_uri; # Redirect HTTP requests to secure layer
}
 
server {
    listen 443 ssl http2;
    server_name app.opensuse.local;
    root /srv/www/enterprise_app;
    index index.php index.html;
    
    # SSL Certificate configurations
    ssl_certificate /etc/pki/tls/certs/app_prod.crt;
    ssl_certificate_key /etc/pki/tls/private/app_prod.key;
    
    # Harden TLS variables
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    
    # Security headers
    add_header X-Frame-Options "DENY";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php_sockets;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Custom Systemd Service

  • Create a daemon configuration:
# File: /etc/systemd/system/node-app.service
[Unit]
Description=NodeJS Application Daemon
After=network.target
 
[Service]
Type=simple
User=wwwrun
Group=www
WorkingDirectory=/srv/www/node-app/
ExecStart=/usr/bin/node /srv/www/node-app/server.js
Restart=on-failure
 
# Sandboxing Hardening parameters
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
 
[Install]
WantedBy=multi-user.target
# Reload systemd configuration
sudo systemctl daemon-reload
 
# Start service
sudo systemctl enable --now node-app.service

Logrotate Configurations

# File: /etc/logrotate.d/node-app
/var/log/node-app/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0660 wwwrun www
}

Network Storage (NFS & Samba)

NFS Export Setup

# 1. Install NFS server packages
sudo zypper install -y nfs-kernel-server
 
# 2. Add exports to /etc/exports
# /srv/nfs-share 192.168.1.0/24(rw,sync,no_subtree_check)
 
# 3. Start service
sudo systemctl enable --now nfsserver

Samba Share Setup

# 1. Install Samba packages
sudo zypper install -y samba
 
# 2. Edit configurations in /etc/samba/smb.conf
# [shares]
# path = /srv/samba-share
# writable = yes
# guest ok = no
 
# 3. Configure credentials
sudo smbpasswd -a admin-usr

High Availability Setup (Keepalived & HAProxy)

  • Secure enterprise operations require load balancing services and virtual router redundancy setups. Install Keepalived and HAProxy on openSUSE Leap:
# 1. Install packages
sudo zypper install -y keepalived haproxy

HAProxy Reverse Proxy Configuration

  • Configure HAProxy to load balance traffic between two upstream web nodes. Edit /etc/haproxy/haproxy.cfg:
# File: /etc/haproxy/haproxy.cfg
global
    log /dev/log local0
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon
 
defaults
    log     global
    mode    http
    option  httplog
    timeout connect 5000ms
    timeout client  50000ms
    timeout server  50000ms
 
frontend http_front
    bind *:80
    default_backend web_nodes
 
backend web_nodes
    balance roundrobin
    server web1 192.168.1.101:80 check
    server web2 192.168.1.102:80 check

Keepalived Virtual Router Redundancy Configuration

  • Bind a Virtual IP (VIP) to the active balancer instance. Edit /etc/keepalived/keepalived.conf:
# File: /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass SecPwd123
    }
    virtual_ipaddress {
        192.168.1.200/24
    }
}
# Enable and start load balancing services
sudo systemctl enable --now haproxy keepalived

Security Hardening & Ethical Hacking

AppArmor Deep Dive

  • AppArmor is a Mandatory Access Control (MAC) system that limits the resources a process can access (e.g., read, write, execute files, make network connections) by applying path-based security profiles.
  • Unlike SELinux, which is based on security context labels applied to files, AppArmor uses standard path strings to match binaries and define permissions.
  • AppArmor profiles operate in one of three modes:
    • Enforce: Actions violating the profile rules are blocked and logged.
    • Complain: Actions violating rules are allowed, but the violation is logged (useful for profile testing).
    • Disable: Profile is completely inactive.
# Check AppArmor status
sudo aa-status
 
# Set an AppArmor profile to complain mode
sudo aa-complain /usr/sbin/nginx
 
# Set an AppArmor profile to enforce mode
sudo aa-enforce /usr/sbin/nginx

Writing a Custom AppArmor Profile

  • Create a profile to sandbox a script /usr/local/bin/secure_agent.sh that must only read /etc/hosts and write to /var/log/agent.log:
# File: /etc/apparmor.d/usr.local.bin.secure_agent.sh
#include <tunables/global>
 
/usr/local/bin/secure_agent.sh {
    #include <abstractions/base>
    
    # Read capability on shell interpreter
    /usr/bin/bash r,
    
    # Read capability on standard files
    /etc/hosts r,
    
    # Read and Write capability on target log file path
    /var/log/agent.log rw,
    
    # Block access to all other paths
    # ...
}
# Load the newly written profile in enforce mode
sudo apparmor_parser -a /etc/apparmor.d/usr.local.bin.secure_agent.sh
 
# Reload a modified profile
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.secure_agent.sh

Production AppArmor Profile for Apache (httpd2)

  • Secure the Apache web server daemon against potential remote code execution exploits. Save this file configuration as /etc/apparmor.d/usr.sbin.httpd2-prefork:
# File: /etc/apparmor.d/usr.sbin.httpd2-prefork
#include <tunables/global>
 
/usr/sbin/httpd2-prefork {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    
    # Capabilities required by web server daemons
    capability setgid,
    capability setuid,
    capability kill,
    capability chown,
    
    # Shared libraries and dependencies
    /usr/lib64/apache2/*.so mr,
    /usr/lib64/lib*.so* mr,
    
    # Configuration read privileges
    /etc/apache2/** r,
    /etc/mime.types r,
    
    # Web document root directories
    /srv/www/html/** r,
    /srv/www/vhosts/** r,
    
    # Logging permissions
    /var/log/apache2/*.log w,
    /var/run/httpd.pid rw,
    
    # Secure deny overrides to prevent sensitive leaks
    deny /etc/shadow r,
    deny /etc/sudoers r,
}

Firewalld Configuration

  • openSUSE uses firewalld to manage system firewall rules.
# Check active rules
sudo firewall-cmd --list-all
 
# Open HTTP port 80 permanently
sudo firewall-cmd --permanent --add-service=http
 
# Open port 9000 TCP permanently
sudo firewall-cmd --permanent --add-port=9000/tcp
 
# Reload firewall state
sudo firewall-cmd --reload
 
# Add rich rule to restrict access to port 22 to specific IP
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port port="22" protocol="tcp" accept'

Fail2ban Configuration

# Install package
sudo zypper install -y fail2ban
 
# Configure jail defaults
# File: /etc/fail2ban/jail.local
# [sshd]
# enabled = true
# port = ssh
# maxretry = 3
 
# Start service
sudo systemctl enable --now fail2ban

Ethical Hacking & Pentesting openSUSE

  • Security auditors analyze openSUSE systems using structured methodologies (details on general auditing are linked in [[Cybersecurity]] and [[Ethical Hacking Advanced]]).

1. Information Gathering & Port Scanning

  • Perform reconnaissance using nmap:
# Scan for open ports and services
nmap -sS -sV -O 192.168.1.20
 
# Output might expose open ports:
# Port 22 (SSH) -> OpenSSH 9.2
# Port 80 (HTTP) -> Apache 2.4 (openSUSE)

2. Local Privilege Escalation via SUID Binaries

  • If you gain access as a standard user (e.g., admin-usr), search for SUID binaries to escalate privileges to root:
find / -perm -4000 -type f 2>/dev/null
  • If a binary like /usr/bin/cp has the SUID bit set, you can exploit it to overwrite critical system configuration files (like /etc/passwd or /etc/shadow) to escalate privileges:
# Create a modified passwd entry with root privileges (password: password123)
# hash generated via: openssl passwd -6 password123
# Entry: hacker:$6$rounds=40960$salt$hash:0:0:root:/root:/bin/bash
 
# Copy the current passwd file locally and append the entry
cp /etc/passwd /tmp/passwd_mod
echo "hacker:\$6\$salt\$e17.c2.x3s4...:0:0:root:/root:/bin/bash" >> /tmp/passwd_mod
 
# Overwrite /etc/passwd using the privileged SUID cp binary
/usr/bin/cp /tmp/passwd_mod /etc/passwd
 
# Switch to user 'hacker' and log in with root privileges
su - hacker
# Output: root shell prompt (#)

3. Bypassing AppArmor Sandboxing

  • AppArmor profiles restrict binaries from executing sub-processes unless explicitly allowed by the profile rules (e.g., using ix to inherit the parent profile, px to require a discrete profile, or Ux to execute unconfined).
  • If an AppArmor profile for an application contains wildcard write access (e.g., /tmp/* rw), and allows execution of shell commands, security professionals look for escapes:
# If a profile permits executing bash unconfined:
# /usr/bin/bash Ux,
 
# You can call bash from inside the application to run arbitrary commands unconfined, bypassing the profile controls entirely.

4. AppArmor Profile Troubleshooting and Generation

  • Administrators refine profile restrictions using AppArmor diagnostic tools:
# 1. Monitor AppArmor denial logs in real-time
sudo journalctl -fx -t apparmor
# Or monitor direct audit subsystem logs:
sudo tail -f /var/log/audit/audit.log | grep -i apparmor
 
# 2. Run aa-logprof to interactively update profiles based on logs
sudo aa-logprof
# This parses the audit log for AppArmor denials, prompts to allow/deny permissions, and updates profiles.

5. Auditing World-Writable Files and SUID Exploitations

  • Perform regular scripts execution audits to detect unprivileged user privilege escalations:
# Find all world-writable files (indicates security vulnerabilities)
find / -xdev -type f -perm -0002 2>/dev/null
 
# Find orphaned files (files belonging to non-existent UIDs/GIDs)
find / -xdev \( -nouser -o -nogroup \) 2>/dev/null

DSA & System Design in Linux Kernels

How the Kernel Implements Key Data Structures

  • openSUSE administrators and kernel developers study data structures (detailed in [[DSA Algo & System Design]] and [[System Design]]) to optimize filesystem throughput and resource allocations.

1. B-Trees & B+ Trees in Btrfs

  • The Btrfs filesystem uses B-Trees and B+ Trees as its primary structural block engine to store filesystem metadata, including inodes, directory items, directory indexes, and file extent mappings.
Btrfs B+ Tree Indexing Node Layout:
                     [ Key 10 | Key 20 | Key 30 ]  (Internal Index Node)
                     /        |        |        \
                    v         v        v         v
                [Node A]   [Node B] [Node C]  [Node D] (Leaf Nodes containing actual data items)

How the B+ Tree Structure Works

  • A B+ Tree is an -way self-balancing search tree where internal nodes contain only indexing keys, and all leaf nodes contain the actual data elements. Leaf nodes are linked sequentially, enabling fast range queries.
  • In Btrfs, every object (metadata item) has a unique 136-bit key structure:
struct btrfs_key {
    __u64 objectid; /* Unique identifier of the object */
    __u8  type;     /* Type of item (e.g., inode item, directory item) */
    __u64 offset;   /* Offset parameter (e.g., file byte offset) */
};
  • B+ Trees minimize disk accesses by maintaining a high fan-out (each node can hold hundreds of keys), keeping search, insertion, and deletion times constant at .
  • When modifications occur in Btrfs (such as editing file data), the Copy-on-Write mechanism writes the modified tree node to a new block on disk. The parent nodes of that block are then updated to point to the new location, continuing recursively up the tree until a new tree root is committed.

B-Tree Searching and Leaf Node Search Algorithm

  • During file retrieval, the Btrfs driver searches internal indexing nodes of the B+ Tree until it reaches the correct leaf node containing the file extent. The search within a leaf node uses a binary search algorithm since the keys are sorted.
  • Here is a structured implementation of the key binary search algorithm used inside B-Tree leaf nodes:
#include <stdio.h>
 
struct btrfs_item {
    unsigned long key_id;
    unsigned int  data_offset;
    unsigned int  data_size;
};
 
// Searches for a target key in a sorted item list.
// Prevents integer overflow when calculating midpoints.
int btrfs_bin_search(struct btrfs_item *items, int size, unsigned long target_key, int *slot) {
    int low = 0;
    int high = size - 1;
    int mid;
    
    while (low <= high) {
        // Prevent integer overflow during addition
        mid = low + (high - low) / 2;
        
        if (items[mid].key_id == target_key) {
            *slot = mid;
            return 0; // Key found
        }
        
        if (items[mid].key_id < target_key) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    *slot = low; // Insertion position slot
    return -1; // Key not found
}
 
int main() {
    struct btrfs_item leaf[5] = {
        {100, 4000, 120},
        {105, 3880, 120},
        {110, 3760, 120},
        {115, 3640, 120},
        {120, 3520, 120}
    };
    int slot = -1;
    int result = btrfs_bin_search(leaf, 5, 115, &slot);
    if (result == 0) {
        printf("Key found at slot %d!\n", slot);
    } else {
        printf("Key not found. Insert slot: %d\n", slot);
    }
    return 0;
}

B-Tree Layout and Btrfs RAID Implementations

  • Unlike standard filesystems that sit on top of software RAID controllers (like mdadm), Btrfs embeds logical block mapping directly into the B-Tree system.
  • Chunk Tree: The chunk tree maps logical system addresses to physical disk locations, allowing Btrfs to manage multi-device storage volumes internally.
  • Btrfs supports RAID 0, RAID 1 (mirroring data blocks across two drives), RAID 10 (striping mirrors), and experimental RAID 5/6 configurations.
  • When writing in RAID 1, the B-Tree structures calculate duplicate physical addresses and commit writes to two separate block allocations in parallel, ensuring immediate data redundancy without intermediate abstraction layers.

2. Red-Black Trees

  • A Red-Black tree is a self-balancing binary search tree used where insertions and lookups occur frequently.

Completely Fair Scheduler (CFS)

  • The kernel scheduling queue uses a Red-Black tree (rb_root defined in <linux/rbtree.h>) to store running tasks, using virtual runtime (vruntime) as the search key.
  • The task with the smallest runtime (the leftmost node in the tree) is selected for execution next. The kernel maintains a cached pointer to this node, allowing lookups.

Virtual Memory Area (VMA)

  • Memory address maps (vm_area_struct) are organized in a Red-Black tree for each process to allow fast memory address lookups during page faults.

3. Radix Trees

  • A Radix tree maps integer keys to pointers. The Linux kernel uses Radix trees to manage the Page Cache.
  • The Page Cache maps file offset block indices (integers) to memory page descriptors (struct page).
  • Because Radix tree lookups depend only on the key length (constant time ) rather than the number of entries, lookups are extremely fast and cache-efficient.

4. Doubly Linked Lists

  • openSUSE and the Linux kernel use circular doubly linked lists (list_head in <linux/list.h>) to link processes and resources.

C Implementation of Kernel List Traversal

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
 
struct list_head {
    struct list_head *next, *prev;
};
 
static inline void INIT_LIST_HEAD(struct list_head *list) {
    list->next = list;
    list->prev = list;
}
 
static 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;
}
 
static inline void list_add(struct list_head *new_node, struct list_head *head) {
    __list_add(new_node, head, head->next);
}
 
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)
 
#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr) - offsetof(type, member)))
 
struct task_node {
    int id;
    struct list_head list;
};
 
int main() {
    struct list_head task_list;
    INIT_LIST_HEAD(&task_list);
    
    struct task_node *t1 = malloc(sizeof(struct task_node));
    t1->id = 1;
    list_add(&t1->list, &task_list);
    
    struct task_node *t2 = malloc(sizeof(struct task_node));
    t2->id = 2;
    list_add(&t2->list, &task_list);
    
    struct list_head *iter;
    struct task_node *entry;
    
    printf("Traversing circular doubly linked list:\n");
    list_for_each(iter, &task_list) {
        entry = list_entry(iter, struct task_node, list);
        printf("Task ID: %d\n", entry->id);
    }
    
    free(t1);
    free(t2);
    return 0;
}

5. Hash Tables

  • The kernel uses hash tables for lookup tasks, such as resolving files in the dcache (Directory Cache) and resolving processes by PID.

Performance Trade-offs in System Design

StructureLookupInsertionSpaceKernel Use CasesSystem Design Reason
B+ TreeBtrfs MetadataOptimized for disk block storage; high node fan-out reduces I/O access counts.
Red-Black TreeCFS Scheduler, VMABalanced search paths; fast insertion and deletion.
Radix Tree (Constant ) (Constant )Page CacheRapid key search for sparse integer index ranges.
Doubly Linked ListTask Lists, Network Queues updates without requiring dynamic memory allocations.
Hash Table (Average) (Average)dcache, PID tablesFast lookup times; performance degrades under hash collisions.

More Learn

Github & Webs

Master Playlists YouTube