đŸ–Ĩī¸ Section 17: Server Management Tasks

Professional Guide to Linux Server Administration & Optimization

1. System Updates

Keeping your Ubuntu server updated is critical for security and stability. This section covers three methods to update your system: manual commands, bash aliases, and automated scripts.

1.1 Manual Update Commands

📌 Best Practice: Run system updates weekly or after critical security patches are released.
Step 1: Update package lists
sudo apt update
Step 2: Upgrade installed packages
sudo apt upgrade
Step 3: Remove unnecessary packages
sudo apt autoremove

Update Process Flow

apt update
→
apt upgrade
→
apt autoremove
→
✓ Complete

1.2 Combined Command (One-Line Execution)

Without automatic confirmation:
sudo apt update && sudo apt upgrade && sudo apt autoremove
With automatic confirmation (-y flag):
sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y

1.3 Creating a Bash Alias

Aliases allow you to create shortcuts for frequently used commands. This saves time and reduces typing errors.

1 Open the bash aliases file:
cd
nano .bash_aliases
2 Add the alias:
alias server_updates='sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'
3 Activate the alias:
exit

After logging back in, you can run: server_updates

1.4 Creating an Automated Script

Scripts provide more control and can include error checking and logging.

1 Create the script file:
sudo nano server_updates.sh
2 Add the following content:
#!/bin/bash # Check if script is run as root if [ "$EUID" -ne 0 ]; then echo "Please run this script with sudo or as root." exit fi # Update package lists echo "Updating package lists..." sudo apt update # Upgrade installed packages echo "Upgrading installed packages..." sudo apt upgrade # Remove unnecessary packages echo "Removing unnecessary packages..." sudo apt autoremove echo "Update, upgrade, and autoremove completed."
3 Make the script executable:
sudo chmod +x server_updates.sh
4 Run the script:
sudo ./server_updates.sh
âš ī¸ Note: The script removes the -y flags to allow manual review of updates before installation.

2. WordPress Updates & Permissions

Proper file permissions are crucial for WordPress security and functionality. This section covers two permission strategies: default permissions for updates and hardened permissions for production.

2.1 Default PHP Pool User Permissions (For Updates)

These permissions allow WordPress to update plugins, themes, and core files through the dashboard.

1 Navigate to the website directory:
cd /var/www/example.com/
2 Check current permissions:
sudo ls -l public_html/
3 Set ownership to PHP pool user:
sudo chown -R PHP_POOL_USER:PHP_POOL_USER public_html/
4 Set directory permissions (770):
sudo find /var/www/example.com/public_html/ -type d -exec chmod 770 {} \;
5 Set file permissions (660):
sudo find /var/www/example.com/public_html/ -type f -exec chmod 660 {} \;
✓ Result: Open the WordPress Dashboard and all updates will run without issues.
6 Restart PHP-FPM:
sudo systemctl reload php8.3-fpm

2.2 File Permission Breakdown

Permission Numeric Description Use Case
770 rwxrwx--- Owner & Group: full access Directories (update mode)
660 rw-rw---- Owner & Group: read/write Files (update mode)
550 r-xr-x--- Owner & Group: read/execute Directories (hardened)
440 r--r----- Owner & Group: read only Files (hardened)

2.3 Hardened Permissions (For Production)

After updates are complete, harden permissions to protect against unauthorized modifications.

1 Navigate to website directory:
cd /var/www/example.com/
2 Check current permissions:
sudo ls -l public_html/
3 Set ownership:
sudo chown -R PHP_POOL_USER:PHP_POOL_USER public_html/
4 Harden directory permissions (550):
sudo find /var/www/example.com/public_html/ -type d -exec chmod 550 {} \;
5 Harden file permissions (440):
sudo find /var/www/example.com/public_html/ -type f -exec chmod 440 {} \;
6 Keep wp-content writable for uploads:
sudo find /var/www/example.com/public_html/wp-content/ -type d -exec chmod 770 {} \;
sudo find /var/www/example.com/public_html/wp-content/ -type f -exec chmod 660 {} \;

WordPress Update Workflow

Loosen Permissions (770/660)
→
Run WordPress Updates
→
Harden Permissions (550/440)
→
Restart PHP-FPM

2.4 Quick Permission Change Commands

Loosen permissions before updates:
sudo find /var/www/example.com/public_html/ -type d -exec chmod 770 {} \;
sudo find /var/www/example.com/public_html/ -type f -exec chmod 660 {} \;
Harden permissions after updates:
sudo find /var/www/example.com/public_html/ -type d -exec chmod 550 {} \;
sudo find /var/www/example.com/public_html/ -type f -exec chmod 440 {} \;
sudo find /var/www/example.com/public_html/wp-content/ -type d -exec chmod 770 {} \;
sudo find /var/www/example.com/public_html/wp-content/ -type f -exec chmod 660 {} \;

3. Security Scanning

Regular security scanning helps detect malware, rootkits, and security vulnerabilities. This section covers two essential tools: ClamAV and RKHunter.

3.1 ClamAV (Antivirus Scanner)

ClamAV is an open-source antivirus engine for detecting trojans, viruses, malware, and other malicious threats.

Installation

1 Update package lists:
sudo apt update
2 Install ClamAV:
sudo apt install clamav
â„šī¸ Note: The ClamAV virus definition database will be updated automatically after installation.

Disable Automatic Updates

For manual control over updates, disable the automatic freshclam service:

Stop the freshclam service:
sudo systemctl stop clamav-freshclam
Disable freshclam on startup:
sudo systemctl disable clamav-freshclam

Manual Database Updates

Update virus definitions manually:
sudo freshclam

Running Manual Scans

Scan a specific directory recursively:
sudo clamscan -r /path/2/scan
Complete manual scanning workflow:
sudo freshclam
sudo clamscan -r /path/2/scan
âš ī¸ Important: Always update virus definitions with freshclam before running scans.

3.2 RKHunter (Rootkit Hunter)

RKHunter is a Unix-based tool that scans for rootkits, backdoors, and possible local exploits.

Installation & Initial Setup

1 Install RKHunter:
sudo apt install rkhunter
2 Update file properties database:
sudo rkhunter --propupd
📌 What is --propupd? This command updates the file properties database, which RKHunter uses as a baseline to detect changes in system files.

Running Security Scans

Run complete system scan (skip keypresses):
sudo rkhunter --checkall --sk
Available flags:
  • --sk or --skip-keypress: Skip manual key presses during scan

Viewing Scan Results

View complete log file:
sudo cat /var/log/rkhunter.log
View log with pagination:
sudo less /var/log/rkhunter.log

Disable Automatic Cron Jobs

To prevent automatic scans and maintain manual control:

Remove daily cron job:
cd /etc/cron.daily/
sudo rm rkhunter
Remove weekly cron job:
cd /etc/cron.weekly/
sudo rm rkhunter

Security Scanning Workflow

Update Definitions
→
Run ClamAV Scan
→
Run RKHunter Scan
→
Review Logs

4. Database Tuning & Monitoring

Database optimization is critical for WordPress performance. This section covers monitoring queries and using MySQLTuner for optimization recommendations.

4.1 InnoDB Buffer Pool Monitoring

The InnoDB buffer pool is the memory area where InnoDB caches table and index data. Monitoring its usage helps optimize memory allocation.

View actual InnoDB buffer pool memory usage:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_bytes_data';

4.2 Database Size Analysis

View all database sizes:
SELECT table_schema AS "Database", ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)" FROM information_schema.tables GROUP BY table_schema;
View InnoDB database sizes only:
SELECT table_schema AS "Database", SUM(data_length + index_length) / 1024 / 1024 AS "Size (MB)" FROM information_schema.tables WHERE engine = 'InnoDB' GROUP BY table_schema;
View buffer pool usage by database:
SELECT table_schema AS "Database", SUM(data_length + index_length) / 1024 / 1024 AS "Size (MB)" FROM information_schema.tables WHERE engine = 'InnoDB' GROUP BY table_schema;

4.3 Table I/O Statistics

Understanding which tables are accessed most frequently helps optimize query performance and indexing strategies.

View table I/O statistics:
SELECT object_schema AS 'Database', object_name AS 'Table', COUNT_READ AS 'Reads', COUNT_WRITE AS 'Writes', SUM_TIMER_READ / 1000000000 AS 'Read Time (ms)', SUM_TIMER_WRITE / 1000000000 AS 'Write Time (ms)' FROM performance_schema.table_io_waits_summary_by_table ORDER BY SUM_TIMER_READ + SUM_TIMER_WRITE DESC;
💡 Analysis Tip: Tables with high read/write times may benefit from additional indexes or query optimization.

4.4 MySQLTuner

MySQLTuner is a Perl script that analyzes your MySQL/MariaDB configuration and provides optimization recommendations.

1 Navigate to MySQLTuner directory:
cd
cd MySQLTuner/
2 List directory contents:
ls -l
3 Run MySQLTuner with sudo:
sudo ./mysqltuner
âš ī¸ Important: MySQLTuner must be run with sudo privileges to access MariaDB and gather necessary statistics.
Query Type Purpose Key Metrics
Buffer Pool Status Memory usage monitoring Bytes in use
Database Size Storage allocation Total MB per database
InnoDB Tables InnoDB-specific analysis InnoDB storage only
Table I/O Stats Performance bottlenecks Reads, writes, timing

5. Disk Space Management

Monitoring and managing disk space is critical to prevent server crashes. Running out of disk space can cause database corruption, application failures, and system instability.

5.1 Check Disk Space Usage

Display disk usage in human-readable format:
df -h
â„šī¸ Flag Explanation: The -h flag displays sizes in human-readable format (KB, MB, GB) instead of bytes.

5.2 Clean Up Package Cache

Remove unused packages and clean cache:
sudo apt autoremove && sudo apt clean

5.3 Clean Up System Logs

System logs can accumulate quickly and consume significant disk space.

Remove logs older than 1 day:
sudo journalctl --vacuum-time=1days
âš ī¸ Caution: Only remove old logs if you don't need them for troubleshooting. For production servers, consider keeping 7-30 days of logs.

5.4 Analyze Directory Sizes

Navigate to root directory:
cd /
List directory sizes sorted by size:
du -ah --max-depth=1 | sort -h
💡 Pro Tip: The largest directories appear at the bottom. You can navigate into any directory and run the same command to drill down further.

Disk Space Management Workflow

Check Space (df -h)
→
Clean Packages
→
Clean Logs
→
Analyze Directories

6. NGINX Connection Backlog

The backlog parameter defines the maximum queue length for pending connections. Proper configuration prevents connection drops during traffic spikes.

Set backlog value:
backlog=2048
HTTP configuration:
listen 80 backlog=2048;
HTTPS configuration:
listen 443 ssl backlog=2048;
📊 Recommended Value: A backlog of 2048 is suitable for most production environments. Increase this value for high-traffic sites.

7. PHP-FPM Optimization

PHP-FPM (FastCGI Process Manager) optimization is crucial for WordPress performance. This section covers monitoring OPcache and analyzing PHP file counts.

âš ī¸ Important Reminder: Setting the correct pm.max_children directive is critical. Setting it too low or too high can significantly impact server performance. Refer to the "Optimizing WordPress" section of the course for detailed PHP-FPM tuning guidance.

7.1 PHP-FPM Tuning Guidelines

  • Single WordPress Site: Refer to the "Optimizing WordPress" section
  • Multiple WordPress Sites: Refer to the "Installing Additional WordPress Sites" section
  • Tuning Frequency: Optimize PHP-FPM weekly or after significant traffic changes

7.2 OPcache Files Monitoring Script

This script displays the number of PHP files per site and compares them with OPcache configuration values.

1 Create the monitoring script:
nano opcache_files.sh
2 Add the script content:
#!/bin/bash round_to_prime() { local value=$1 primes=(223 463 983 1979 3907 7963 16229 32531 65407 130987 262237 524524 1048793) closest=0 min_diff=$((value - primes[0])) for prime in "${primes[@]}"; do diff=$((value - prime)) if [ $diff -lt 0 ]; then closest=$prime break elif [ $diff -lt $min_diff ]; then min_diff=$diff closest=$prime fi done echo "$closest" } echo "" echo "Checking for opcache.max_accelerated_files directive in PHP pool files..." echo "" echo "The value used (actual value) will be the first number in the set of prime numbers" echo "223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793" echo "that is greater than or equal to the configured value (value set)" echo "" POOL_DIR="/etc/php/8.3/fpm/pool.d/" for file in "$POOL_DIR"*.conf; do filename=$(basename "$file") if grep -q "opcache.max_accelerated_files" "$file"; then value=$(grep "opcache.max_accelerated_files" "$file" | awk -F'=' '{print $2}' | tr -d ' ') rounded_value=$(round_to_prime "$value") echo "File: $filename - opcache.max_accelerated_files: set value ($value) actual value ($rounded_value)" else echo "File: $filename - opcache.max_accelerated_files directive not found" fi done echo "" echo "Listing domain names and number of PHP files in public_html directories..." echo "" WWW_DIR="/var/www/" for domain_dir in "$WWW_DIR"*/ ; do if [ "$domain_dir" == "/var/www/html/" ]; then continue fi domain_name=$(basename "$domain_dir") public_html_dir="$domain_dir/public_html/" if [ -d "$public_html_dir" ]; then php_file_count=$(find "$public_html_dir" -type f -name "*.php" | wc -l) echo "WordPress site: $domain_name - PHP files: $php_file_count" else echo "Domain: $domain_name - public_html directory not found" fi done echo ""
3 Make the script executable:
sudo chmod +x opcache_files.sh
4 Run the script:
./opcache_files.sh

7.3 OPcache Prime Numbers Explanation

OPcache uses prime numbers for hash table sizing to reduce collisions. The system automatically rounds up your configured value to the next available prime number.

Prime Number Recommended For Site Type
223 Very small sites Basic blogs
463 Small sites Simple WordPress
983 Small-medium sites Standard WordPress
1979 Medium sites WordPress + plugins
3907 Medium-large sites E-commerce sites
7963 Large sites WooCommerce + many plugins
16229+ Very large sites Enterprise WordPress
✓ Best Practice: Set opcache.max_accelerated_files to the next prime number above your total PHP file count. This ensures all files can be cached efficiently.

PHP-FPM Optimization Process

Count PHP Files
→
Round to Prime
→
Configure OPcache
→
Monitor Weekly

📚 Summary & Best Practices

Key Takeaways

  • Regular Updates: Run system updates weekly or after security patches
  • Permission Management: Loosen permissions for updates, then harden for production
  • Security Scanning: Run ClamAV and RKHunter regularly to detect threats
  • Database Optimization: Use MySQLTuner and monitor InnoDB buffer pool usage
  • Disk Space: Monitor disk usage to prevent crashes
  • PHP-FPM Tuning: Optimize weekly and adjust based on traffic patterns
  • OPcache Configuration: Set max_accelerated_files above your PHP file count

Maintenance Schedule Recommendations

Task Frequency Priority
System Updates Weekly High
Security Scans Weekly High
Disk Space Check Daily Critical
PHP-FPM Tuning Weekly Medium
Database Optimization Monthly Medium
Log Cleanup Weekly Low