Introduction
Rocky Linux has emerged as a leading enterprise Linux distribution, providing a stable, secure, and community-driven alternative for production environments. After completing the installation, proper initial configuration is critical for establishing a secure, optimized, and manageable system. This comprehensive guide walks through essential first steps to transform a fresh Rocky Linux installation into a production-ready server.
System Verification and Initial Access
Verify Rocky Linux Installation
# Verify system installation details
cat /etc/rocky-release
cat /etc/os-release
# Check system information
hostnamectl status
# Display kernel information
uname -a
uname -r
# Check system architecture
arch
lscpu | grep Architecture
# Verify installation media
rpm -qa | grep rocky-release
# Check system resources
free -h
df -h
lsblk
# Display hardware information
dmidecode -t system
dmidecode -t processor
dmidecode -t memory
Configure System Hostname
# Set appropriate hostname
hostnamectl set-hostname rocky-server.example.com
# Verify hostname configuration
hostnamectl status
# Update hosts file
cat > /etc/hosts << EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
$(hostname -I | awk '{print $1}') rocky-server.example.com rocky-server
EOF
# Verify hosts file
cat /etc/hosts
# Test hostname resolution
hostname
hostname -f
hostname -d
System Updates and Repository Management
Configure DNF Package Manager
# Optimize DNF configuration
cat >> /etc/dnf/dnf.conf << 'EOF'
# Performance and reliability settings
fastestmirror=True
max_parallel_downloads=10
deltarpm=True
keepcache=True
clean_requirements_on_remove=True
best=True
skip_if_unavailable=True
install_weak_deps=False
EOF
# Clean package manager cache
dnf clean all
dnf makecache
# Import Rocky Linux GPG keys
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
# Update system packages
dnf update -y
# Install essential tools
dnf install -y \
epel-release \
vim-enhanced \
nano \
wget \
curl \
git \
rsync \
net-tools \
bind-utils \
lsof \
bash-completion \
policycoreutils-python-utils \
setroubleshoot-server \
yum-utils \
device-mapper-persistent-data \
lvm2 \
htop \
iotop \
iftop \
tmux \
screen \
tree \
unzip \
bzip2 \
tar \
tcpdump \
traceroute \
mtr \
nmap-ncat \
telnet \
strace \
sysstat
# Install development tools (optional)
dnf groupinstall -y "Development Tools"
# Remove unnecessary packages
dnf autoremove -y
Enable Additional Repositories
# Enable PowerTools/CRB repository
dnf config-manager --set-enabled crb
# Install EPEL repository
dnf install -y epel-release
# Install ELRepo for kernel and hardware support
dnf install -y elrepo-release
# Install Remi repository (for newer PHP versions)
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
# Configure repository priorities
dnf install -y dnf-plugins-core
dnf config-manager --save --setopt=baseos.priority=1
dnf config-manager --save --setopt=appstream.priority=1
dnf config-manager --save --setopt=crb.priority=2
dnf config-manager --save --setopt=epel.priority=10
# List enabled repositories
dnf repolist enabled
# Update repository metadata
dnf makecache
Network Configuration and Optimization
Configure Network Settings
# Display network interfaces
ip link show
nmcli device status
nmcli connection show
# Configure primary network interface
INTERFACE="enp0s3" # Adjust to your interface name
# Set static IP configuration
nmcli connection modify "$INTERFACE" ipv4.method manual
nmcli connection modify "$INTERFACE" ipv4.addresses 192.168.1.10/24
nmcli connection modify "$INTERFACE" ipv4.gateway 192.168.1.1
nmcli connection modify "$INTERFACE" ipv4.dns "8.8.8.8 8.8.4.4"
nmcli connection modify "$INTERFACE" ipv4.dns-search "example.com"
# Configure IPv6 (if required)
nmcli connection modify "$INTERFACE" ipv6.method auto
nmcli connection modify "$INTERFACE" ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"
# Set connection to auto-connect
nmcli connection modify "$INTERFACE" connection.autoconnect yes
nmcli connection modify "$INTERFACE" connection.autoconnect-priority 100
# Apply network changes
nmcli connection up "$INTERFACE"
# Verify network configuration
ip addr show
ip route show
cat /etc/resolv.conf
Network Performance Optimization
# Create network optimization configuration
cat > /etc/sysctl.d/99-network-tuning.conf << 'EOF'
# Network stack tuning for Rocky Linux
# Core network settings
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.rmem_default = 4194304
net.core.wmem_default = 4194304
net.core.optmem_max = 40960
net.core.netdev_max_backlog = 50000
net.core.somaxconn = 65535
# TCP settings
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 6
net.ipv4.tcp_synack_retries = 2
# IP settings
net.ipv4.ip_forward = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.ip_local_port_range = 10000 65535
# IPv6 settings
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
EOF
# Apply network optimizations
sysctl -p /etc/sysctl.d/99-network-tuning.conf
Security Hardening
Configure Firewall
# Install and enable firewalld
dnf install -y firewalld
systemctl enable --now firewalld
# Check firewall status
firewall-cmd --state
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
# Set default zone
firewall-cmd --set-default-zone=public
# Configure essential services
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
# Configure custom ports (examples)
firewall-cmd --permanent --zone=public --add-port=10050/tcp # Zabbix agent
firewall-cmd --permanent --zone=public --add-port=9090/tcp # Cockpit
# Remove unnecessary services
firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client
firewall-cmd --permanent --zone=public --remove-service=mdns
firewall-cmd --permanent --zone=public --remove-service=samba-client
# Configure source-based rules (example)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" accept'
# Enable logging for dropped packets
firewall-cmd --permanent --set-log-denied=all
# Reload firewall configuration
firewall-cmd --reload
# Verify firewall rules
firewall-cmd --list-all
firewall-cmd --get-services
firewall-cmd --list-ports
SELinux Configuration
# Verify SELinux status
sestatus
getenforce
# Ensure SELinux is enforcing
setenforce 1
# Make enforcement permanent
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
# Install SELinux management tools
dnf install -y \
setools-console \
policycoreutils-python-utils \
selinux-policy-doc \
setroubleshoot-server
# Configure SELinux booleans for common services
# Allow httpd to connect to network
setsebool -P httpd_can_network_connect on
setsebool -P httpd_can_network_relay on
# Allow httpd to send mail
setsebool -P httpd_can_sendmail on
# Configure for FTP (if needed)
setsebool -P ftpd_anon_write off
setsebool -P ftpd_full_access off
# Check SELinux denials
ausearch -m avc -ts recent
sealert -a /var/log/audit/audit.log
# Create custom SELinux module (example)
cat > myapp.te << 'EOF'
module myapp 1.0;
require {
type httpd_t;
type httpd_sys_content_t;
class file { read write };
}
allow httpd_t httpd_sys_content_t:file { read write };
EOF
# Compile and install custom module
checkmodule -M -m -o myapp.mod myapp.te
semodule_package -o myapp.pp -m myapp.mod
semodule -i myapp.pp
SSH Security Hardening
# Backup original SSH configuration
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date +%Y%m%d)
# Create hardened SSH configuration
cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
# SSH Security Hardening Configuration
# Protocol and Port
Protocol 2
Port 22
AddressFamily any
ListenAddress 0.0.0.0
# Host Keys
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# Authentication
PermitRootLogin prohibit-password
PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
MaxAuthTries 3
MaxSessions 10
AuthorizedKeysFile .ssh/authorized_keys
# Security Features
StrictModes yes
IgnoreRhosts yes
HostbasedAuthentication no
UsePAM yes
X11Forwarding no
PrintMotd yes
PrintLastLog yes
TCPKeepAlive yes
Compression delayed
UseDNS no
PermitUserEnvironment no
# Login Controls
LoginGraceTime 60
ClientAliveInterval 300
ClientAliveCountMax 2
MaxStartups 10:30:60
# Access Restrictions
AllowUsers *
DenyUsers root bin daemon adm lp sync shutdown halt mail news uucp operator games nobody
AllowGroups wheel admins
# Crypto Settings
Ciphers [email protected],[email protected],[email protected],aes128-ctr,aes192-ctr,aes256-ctr
MACs [email protected],[email protected],[email protected]
KexAlgorithms curve25519-sha256,[email protected],diffie-hellman-group-exchange-sha256
# Logging
SyslogFacility AUTH
LogLevel INFO
# Banner
Banner /etc/issue.net
EOF
# Create login banner
cat > /etc/issue.net << 'EOF'
***************************************************************************
AUTHORIZED ACCESS ONLY
***************************************************************************
This system is for authorized use only. By accessing this system, you
agree that your actions may be monitored and recorded. Unauthorized
access is strictly prohibited and will be prosecuted to the full extent
of the law. If you are not an authorized user, disconnect immediately.
***************************************************************************
EOF
# Test SSH configuration
sshd -t
# Restart SSH service
systemctl restart sshd
# Configure SSH keys for admin user
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# Generate SSH key pair (if needed)
ssh-keygen -t ed25519 -C "admin@rocky-server"
User Management and Access Control
Create Administrative Users
# Create admin group
groupadd -g 2000 admins
# Create system administrator account
useradd -m -u 1001 -g admins -G wheel -c "System Administrator" -s /bin/bash sysadmin
# Set secure password
passwd sysadmin
# Create additional admin users
useradd -m -u 1002 -g admins -G wheel -c "DevOps Engineer" -s /bin/bash devops
passwd devops
# Configure sudo access
cat > /etc/sudoers.d/admins << 'EOF'
# Admin group sudo configuration
%admins ALL=(ALL:ALL) ALL
%wheel ALL=(ALL:ALL) ALL
# Allow password-less sudo for specific commands
%admins ALL=(ALL) NOPASSWD: /usr/bin/systemctl status *, /usr/bin/journalctl
%admins ALL=(ALL) NOPASSWD: /usr/bin/dnf check-update
# Command aliases
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl restart *
Cmnd_Alias MONITORING = /usr/bin/top, /usr/bin/htop, /usr/bin/iotop
%admins ALL=(ALL) NOPASSWD: SERVICES, MONITORING
EOF
# Verify sudoers syntax
visudo -c -f /etc/sudoers.d/admins
# Configure password policies
authselect select sssd with-mkhomedir --force
authconfig --enablereqlower --enablerequpper --enablereqdigit --enablereqother --passminlen=12 --passmaxrepeat=3 --update
# Set password aging policies
for user in sysadmin devops; do
chage -M 90 -m 7 -W 14 -I 30 $user
done
# Display password policies
chage -l sysadmin
Configure System Limits
# Set user resource limits
cat > /etc/security/limits.d/99-admins.conf << 'EOF'
# Resource limits for admin users
# Default limits for all users
* soft nofile 65536
* hard nofile 65536
* soft nproc 16384
* hard nproc 16384
* soft stack 10240
* hard stack 32768
* soft memlock unlimited
* hard memlock unlimited
# Enhanced limits for admin group
@admins soft nofile 131072
@admins hard nofile 131072
@admins soft nproc 32768
@admins hard nproc 32768
@admins soft priority -10
@admins hard priority -10
# Database user limits (example)
@postgres soft nofile 262144
@postgres hard nofile 262144
@postgres soft nproc 65536
@postgres hard nproc 65536
EOF
# Configure systemd limits
mkdir -p /etc/systemd/system.conf.d
cat > /etc/systemd/system.conf.d/limits.conf << 'EOF'
[Manager]
DefaultLimitNOFILE=65536:524288
DefaultLimitNPROC=16384:65536
DefaultTasksMax=65536
DefaultLimitMEMLOCK=infinity
DefaultLimitCORE=infinity
EOF
# Configure user systemd limits
mkdir -p /etc/systemd/user.conf.d
cat > /etc/systemd/user.conf.d/limits.conf << 'EOF'
[Manager]
DefaultLimitNOFILE=32768:65536
DefaultLimitNPROC=8192:16384
DefaultTasksMax=16384
EOF
# Reload systemd configuration
systemctl daemon-reload
System Monitoring and Logging
Configure System Logging
# Configure rsyslog
cat > /etc/rsyslog.d/99-rocky-custom.conf << 'EOF'
# Custom Rocky Linux logging configuration
# Log all kernel messages
kern.* /var/log/kernel.log
# Log authentication messages
auth,authpriv.* /var/log/secure
# Log cron jobs
cron.* /var/log/cron
# Log mail system
mail.* -/var/log/maillog
# Emergency messages to all users
*.emerg :omusrmsg:*
# Custom application logs
local0.* /var/log/local0.log
local1.* /var/log/local1.log
# Remote syslog server (if configured)
# *.* @@remote-syslog:514
# Log rotation prevention for some logs
& stop
EOF
# Configure advanced logging
cat > /etc/rsyslog.d/10-templates.conf << 'EOF'
# Define custom log format templates
$template CustomFormat,"%timegenerated% %hostname% %syslogtag% %msg%\n"
$template LogFile,"/var/log/hosts/%hostname%/%programname%.log"
# Use custom template for specific logs
*.* ?LogFile;CustomFormat
EOF
# Configure journald
mkdir -p /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-custom.conf << 'EOF'
[Journal]
# Storage configuration
Storage=persistent
Compress=yes
Seal=yes
# Size limits
SystemMaxUse=2G
SystemKeepFree=1G
SystemMaxFileSize=200M
SystemMaxFiles=10
# Runtime limits
RuntimeMaxUse=1G
RuntimeKeepFree=500M
RuntimeMaxFileSize=100M
RuntimeMaxFiles=5
# Retention
MaxRetentionSec=3month
MaxFileSec=1week
# Forwarding
ForwardToSyslog=yes
ForwardToKMsg=no
ForwardToConsole=no
ForwardToWall=yes
# Rate limiting
RateLimitInterval=30s
RateLimitBurst=10000
# Audit
Audit=yes
EOF
# Restart logging services
systemctl restart rsyslog
systemctl restart systemd-journald
# Configure logrotate
cat > /etc/logrotate.d/custom << 'EOF'
/var/log/kernel.log
/var/log/local*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 root root
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
EOF
Enable System Auditing
# Install audit system
dnf install -y audit audit-libs
# Enable and start auditd
systemctl enable --now auditd
# Configure audit rules
cat > /etc/audit/rules.d/99-rocky-custom.rules << 'EOF'
# Remove any existing rules
-D
# Set buffer size
-b 8192
# Set failure mode
-f 1
# Monitor user and group changes
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity
# Monitor sudoers changes
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope
# Monitor SSH configuration
-w /etc/ssh/sshd_config -p wa -k sshd_config
-w /etc/ssh/sshd_config.d/ -p wa -k sshd_config
# Monitor system calls
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time_change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time_change
-a always,exit -F arch=b64 -S clock_settime -k time_change
-a always,exit -F arch=b32 -S clock_settime -k time_change
# Monitor file permission changes
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
# Monitor unauthorized access attempts
-a always,exit -F arch=b64 -S open -S openat -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b64 -S open -S openat -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
# Make configuration immutable
-e 2
EOF
# Load audit rules
augenrules --load
# Check audit status
auditctl -l
auditctl -s
Performance Tuning and Optimization
System Performance Tuning
# Install tuned
dnf install -y tuned tuned-utils
# Enable and start tuned
systemctl enable --now tuned
# List available profiles
tuned-adm list
# Recommend profile based on system
tuned-adm recommend
# Set appropriate profile
# For virtual machines
tuned-adm profile virtual-guest
# For physical servers
# tuned-adm profile throughput-performance
# For web servers
# tuned-adm profile web-server
# Verify active profile
tuned-adm active
tuned-adm verify
# Create custom tuned profile
mkdir -p /etc/tuned/rocky-custom
cat > /etc/tuned/rocky-custom/tuned.conf << 'EOF'
[main]
summary=Custom Rocky Linux Performance Profile
include=throughput-performance
[cpu]
governor=performance
energy_perf_bias=performance
min_perf_pct=100
[disk]
devices=sd*
elevator=mq-deadline
readahead=4096
[vm]
transparent_hugepages=never
[sysctl]
vm.swappiness=10
vm.dirty_ratio=15
vm.dirty_background_ratio=5
vm.vfs_cache_pressure=50
kernel.sched_migration_cost_ns=5000000
kernel.sched_autogroup_enabled=0
net.core.busy_read=50
net.core.busy_poll=50
EOF
# Activate custom profile
tuned-adm profile rocky-custom
Memory and Swap Configuration
# Configure swap
# Check current swap
swapon --show
free -h
# Create swap file (4GB example)
dd if=/dev/zero of=/swapfile bs=1G count=4
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# Make swap permanent
echo '/swapfile none swap sw,pri=10 0 0' >> /etc/fstab
# Configure swap parameters
cat > /etc/sysctl.d/99-swap.conf << 'EOF'
# Swap configuration
vm.swappiness=10
vm.page-cluster=0
vm.vfs_cache_pressure=50
EOF
# Apply swap settings
sysctl -p /etc/sysctl.d/99-swap.conf
# Configure zswap (compressed swap in RAM)
echo 1 > /sys/module/zswap/parameters/enabled
echo lz4 > /sys/module/zswap/parameters/compressor
echo z3fold > /sys/module/zswap/parameters/zpool
# Make zswap permanent
cat > /etc/modules-load.d/zswap.conf << 'EOF'
lz4
lz4_compress
z3fold
EOF
Service Management and Automation
Configure Essential Services
# Disable unnecessary services
systemctl disable --now cups
systemctl disable --now bluetooth
systemctl disable --now avahi-daemon
systemctl disable --now mdns
systemctl mask bluetooth
systemctl mask cups
# Enable essential services
systemctl enable --now crond
systemctl enable --now sshd
systemctl enable --now NetworkManager
systemctl enable --now firewalld
systemctl enable --now tuned
systemctl enable --now auditd
# Configure time synchronization
dnf install -y chrony
systemctl enable --now chronyd
# Configure chrony
cat > /etc/chrony.conf << 'EOF'
# Rocky Linux Chrony configuration
# NTP servers
pool 2.pool.ntp.org iburst
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst
# Record the rate at which the system clock gains/losses time
driftfile /var/lib/chrony/drift
# Allow the system clock to be stepped in the first three updates
makestep 1.0 3
# Enable kernel synchronization
rtcsync
# Enable hardware timestamping on all interfaces
hwtimestamp *
# Increase the minimum number of selectable sources
minsources 2
# Allow NTP client access from local network
#allow 192.168.0.0/16
# Serve time even if not synchronized
#local stratum 10
# Specify file containing keys
keyfile /etc/chrony.keys
# Disable logging of client accesses
noclientlog
# Send a message to syslog if clock adjustment is larger than 0.5 seconds
logchange 0.5
# Log files
logdir /var/log/chrony
EOF
# Restart chrony
systemctl restart chronyd
# Check time synchronization
chronyc sources -v
chronyc tracking
timedatectl status
Create Maintenance Scripts
# Create maintenance directory
mkdir -p /opt/maintenance/scripts
mkdir -p /opt/maintenance/logs
# Create system health check script
cat > /opt/maintenance/scripts/health-check.sh << 'EOF'
#!/bin/bash
# Rocky Linux System Health Check Script
LOG_FILE="/opt/maintenance/logs/health-check-$(date +%Y%m%d).log"
echo "=== Rocky Linux System Health Check ===" | tee -a "$LOG_FILE"
echo "Date: $(date)" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# System Information
echo "=== System Information ===" | tee -a "$LOG_FILE"
hostnamectl | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Uptime and Load
echo "=== System Uptime and Load ===" | tee -a "$LOG_FILE"
uptime | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Memory Usage
echo "=== Memory Usage ===" | tee -a "$LOG_FILE"
free -h | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Disk Usage
echo "=== Disk Usage ===" | tee -a "$LOG_FILE"
df -h | grep -vE '^tmpfs|^devtmpfs' | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# CPU Information
echo "=== CPU Usage (Top 10) ===" | tee -a "$LOG_FILE"
ps aux | sort -nrk 3,3 | head -10 | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Failed Services
echo "=== Failed Services ===" | tee -a "$LOG_FILE"
systemctl --failed | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# SELinux Status
echo "=== SELinux Status ===" | tee -a "$LOG_FILE"
getenforce | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Recent Security Events
echo "=== Recent Security Events ===" | tee -a "$LOG_FILE"
grep "Failed password" /var/log/secure | tail -5 | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Network Connections
echo "=== Active Network Connections ===" | tee -a "$LOG_FILE"
ss -tulpn | grep LISTEN | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
# Package Updates Available
echo "=== Available Updates ===" | tee -a "$LOG_FILE"
dnf check-update --security | grep -c "updates" | tee -a "$LOG_FILE"
echo "" | tee -a "$LOG_FILE"
echo "=== Health Check Complete ===" | tee -a "$LOG_FILE"
EOF
chmod +x /opt/maintenance/scripts/health-check.sh
# Create backup script
cat > /opt/maintenance/scripts/backup.sh << 'EOF'
#!/bin/bash
# Rocky Linux Backup Script
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
HOSTNAME=$(hostname -s)
BACKUP_FILE="$BACKUP_DIR/rocky-backup-$HOSTNAME-$DATE.tar.gz"
LOG_FILE="/opt/maintenance/logs/backup-$(date +%Y%m%d).log"
echo "Starting backup at $(date)" >> "$LOG_FILE"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Create backup
tar -czf "$BACKUP_FILE" \
--exclude=/backup \
--exclude=/proc \
--exclude=/sys \
--exclude=/dev \
--exclude=/run \
--exclude=/tmp \
--exclude=/mnt \
--exclude=/media \
--exclude=/lost+found \
--exclude=/var/cache \
--exclude=/var/tmp \
--exclude=/swapfile \
/etc \
/root \
/home \
/var/log \
/opt \
/usr/local 2>> "$LOG_FILE"
# Keep only last 7 backups
find "$BACKUP_DIR" -name "rocky-backup-$HOSTNAME-*.tar.gz" -mtime +7 -delete
echo "Backup completed at $(date)" >> "$LOG_FILE"
echo "Backup file: $BACKUP_FILE" >> "$LOG_FILE"
EOF
chmod +x /opt/maintenance/scripts/backup.sh
# Create update check script
cat > /opt/maintenance/scripts/check-updates.sh << 'EOF'
#!/bin/bash
# Rocky Linux Update Check Script
LOG_FILE="/opt/maintenance/logs/updates-$(date +%Y%m%d).log"
echo "=== Rocky Linux Update Check ===" > "$LOG_FILE"
echo "Date: $(date)" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
# Check for all updates
echo "=== All Available Updates ===" >> "$LOG_FILE"
dnf check-update >> "$LOG_FILE" 2>&1
echo "" >> "$LOG_FILE"
# Check for security updates
echo "=== Security Updates ===" >> "$LOG_FILE"
dnf check-update --security >> "$LOG_FILE" 2>&1
echo "" >> "$LOG_FILE"
# Count updates
TOTAL_UPDATES=$(dnf check-update 2>/dev/null | grep -c "updates")
SECURITY_UPDATES=$(dnf check-update --security 2>/dev/null | grep -c "updates")
echo "Summary:" >> "$LOG_FILE"
echo "Total updates available: $TOTAL_UPDATES" >> "$LOG_FILE"
echo "Security updates available: $SECURITY_UPDATES" >> "$LOG_FILE"
# Send notification if security updates are available
if [ "$SECURITY_UPDATES" -gt 0 ]; then
echo "ALERT: $SECURITY_UPDATES security updates available!" | mail -s "Rocky Linux Security Updates" root
fi
EOF
chmod +x /opt/maintenance/scripts/check-updates.sh
Schedule Maintenance Tasks
# Create cron jobs for maintenance
cat > /etc/cron.d/rocky-maintenance << 'EOF'
# Rocky Linux Maintenance Schedule
# Daily health check at 6:00 AM
0 6 * * * root /opt/maintenance/scripts/health-check.sh
# Daily backup at 2:00 AM
0 2 * * * root /opt/maintenance/scripts/backup.sh
# Check for updates every Monday at 7:00 AM
0 7 * * 1 root /opt/maintenance/scripts/check-updates.sh
# Clean old logs monthly
0 3 1 * * root find /opt/maintenance/logs -name "*.log" -mtime +90 -delete
# System performance report weekly
0 8 * * 0 root sar -A > /opt/maintenance/logs/sar-weekly-$(date +\%Y\%m\%d).txt
EOF
# Configure log rotation for maintenance logs
cat > /etc/logrotate.d/maintenance << 'EOF'
/opt/maintenance/logs/*.log {
monthly
rotate 12
compress
delaycompress
missingok
notifempty
create 0640 root root
}
EOF
Final Configuration Steps
Create System Documentation
# Create documentation directory
mkdir -p /root/docs
# Generate system documentation
cat > /root/docs/system-info.md << EOF
# Rocky Linux System Documentation
Generated on: $(date)
## System Information
- **Hostname**: $(hostname -f)
- **OS Version**: $(cat /etc/rocky-release)
- **Kernel**: $(uname -r)
- **Architecture**: $(arch)
- **CPU**: $(lscpu | grep "Model name" | cut -d: -f2 | xargs)
- **Memory**: $(free -h | grep Mem | awk '{print $2}')
- **Disk**: $(df -h / | tail -1 | awk '{print $2}')
## Network Configuration
- **Primary IP**: $(ip route get 8.8.8.8 | awk '{print $7}' | head -1)
- **Gateway**: $(ip route | grep default | awk '{print $3}')
- **DNS Servers**: $(grep nameserver /etc/resolv.conf | awk '{print $2}' | tr '\n' ' ')
## Security Configuration
- **SELinux**: $(getenforce)
- **Firewall**: Active (firewalld)
- **SSH Port**: 22
- **Fail2ban**: $(systemctl is-active fail2ban 2>/dev/null || echo "Not installed")
## Maintenance Schedule
- **Health Checks**: Daily at 6:00 AM
- **Backups**: Daily at 2:00 AM
- **Update Checks**: Weekly (Mondays at 7:00 AM)
- **Log Rotation**: Monthly
## Administrative Contacts
- **System Administrator**: sysadmin
- **DevOps Engineer**: devops
## Important Paths
- **Maintenance Scripts**: /opt/maintenance/scripts
- **Backup Location**: /backup
- **Custom Configurations**: /etc/sysctl.d/, /etc/security/limits.d/
- **Audit Logs**: /var/log/audit/
EOF
# Create quick reference guide
cat > /root/docs/quick-reference.txt << 'EOF'
Rocky Linux Quick Reference Guide
=================================
System Management
-----------------
systemctl status <service> # Check service status
systemctl restart <service> # Restart service
systemctl enable --now <service> # Enable and start service
journalctl -u <service> -f # Follow service logs
journalctl --since "1 hour ago" # View recent logs
Package Management
------------------
dnf update # Update all packages
dnf search <package> # Search for package
dnf info <package> # Show package info
dnf install <package> # Install package
dnf remove <package> # Remove package
dnf autoremove # Remove unused dependencies
Firewall Management
-------------------
firewall-cmd --list-all # Show all rules
firewall-cmd --add-service=<service> --permanent
firewall-cmd --add-port=<port>/tcp --permanent
firewall-cmd --reload # Apply changes
SELinux Management
------------------
getenforce # Check SELinux mode
setenforce 0|1 # Set permissive|enforcing
ausearch -m avc -ts recent # Check recent denials
setsebool -P <boolean> on|off # Set boolean permanently
Network Diagnostics
-------------------
ip addr show # Show IP addresses
ip route show # Show routing table
ss -tulpn # Show listening ports
nmcli connection show # Show network connections
nmap -sT localhost # Port scan
Performance Monitoring
----------------------
top / htop # Process monitoring
iotop # I/O monitoring
sar -u 1 10 # CPU usage
vmstat 1 # Virtual memory stats
iostat -x 1 # I/O statistics
Maintenance Tasks
-----------------
/opt/maintenance/scripts/health-check.sh # Run health check
/opt/maintenance/scripts/backup.sh # Run backup
/opt/maintenance/scripts/check-updates.sh # Check updates
EOF
Final Security Hardening
# Disable unnecessary network protocols
cat > /etc/modprobe.d/disable-protocols.conf << 'EOF'
# Disable unnecessary network protocols
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
EOF
# Configure kernel security parameters
cat > /etc/sysctl.d/99-security.conf << 'EOF'
# Kernel security hardening
# Enable ExecShield
kernel.exec-shield = 1
kernel.randomize_va_space = 2
# Restrict core dumps
fs.suid_dumpable = 0
kernel.core_uses_pid = 1
# Restrict access to kernel logs
kernel.dmesg_restrict = 1
# Restrict ptrace scope
kernel.yama.ptrace_scope = 1
# Protect against SYN flood attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# Log martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Ignore ICMP ping requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore bogus ICMP errors
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Enable IP spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
EOF
# Apply security settings
sysctl -p /etc/sysctl.d/99-security.conf
# Set proper permissions on sensitive files
chmod 600 /etc/cron.allow
chmod 600 /etc/at.allow
chmod 600 /etc/ssh/sshd_config
chmod 700 /root
chmod 600 /boot/grub2/grub.cfg
# Final SELinux relabel (if needed)
touch /.autorelabel
Conclusion
Your Rocky Linux system is now properly configured with a solid foundation for production use. This configuration provides:
- Security: Hardened SSH, enforcing SELinux, configured firewall, and comprehensive auditing
- Performance: Optimized kernel parameters, tuned profiles, and efficient resource management
- Reliability: Automated maintenance, comprehensive monitoring, and backup strategies
- Management: Proper user access controls, systematic logging, and documentation
Regular maintenance tasks to remember:
- Review security updates weekly
- Monitor system health daily
- Verify backup integrity monthly
- Audit user access quarterly
- Update documentation with changes
- Test disaster recovery procedures
This initial configuration establishes a secure, performant, and manageable Rocky Linux environment ready for specific application deployments.