System Administrator Full Documentation
This documentation is an extensive guide designed for Linux system administrators. It covers complete workflows including server setup, networking, security, email systems, web hosting, MySQL, and storage management.
Code examples are formatted in VS Code dark theme. Every command includes comments, explanations, and real-world usage scenarios.
File System Overview
This section explains how Linux organizes and manages data on disks, including partitions, filesystems, and related tools for monitoring and maintenance.
lsblk -f # Shows all block devices, partitions, filesystem types, and mount points.
# View partition tables
sudo fdisk -l # Lists partitions, sizes, and types on all disks.
# Check mounted filesystems
mount | column -t # Shows all currently mounted filesystems and mount options.
# Check disk usage
df -h # Reports free/used space in human-readable format.
# Check inode usage
df -i # Useful when lots of small files cause "No space left on device" despite free disk space.
# Show detailed disk usage
du -sh /var/log/* # Displays the size of directories or files. Helps locate large files consuming space.
# File permissions and ownership
ls -l /var/www/html # Lists permissions, owners, and groups of files in a directory.
# Change ownership
sudo chown user:group filename # Changes owner and group of a file/directory.
# Change permissions
sudo chmod 755 filename # Sets read/write/execute permissions. Common: 755 for directories, 644 for files.
# Create symbolic and hard links
ln -s /path/to/original /path/to/link ln /path/to/original /path/to/hardlink # Symbolic links point to files/directories; hard links duplicate references.
# Configure fstab for auto-mounting
sudo nano /etc/fstab # Add entries for devices to mount at boot. Example: UUID=xxxx /mnt/data ext4 defaults 0 2
# Mount and unmount manually
sudo mount /dev/sdb1 /mnt/data sudo umount /mnt/data # Mount or unmount partitions temporarily.
# File system check (for ext4)
sudo fsck -f /dev/sdb1 # Checks and repairs filesystem inconsistencies. Run only on unmounted partitions.
# Identify filesystem type
sudo blkid /dev/sdb1 # Shows the filesystem type and UUID of a disk/partition.
# Disk quotas (if enabled)
sudo repquota -a # Shows user disk usage and limits when quotas are active.
# Troubleshooting tips
dmesg | grep -i ext4 sudo journalctl -xe | grep mount # Check kernel and system logs for filesystem or mount errors.
System Overview
This section introduces fundamental tools used by system administrators to inspect, monitor, and understand the state of a Linux server. These commands are the first step when diagnosing issues or performing audits.
uname -a # Explanation: Shows kernel version, architecture, and OS type. # Used when checking compatibility or diagnosing kernel issues.
# Distribution details
cat /etc/os-release # Example output: NAME="Ubuntu" VERSION="22.04 LTS"
# System uptime
uptime # Example: "14:22 up 5 days, load average: 0.15, 0.20, 0.30"
# Hardware info
lscpu lsmem lsblk lspci lsusb # These help identify RAM, CPU cores, PCI devices, or attached USB hardware.
# Disk usage summary
df -h # Use this to ensure partitions are not full. A full disk stops MySQL, Postfix, or Apache.
# Memory usage
free -h # Shows available and used RAM. High swap usage indicates low memory.
# List all services
systemctl list-units --type=service # Useful to confirm which services failed.
Users and Groups
This section covers user management, group administration, and best practices for secure account handling. System administrators use these commands daily when onboarding users, assigning roles, or securing directories.
sudo adduser johndoe # Prompts for password and creates /home/johndoe # Use this for normal user accounts.
# Create a system user (no shell, no home)
sudo useradd -r -s /usr/sbin/nologin mysqluser
usermod -s /sbin/nologin testuser # Used for system services like MySQL, Postfix, web apps.
Change usr dir
sudo usermod -d /var/www/html ftp-user
sudo usermod -aG www-data ftp-user
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 775 /var/www/html
View user dir
getent passwd ftp-user
# Change user shell
sudo chsh -s /bin/bash johndoe
# Assign user to a group
sudo usermod -aG sudo johndoe # Adds johndoe to sudoers without removing other groups.
# List all users
cut -d: -f1 /etc/passwd
# List groups
cut -d: -f1 /etc/group
# Delete a user (keep home folder)
sudo userdel johndoe
# Delete a user with home folder
sudo userdel -r johndoe
# Switch to another user account
su - johndoe
Permissions and Ownership
Permissions determine who can read, write, or execute files and directories. Misconfiguration can cause service failures (Apache, MySQL, Postfix). Understanding these is essential for security.
ls -l # Example: -rw-r--r-- 1 root root 1200 file.txt # Meaning: owner=rw, group=r, others=r
# Change owner
sudo chown johndoe:johndoe file.txt
# Recursive ownership change
sudo chown -R www-data:www-data /var/www/html # Required for Apache document root.
# Change permissions
chmod 755 script.sh chmod 644 config.php # 755 = rwx r-x r-x (execute allowed) # 644 = rw- r-- r-- (common for configs)
# Give execute permission
chmod +x run.sh
# Remove write permissions from others
chmod o-w file.txt
Sudoers Configuration
Sudo allows controlled privilege escalation. Editing sudoers incorrectly can lock you out entirely, so always use visudo, which checks syntax.
sudo visudo
# Allow user full sudo access
johndoe ALL=(ALL) ALL
# Allow user to run specific command
johndoe ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart apache2
# Allow group sudo privileges
%support ALL=(ALL) ALL
Processes, Logs, and System Monitoring
Process management is essential for diagnosing high CPU, memory leaks, or services failing. Linux provides many tools for system observation.
ps aux
# Real-time process view
top
htop # install: sudo apt install htop
# Detailed kernel messages
dmesg | less
# Follow system logs live
sudo journalctl -f
# Service status
sudo systemctl status apache2
sudo systemctl status mysql
# Restart failed services
sudo systemctl restart postfix
# Enable services on boot
sudo systemctl enable dovecot
# Show failed units
systemctl --failed
Disk Management
Disk operations include creating partitions, formatting, mounting, or preparing disks for LVM or RAID. These commands must be used carefully because mistakes can destroy data.
lsblk fdisk -l
# Create or edit a partition
sudo fdisk /dev/sdb # Commands: n = new partition, d = delete, w = write changes
# Format a disk
sudo mkfs.ext4 /dev/sdb1 sudo mkfs.xfs /dev/sdb1
# Create mount directory
sudo mkdir -p /mnt/data
# Mount a filesystem manually
sudo mount /dev/sdb1 /mnt/data
# List mounted filesystems
mount | grep /mnt
# Get disk UUID (recommended for persistent mounts)
sudo blkid /dev/sdb1
# Edit fstab to mount disk automatically at boot
sudo nano /etc/fstab
# Add this line inside /etc/fstab
UUID=your-uuid-here /mnt/data ext4 defaults,nofail 0 2
# Test fstab configuration without rebooting
sudo mount -a
# Unmount a disk
sudo umount /mnt/data
Logical Volume Management (LVM)
LVM allows flexible disk management: resizing storage without unmounting, adding new disks easily, or creating snapshots. Essential for servers.
sudo pvcreate /dev/sdb1
# 2. Create Volume Group
sudo vgcreate datavg /dev/sdb1
# 3. Create Logical Volume
sudo lvcreate -L 50G -n datalv datavg
# 4. Format LV
sudo mkfs.ext4 /dev/datavg/datalv
# 5. Mount LV
sudo mkdir /data
sudo mount /dev/datavg/datalv /data
# Extend LV and filesystem (online)
sudo lvextend -L +20G /dev/datavg/datalv sudo resize2fs /dev/datavg/datalv # Now LV grows by 20 GB without downtime.
RAID (mdadm)
RAID increases redundancy or speed. RAID1 mirrors disks, RAID5 provides parity, RAID0 improves performance but no redundancy.
sudo apt install mdadm -y
# Create RAID1 (mirror)
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1
# Create RAID5
sudo mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sd{b1,c1,d1}
# Check RAID status
cat /proc/mdstat
# Save RAID config
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
fstab & Automounting
The /etc/fstab file ensures filesystems mount automatically at boot. Mistakes here can prevent the server from booting.
sudo blkid
# Sample fstab entry
# /dev/sdb1 mounted to /data with ext4 filesystem
UUID=xxxx-xxxx /data ext4 defaults 0 2
# Test fstab for errors
sudo mount -a # If no output, fstab is correct.
Backups & Archiving
Backups are essential for server reliability. Administrators use tar, zip, rsync, or mysqldump to protect data.
tar -czvf backup.tar.gz /var/www/html
# Extract archive
tar -xzvf backup.tar.gz
# Sync directories (incremental backup)
rsync -avz /var/www/ /backup/www/
Cron Jobs
Cron automates repetitive tasks like backups, updates, log rotation, certificate renewal, database dumps, cache clearing, and monitoring scripts. It runs commands automatically at scheduled times based on defined intervals.
Each cron job consists of five time fields followed by the command to execute.
crontab -e
# View existing cron jobs
crontab -l
# Remove all cron jobs
crontab -r
# Cron format:
# ┌───────────── minute (0 - 59)
# │ ┌─────────── hour (0 - 23)
# │ │ ┌───────── day of month (1 - 31)
# │ │ │ ┌─────── month (1 - 12)
# │ │ │ │ ┌───── day of week (0 - 7) (Sunday=0 or 7)
# │ │ │ │ │
# * * * * * command_to_execute
# Special characters:
# * → every value
# */5 → every 5 units
# 1-5 → range
# 1,15 → specific values
# Run every minute (testing)
* * * * * /home/user/test.sh
# Daily backup at 1 AM
0 1 * * * /usr/bin/rsync -av /data /backup/data
# Every 5 minutes
*/5 * * * * /usr/bin/php /var/www/html/cron.php
# Every day at 6:30 PM
30 18 * * * /home/user/evening_task.sh
# Every Monday at 3 AM
0 3 * * 1 /home/user/weekly_report.sh
# Every weekday at 9 AM (Mon-Fri)
0 9 * * 1-5 /home/user/work_task.sh
# On the 1st day of every month at midnight
0 0 1 * * /home/user/monthly_backup.sh
# Every 2 hours
0 */2 * * * /home/user/every2hours.sh
# Weekly system updates (Sunday 4 AM)
0 4 * * 0 sudo apt update && sudo apt upgrade -y
# Redirect output to log file
0 2 * * * /home/user/script.sh >> /var/log/script.log 2>&1
System-wide Cron
System-wide cron jobs are defined in:
/etc/cron.d/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/
These are useful for administrative tasks affecting the entire server.
Best Practices
- Always use full paths to commands (e.g., /usr/bin/php instead of php).
- Redirect output to log files to debug errors.
- Test scripts manually before scheduling them.
- Avoid running heavy jobs during peak traffic hours.
- Secure scripts with proper permissions.
Troubleshooting
sudo systemctl status cron
# Check cron logs (Debian/Ubuntu)
grep CRON /var/log/syslog
IP Configuration & Routing
System administrators frequently configure network interfaces, diagnose connectivity issues, or modify routing tables. Below are the foundational commands with full explanations.
ip addr show # Shows interface names, MAC addresses, assigned IPs, and link status.
# Assign temporary IP to interface (lost after reboot)
sudo ip addr add 192.168.1.50/24 dev enp0s3
# Delete assigned IP
sudo ip addr del 192.168.1.50/24 dev enp0s3
# Bring interface up or down
sudo ip link set enp0s3 up sudo ip link set enp0s3 down
# Display routing table
ip route # Shows default gateway and route priorities.
# Add new route
sudo ip route add 10.0.0.0/24 via 192.168.1.1 dev enp0s3
# Delete route
sudo ip route del 10.0.0.0/24
# Test connectivity
ping -c 4 google.com ping -c 4 8.8.8.8 # DNS-independent test
# Trace path to a remote server
traceroute google.com
DNS Tools
DNS resolution is crucial for communication between services. Administrators need to test DNS records, MX mail routing, or troubleshoot name failures.
dig example.com
# Query specific record types
dig MX example.com dig A example.com dig TXT example.com
# Reverse lookup
dig -x 8.8.8.8
# Query using specific DNS server
dig @8.8.8.8 example.com
# Simplified DNS query
nslookup example.com
Netplan Configuration
Netplan controls permanent network configuration in Ubuntu Server. It processes YAML configuration files and applies them to systemd-networkd or NetworkManager.
sudo nano /etc/netplan/50-cloud-init.yaml
# Sample static IP configuration
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
addresses: [192.168.1.10/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
# Apply configuration
sudo netplan apply
# Validate configuration syntax
sudo netplan try
Network Bonding (Interface Teaming)
Bonding provides redundancy or increased bandwidth by combining multiple network interfaces into a single logical interface.
sudo apt install ifenslave
# Sample Netplan bonding configuration
network:
version: 2
renderer: networkd
bonds:
bond0:
interfaces: [enp0s3, enp0s8]
parameters:
mode: active-backup
primary: enp0s3
dhcp4: yes
# Apply bonding
sudo netplan apply
# Check bonding status
cat /proc/net/bonding/bond0
DHCP Server & Client
DHCP automatically assigns IP addresses. System administrators configure DHCP servers for internal networks or troubleshoot client issues.
DHCP Server (isc-dhcp-server)
sudo apt install isc-dhcp-server -y
# Edit DHCP configuration
sudo nano /etc/dhcp/dhcpd.conf
# Example DHCP pool
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option domain-name-servers 8.8.8.8, 1.1.1.1;
}
# Enable interface
sudo nano /etc/default/isc-dhcp-server INTERFACESv4="enp0s3"
# Restart service
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server
DHCP Client Tools
sudo dhclient -r sudo dhclient
# View DHCP leases
cat /var/lib/dhcp/dhclient.leases
sudo apt update
sudo apt install openssh-server -y
# Verify SSH service status
sudo systemctl status ssh
# Enable SSH to start automatically on boot
sudo systemctl enable ssh
# Start SSH service if not running
sudo systemctl start ssh
# Check SSH port listening
sudo ss -tulpn | grep ssh
# Default port is 22
# Allow SSH through firewall (UFW)
sudo ufw allow ssh
# or
sudo ufw allow 22/tcp
# Test SSH connection from another machine
ssh username@server-ip
# Edit SSH server configuration
sudo nano /etc/ssh/sshd_config
# Important SSH security configurations
Port 22 # Change port to something else for security (example 2222)
PermitRootLogin no # Disable root login
PasswordAuthentication yes # Allow password login (or set to no for key-only login)
PubkeyAuthentication yes # Enable SSH key authentication
MaxAuthTries 3 # Limit login attempts
LoginGraceTime 30 # Time allowed for login
X11Forwarding no # Disable X11 forwarding if not needed
# Save configuration and restart SSH
sudo systemctl restart ssh
# Verify SSH configuration syntax
sudo sshd -t
# Generate SSH key on client machine
ssh-keygen -t rsa -b 4096
# Copy SSH key to server
ssh-copy-id username@server-ip
# Test login using SSH key
ssh username@server-ip
# Disable password authentication after key setup (recommended)
sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
# Restart SSH to apply changes
sudo systemctl restart ssh
# Check SSH logs if login fails
sudo journalctl -u ssh
# or
sudo tail -f /var/log/auth.log
# Allow SSH only from specific IP (optional security)
sudo ufw allow from YOUR-IP-ADDRESS to any port 22
# View current SSH connections
who
# or
w
SSH Hardening
SSH is the primary admin access method. Hardening prevents unauthorized access and brute-force attacks.
sudo systemctl status ssh
# Edit SSH config
sudo nano /etc/ssh/sshd_config
# Recommended security settings
Port 2222 PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AllowUsers johndoe sysadmin
# Restart SSH
sudo systemctl restart ssh
UFW Firewall
UFW provides simple syntax for firewall rule configuration. Essential for restricting access to services.
sudo ufw default deny incoming sudo ufw default allow outgoing
# Allow essential ports
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 25/tcp # SMTP
sudo ufw allow 587/tcp # Submission
sudo ufw allow 993/tcp # IMAP SSL
# Deny specific IP
sudo ufw deny from 10.0.0.55
# Enable firewall
sudo ufw enable
# Check rules
sudo ufw status numbered
Fail2ban Intrusion Prevention
Fail2ban blocks repeated unauthorized login attempts. It is vital for SSH, Postfix, and Apache brute-force protection.
sudo apt install fail2ban -y
# Create local jail override file
sudo nano /etc/fail2ban/jail.local
# Recommended configuration
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
# Restart fail2ban
sudo systemctl restart fail2ban
# View banned IPs
sudo fail2ban-client status sshd
sudo apt update
sudo apt install figlet -y
# Generate ASCII logo (copy output for later use)
figlet "DAUDI SERVER"
# Create custom MOTD script (dynamic banner)
sudo nano /etc/update-motd.d/01-daudi
# Example script content
#!/bin/bash
echo "================================="
figlet "DAUDI SERVER"
echo "================================="
echo "Hostname: $(hostname)"
echo "Uptime: $(uptime -p)"
echo "Memory usage:"
free -h
# Make the script executable
sudo chmod +x /etc/update-motd.d/01-daudi
# Test MOTD output without logging out
run-parts /etc/update-motd.d/
# Edit static MOTD (optional)
sudo nano /etc/motd
# Create SSH pre-login banner
sudo nano /etc/issue.net
# Enable banner in SSH configuration
sudo nano /etc/ssh/sshd_config
# Add or modify:
Banner /etc/issue.net
# Restart SSH service
sudo systemctl restart ssh
# Disable unwanted default MOTD scripts (optional)
sudo chmod -x /etc/update-motd.d/50-motd-news
OpenSSL Certificate Management
OpenSSL creates private keys, CSRs, and self-signed certificates. Used for HTTPS, SMTP, IMAP, and internal secure communication.
openssl genrsa -out server.key 2048
# Generate a certificate signing request
openssl req -new -key server.key -out server.csr
# Fill in domain details: CN = example.com
# Self-signed certificate (valid 1 year)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# View certificate details
openssl x509 -in server.crt -noout -text
Apache Web Server
Apache hosts websites, APIs, and applications. System administrators configure virtual hosts, SSL certificates, and document roots.
sudo apt update
sudo apt install apache2 -y
# Verify Apache status
sudo systemctl status apache2
# Enable Apache modules
sudo a2enmod rewrite sudo a2enmod ssl sudo systemctl restart apache2
# Create a new site configuration
sudo nano /etc/apache2/sites-available/example.conf
# Sample Virtual Host
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example
ErrorLog ${APACHE_LOG_DIR}/example-error.log
CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>
# Enable site
sudo a2ensite example.conf
sudo systemctl reload apache2
# Disable default site
sudo a2dissite 000-default.conf
vsftpd FTP
sudo apt update
sudo apt install vsftpd -y
# Verify vsftpd status
sudo systemctl status vsftpd
# Backup default configuration
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
# Edit vsftpd configuration for remote access
sudo nano /etc/vsftpd.conf
# Key configuration options
listen=YES # Listen on IPv4
anonymous_enable=NO # Disable anonymous login
local_enable=YES # Enable local users
write_enable=YES # Allow uploads
chroot_local_user=YES # Restrict users to home directory. If you do not wish FTP users to be able to access any files outside of their own home directory, set up chroot jail.
pasv_min_port=10000
pasv_max_port=10100
# Restart vsftpd to apply changes
sudo systemctl restart vsftpd
# Configure firewall (UFW) for FTP
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 10000:10100/tcp # Passive FTP ports
sudo ufw reload
# Configure NAT/port forwarding (if behind router)
# Forward ports 21 and 10000-10100 to FTP server IP
# This is router-dependent; consult router interface
# Test FTP connection from remote machine
ftp your-server-ip
# Login with local user credentials
# Enable vsftpd to start on boot
sudo systemctl enable vsftpd
# Print the actual error on vsftp
sudo /usr/sbin/vsftpd /etc/vsftpd.conf
# 500 OOPS: vsftpd: refusing to run with writable root inside chroot() Connection closed by remote host.
$ nano /etc/vsftpd/vsftpd.conf ... allow_writeable_chroot=YES
# These files currently have permission 600 (rw-------) which blocks the web server
# Change permissions so the web server group (www-data) can read them
sudo chmod 664 /var/www/html/freeradius3-pfsense.html
sudo chmod 664 /var/www/html/mysql-remote.html
sudo chmod 664 /var/www/html/samba.html
# Fix all files uploaded by ftp-user at once
sudo find /var/www/html -type f -user ftp-user -exec chmod 664 {} \;
# Ensure directories allow group access
sudo find /var/www/html -type d -exec chmod 775 {} \;
# Step 5: Configure system so future FTP uploads work automatically
# Set directory owner and group
sudo chown -R ftp-user:www-data /var/www/html
# Enable setgid so new files inherit the www-data group
sudo chmod g+s /var/www/html
# Configure FTP server default permission mask
# Edit vsftpd configuration
sudo nano /etc/vsftpd.conf
# Add or modify this line
local_umask=002 # Files will be 664 and directories 775
# Restart FTP server to apply changes
sudo systemctl restart vsftpd
# Verify permissions after upload
ls -la /var/www/html
PHP Installation & Modules
PHP is required by many applications including Roundcube, WordPress, Laravel, moodle, etc.
sudo apt install php php-cli php-mysql php-curl php-gd php-xml php-mbstring php-intl php-zip libapache2-mod-php -y
# Check PHP version
php -v
# Restart Apache to load modules
sudo systemctl restart apache2
SSL Certificates with Certbot (Let's Encrypt)
SSL encrypts communication for HTTPS, IMAP, SMTP, and Roundcube. Certbot provides free, automated certificates.
sudo apt install certbot python3-certbot-apache -y
# Request an SSL certificate
sudo certbot --apache -d example.com -d www.example.com
# Certificate location
/etc/letsencrypt/live/example.com/
# Test renewal
sudo certbot renew --dry-run
MySQL Installation
MySQL powers databases for PHP applications. Correct configuration ensures security and performance.
sudo apt install mysql-server -y
# Secure installation
sudo mysql_secure_installation
# Log in as root
sudo mysql
# Create database
CREATE DATABASE exampledb;
# Create user with password
CREATE USER 'exampleuser'@'localhost' IDENTIFIED BY 'StrongPass123!';
# Grant privileges
GRANT ALL PRIVILEGES ON exampledb.* TO 'exampleuser'@'localhost';
FLUSH PRIVILEGES;
MySQL Remote Connection
Configure MySQL to allow remote connections while maintaining security and proper firewall rules.
sudo mysql -u root -p
# Create database (if not already created)
CREATE DATABASE exampledb;
# Create user and allow remote access
CREATE USER 'exampleuser'@'%' IDENTIFIED BY 'StrongPass123!';
# Grant privileges for the user
GRANT ALL PRIVILEGES ON exampledb.* TO 'exampleuser'@'%';
FLUSH PRIVILEGES;
# Enable MySQL to listen on all network interfaces
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# Change bind-address from 127.0.0.1 to 0.0.0.0
# Restart MySQL service to apply changes
sudo systemctl restart mysql
# Configure firewall (UFW) to allow MySQL port 3306
sudo ufw allow 3306/tcp
sudo ufw reload
# Test remote connection from another machine
mysql -u exampleuser -p -h your-server-ip
MySQL Backups
Backups protect against corruption, accidental deletion, and hardware failures.
mysqldump -u root -p exampledb > exampledb.sql
# Import database
mysql -u root -p exampledb < exampledb.sql
# Scheduled backup via cron
0 2 * * * mysqldump exampledb > /backup/exampledb-$(date +\%F).sql
Postfix (SMTP Server)
Postfix is the SMTP server used to send outgoing email. Below is the full installation, configuration, and explanation for a production mail server.
sudo apt install postfix -y
# Select configuration type:
# Internet Site
# Configure main Postfix settings
sudo nano /etc/postfix/main.cf
# Recommended settings
myhostname = mail.example.com
mydomain = example.com
myorigin = /etc/mailname
inet_interfaces = all
mydestination = \$myhostname, localhost.\$mydomain, localhost
home_mailbox = Maildir/
smtpd_tls_cert_file=/etc/letsencrypt/live/example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/example.com/privkey.pem
smtpd_use_tls=yes
smtp_tls_security_level = may
# Restart Postfix
sudo systemctl restart postfix
sudo systemctl status postfix
Dovecot (IMAP/POP3 Authentication)
Dovecot allows users to receive email using IMAP/POP3. It works together with Postfix to store and retrieve messages.
sudo apt install dovecot-core dovecot-imapd dovecot-pop3d -y
# Use Maildir format
sudo nano /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
# Enable SSL for IMAP
sudo nano /etc/dovecot/conf.d/10-ssl.conf
ssl = yes
ssl_cert =
ssl_key =
# Restart Dovecot
sudo systemctl restart dovecot
sudo systemctl status dovecot
OpenDKIM
OpenDKIM digitally signs outgoing mail so receiving servers trust your mail. Prevents spam and spoofing alerts.
sudo apt install opendkim opendkim-tools -y
# Configure OpenDKIM
sudo nano /etc/opendkim.conf
Syslog yes
UMask 002
Mode sv
KeyTable /etc/opendkim/key.table
SigningTable /etc/opendkim/signing.table
ExternalIgnoreList /etc/opendkim/trusted.hosts
InternalHosts /etc/opendkim/trusted.hosts
# Create signing directory
sudo mkdir -p /etc/opendkim/keys/example.com
# Generate DKIM key
sudo opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/*
# Add key to KeyTable
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
# Add signing entry
example.com mail._domainkey.example.com
# Restart service
sudo systemctl restart opendkim opendkim.service
OpenDMARC
OpenDMARC evaluates incoming email authenticity using SPF and DKIM. Helps prevent spoofing and phishing.
sudo apt install opendmarc -y
# Configure OpenDMARC
sudo nano /etc/opendmarc.conf
AuthservID mail.example.com
TrustedAuthservIDs mail.example.com
Socket inet:8893@localhost
# Restart OpenDMARC
sudo systemctl restart opendmarc
Roundcube Webmail
Roundcube provides a full-featured webmail client for IMAP.
sudo apt install roundcube roundcube-core roundcube-mysql -y
# Apache integration
sudo a2enconf roundcube
sudo systemctl reload apache2
# Set Roundcube config
sudo nano /etc/roundcube/config.inc.php
DNS Records for Email (MX, SPF, DKIM, DMARC)
Correct DNS configuration is mandatory for mail delivery. Most issues come from missing or incorrect DNS records.
example.com. 3600 IN MX 10 mail.example.com.
# SPF Record
example.com. IN TXT "v=spf1 mx a ip4:YOUR_SERVER_IP ~all"
# DKIM Record
mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=PUBLIC_KEY_HERE"
# DMARC Record
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:admin@example.com"
Testing Email Delivery
These tests verify that mail successfully leaves the SMTP server and arrives at its destination.
echo "Test body" | mail -s "Test Subject" user@example.com
# Debug email
echo -e "Subject: Test\nHello world" | sendmail -v user@example.com
# Test SMTP port
telnet mail.example.com 25
Email Troubleshooting & Logs
Logs provide clues when messages fail to send or authenticate.
sudo tail -f /var/log/mail.log
# Inspect queued messages
sudo postqueue -p
# View specific message
sudo postcat -q QUEUE_ID
# Check Dovecot authentication
sudo journalctl -u dovecot -n 50
# Check Postfix errors
sudo journalctl -u postfix -n 50