Security Basics

Your server is on the internet. Attackers are scanning it right now. Let's make their job harder.

The Attacker's Perspective

What they try first:

  1. SSH brute force (root / common passwords)
  2. Scan for open ports with vulnerable services
  3. Exploit known vulnerabilities in outdated software
  4. Attack web applications

SSH Security

Disable Root Login

Terminal
$sudo nano /etc/ssh/sshd_config
PermitRootLogin no

Use SSH Keys Only

PasswordAuthentication no
PubkeyAuthentication yes

Change Default Port (Optional)

Port 2222

Don't forget to update your firewall:

Terminal
$sudo ufw allow 2222/tcp
$sudo ufw delete allow ssh
$sudo systemctl restart sshd

Test Before Disconnecting

After SSH changes, open a new terminal and test the connection before closing your current session.

Firewall with UFW

Terminal
$# Default deny incoming
$sudo ufw default deny incoming
$sudo ufw default allow outgoing
$
$# Only allow what you need
$sudo ufw allow ssh
$sudo ufw allow 80/tcp
$sudo ufw allow 443/tcp
$
$# Enable
$sudo ufw enable
$
$# Check status
$sudo ufw status verbose

Allow Specific IPs

Terminal
$# Only allow SSH from office IP
$sudo ufw allow from 203.0.113.50 to any port 22

Keep Software Updated

Terminal
$# Regular updates
$sudo apt update && sudo apt upgrade -y
$
$# Security updates only
$sudo unattended-upgrades --dry-run
$
$# Enable automatic security updates
$sudo apt install unattended-upgrades
$sudo dpkg-reconfigure unattended-upgrades

fail2ban - Block Brute Force

Terminal
$sudo apt install fail2ban
$sudo systemctl enable --now fail2ban
$
$# Check banned IPs
$sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 3 | `- Total failed: 150 `- Actions |- Currently banned: 12 `- Total banned: 45

Custom configuration:

Terminal
$sudo nano /etc/fail2ban/jail.local
hljs ini
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 1h
findtime = 10m

File Permissions

Terminal
$# Home directories: owner only
$chmod 700 ~
$
$# SSH directory: strict permissions
$chmod 700 ~/.ssh
$chmod 600 ~/.ssh/authorized_keys
$chmod 600 ~/.ssh/id_ed25519
$
$# Find world-writable files
$find / -perm -002 -type f 2>/dev/null

Principle of Least Privilege

  • Don't run services as root
  • Create dedicated service users
  • Use sudo instead of root shell
  • Grant minimum required permissions
hljs bash
# Bad: running app as root
sudo node server.js

# Good: dedicated user
sudo -u appuser node server.js

# Better: systemd service as non-root
# In service file: User=appuser

Monitor Your System

Check Login Attempts

Terminal
$# Failed logins
$sudo grep 'Failed password' /var/log/auth.log | tail -20
$
$# Successful logins
$last | head -10
$
$# Currently logged in
$who
john pts/0 2025-01-14 10:00 (192.168.1.50)

Check Open Ports

Terminal
$sudo ss -tulpn
State Local Address:Port Process LISTEN 0.0.0.0:22 sshd LISTEN 0.0.0.0:80 nginx LISTEN 127.0.0.1:3306 mysqld

If you see unexpected ports, investigate.

Security Checklist

□ SSH: Key auth only, root disabled
□ Firewall enabled, minimal ports open
□ Automatic security updates
□ fail2ban protecting SSH
□ Services running as non-root
□ Regular backups
□ Monitoring for anomalies
□ Strong passwords where needed
□ Software kept updated
Knowledge Check

Why should you disable password authentication for SSH?

Quick Reference

ActionCommand
Check open portssudo ss -tulpn
Check firewallsudo ufw status
Check failed loginsgrep 'Failed' /var/log/auth.log
Check banned IPssudo fail2ban-client status sshd
Update systemsudo apt update && sudo apt upgrade
Check running servicessystemctl list-units --type=service

Key Takeaways

  • SSH: keys only, no root, consider changing port
  • Firewall: default deny, allow only what's needed
  • Keep software updated (automatic is good)
  • fail2ban blocks brute force attacks
  • Run services as non-root users
  • Monitor logs for suspicious activity
  • Security is ongoing, not a one-time setup

Next: where to go from here.