This final part of the Linux series covers security hardening — making a Linux server resistant to attacks and unauthorized access. Every internet-facing server needs these practices. Security is not a feature you add later — it is a set of habits you build from the start.
# Disable root SSH login
sudo nano /etc/ssh/sshd_config
# Set: PermitRootLogin no
# Set: PasswordAuthentication no (force key-based auth)
# Set: MaxAuthTries 3
sudo systemctl restart ssh
# Create sudo user instead of using root
sudo adduser deploy
sudo usermod -aG sudo deploy
# Lock unused accounts
sudo passwd -l username
# Check failed login attempts
grep "Failed password" /var/log/auth.log | tail -20
lastb | head -20
# Generate key pair on your local machine
ssh-keygen -t ed25519 -C "suraj@srjahir.in"
# Copy public key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Or manually:
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Set correct permissions on server
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
sudo ufw default deny incoming # Block all incoming by default
sudo ufw default allow outgoing # Allow all outgoing
sudo ufw allow from YOUR_IP to any port 22 # SSH from your IP only
sudo ufw allow 80 # HTTP
sudo ufw allow 443 # HTTPS
sudo ufw enable
sudo ufw status verbose
sudo apt install fail2ban
sudo systemctl enable fail2ban
# Configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
# [sshd]
# enabled = true
# maxretry = 5
# bantime = 3600
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd # See banned IPs
sudo apt update && sudo apt upgrade -y # Apply all updates
sudo apt install unattended-upgrades # Auto security updates
sudo dpkg-reconfigure unattended-upgrades # Configure auto-updates
sudo unattended-upgrade --dry-run # Preview changes
sudo apt install aide # Advanced Intrusion Detection Environment
sudo aideinit # Initialize baseline database
sudo aide --check # Compare current state to baseline
# Auditd for logging
sudo apt install auditd
sudo auditctl -w /etc/passwd -p rwxa -k passwd_changes
sudo ausearch -k passwd_changes # Search audit log
Here is a practical security checklist for every new Linux server you set up:
Security is not a one-time task — it is an ongoing practice. Systems that were secure a year ago may not be secure today because new vulnerabilities are discovered constantly. Subscribe to security advisories for your distribution and review logs regularly.
Congratulations on completing the Linux tutorial series. You now have the foundation to operate Linux servers, write automation scripts, manage security, and work confidently in any Linux-based environment.
Security on a Linux server requires ongoing monitoring, not just initial hardening. The /var/log/auth.log file (Ubuntu) or /var/log/secure (RHEL) records all authentication events including SSH login attempts and sudo usage. Check it regularly: grep "Failed password" /var/log/auth.log | tail -20 shows recent failed SSH attempts. fail2ban automatically parses auth logs and temporarily bans IPs showing brute-force patterns — essential for any internet-facing server. Install with sudo apt install fail2ban and it works with sensible defaults immediately. Review its jail status with sudo fail2ban-client status sshd to see how many IPs have been banned.
A practical security maintenance routine for Linux servers: keep the system updated — sudo apt update && sudo apt upgrade weekly at minimum, and configure unattended-upgrades for automatic security patches. Review user accounts periodically — cat /etc/passwd to check for unexpected accounts, last to see recent logins. Check for world-writable files: find /etc /var /usr -perm -002 -type f 2>/dev/null. Verify SSH configuration — root login disabled, password authentication off if keys are in use. Review open ports regularly: ss -tulnp and verify each service should be running. Check for failed services: systemctl --failed.
Perform a basic security audit: check for accounts with UID 0 using awk -F: '($3 == 0)' /etc/passwd, check SSH configuration with grep -E "PermitRootLogin|PasswordAuthentication|Port" /etc/ssh/sshd_config, list all listening network services with ss -tulnp, check recent authentication events with tail -50 /var/log/auth.log, and find recently modified files in /etc with find /etc -mtime -7 -type f. Document what you find and research the correct secure configuration for any items that need attention.
Linux command-line proficiency is not something you learn once and then stop improving. It is a skill that deepens continuously as you encounter new tools, new use cases, and new problems to solve. The engineers who are most effective at the command line did not become that way by reading comprehensive guides — they became that way by spending years solving real problems at the terminal, gradually accumulating a toolkit of commands, aliases, scripts, and muscle memory. The best approach is to use Linux for real work as much as possible, to look up better ways to do things you already do, and to make note of efficient patterns you observe in others' work. Over time, the terminal becomes faster than any GUI for the tasks you do repeatedly.
Every topic in technology and finance rewards the learner who goes beyond surface understanding to build genuine fluency. Fluency comes from repeated exposure, application in varied contexts, and reflection on what worked and what did not. The concepts discussed here are starting points — each one opens into a deeper field of study that could occupy years of focused learning. The most effective approach is not to try to master everything at once, but to pick the areas most relevant to your current goals, go deep there, and then expand. Depth in a few areas is more valuable than shallow familiarity with many. Build on what you know, stay curious about what you do not, and keep the practice of learning as a consistent daily habit rather than an occasional burst of effort.
The questions that make learning stick: How does this connect to what I already know? Where would I actually use this? What would happen if I tried to explain this to someone who knows nothing about it? What are the edge cases and exceptions? What is still unclear? Asking these questions transforms passive reading into active learning, and active learning is what builds the kind of understanding that is still accessible years later when you need it under real conditions.