- Fresh Ubuntu/Debian server installation
- Root or sudo access
- Basic familiarity with command line
# Update package lists and upgrade system
sudo apt update && sudo apt upgrade -y
# Install essential packages
sudo apt install -y curl wget git unzip software-properties-common apt-transport-https ca-certificates gnupg lsb-release# Create backup of original SSH config
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup# Edit SSH daemon configuration
sudo nano /etc/ssh/sshd_configKey changes to make:
# Change default port (choose a port between 1024-65535)
Port 2222
# Disable root login
PermitRootLogin no
# Use only SSH protocol 2
Protocol 2
# Limit login attempts
MaxAuthTries 3
MaxSessions 2
# Set login grace time
LoginGraceTime 60
# Enable public key authentication
PubkeyAuthentication yes
# Disable password authentication (after setting up SSH keys)
PasswordAuthentication yes # Keep as 'yes' initially, change to 'no' after SSH key setup
# Disable empty passwords
PermitEmptyPasswords no
# Disable X11 forwarding if not needed
X11Forwarding no
# Set allowed users (replace 'yourusername' with your actual username)
AllowUsers yourusername
# Add these additional security settings
ClientAliveInterval 300
ClientAliveCountMax 2# Test the configuration for syntax errors
sudo sshd -t
# If no errors, restart SSH service
sudo systemctl restart sshd
# Check SSH service status
sudo systemctl status sshdImportant: Before closing your current session, test the new SSH port in a new terminal:
# Test connection with new port (replace 2222 with your chosen port)
ssh -p 2222 yourusername@your-server-ip# Generate SSH key pair
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# Copy public key to server
ssh-copy-id -p 2222 yourusername@your-server-ipOnce SSH key authentication is working:
# Edit SSH config again
sudo nano /etc/ssh/sshd_config
# Change this line
PasswordAuthentication no
# Restart SSH
sudo systemctl restart sshd# UFW is usually pre-installed, but just in case
sudo apt install -y ufw# Reset UFW to defaults
sudo ufw --force reset
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH on your custom port (replace 2222 with your port)
sudo ufw allow 2222/tcp comment 'SSH Custom Port'
# Allow HTTP traffic
sudo ufw allow 80/tcp comment 'HTTP'
# Allow HTTPS traffic
sudo ufw allow 443/tcp comment 'HTTPS'
# Limit SSH connections to prevent brute force (optional but recommended)
sudo ufw limit 2222/tcp
# Enable UFW
sudo ufw enable
# Check UFW status
sudo ufw status verboseTo ensure UFW only handles IPv4 traffic:
# Edit UFW configuration
sudo nano /etc/default/ufw
# Set IPv6 to no
IPV6=no
# Restart UFW
sudo ufw disable
sudo ufw enable# Install Fail2Ban
sudo apt install -y fail2ban# Create local configuration file
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit the local configuration
sudo nano /etc/fail2ban/jail.localAdd or modify these settings in /etc/fail2ban/jail.local:
[DEFAULT]
# Ban time in seconds (10 minutes)
bantime = 600
# Time window to count failures (10 minutes)
findtime = 600
# Number of failures before ban
maxretry = 3
# Ignore local connections
ignoreip = 127.0.0.1/8 ::1
# Email settings (optional)
destemail = [email protected]
sendername = Fail2Ban
mta = sendmail
[sshd]
enabled = true
# Use your custom SSH port
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
[apache-auth]
enabled = true
filter = apache-auth
logpath = /var/log/apache*/*error.log
[apache-badbots]
enabled = true
filter = apache-badbots
logpath = /var/log/apache*/*access.logCreate a custom filter for repeated HTTP 404 errors:
# Create custom filter
sudo nano /etc/fail2ban/filter.d/nginx-404.confAdd this content:
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" 404.*$
ignoreregex =Add jail configuration:
# Add to jail.local
sudo nano /etc/fail2ban/jail.localAppend:
[nginx-404]
enabled = true
filter = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 3600# Start and enable Fail2Ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# Check Fail2Ban status
sudo systemctl status fail2ban
# Check active jails
sudo fail2ban-client status
# Check specific jail status
sudo fail2ban-client status sshd# Install unattended-upgrades
sudo apt install -y unattended-upgrades
# Configure automatic updates
sudo dpkg-reconfigure -plow unattended-upgrades
# Edit configuration (optional)
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades# Install logwatch for log monitoring
sudo apt install -y logwatch
# Configure logwatch
sudo nano /usr/share/logwatch/default.conf/logwatch.conf
# Run logwatch manually to test
sudo logwatch --detail High --mailto [email protected] --service All --range yesterday# List all running services
sudo systemctl list-unit-files --type=service --state=enabled
# Disable unnecessary services (examples)
sudo systemctl disable bluetooth
sudo systemctl disable cups
sudo systemctl disable avahi-daemon
# Stop services immediately
sudo systemctl stop bluetooth
sudo systemctl stop cups
sudo systemctl stop avahi-daemon# Check UFW status and rules
sudo ufw status numbered
# View Fail2Ban banned IPs
sudo fail2ban-client status sshd
# Unban an IP if needed
sudo fail2ban-client set sshd unbanip IP_ADDRESS
# View recent authentication attempts
sudo tail -f /var/log/auth.log
# Check open ports
sudo netstat -tulpn
# Or using ss (modern alternative)
sudo ss -tulpn
# Check system logs
sudo journalctl -f# Update system packages
sudo apt update && sudo apt upgrade
# Check for security updates
sudo apt list --upgradable
# Clean package cache
sudo apt autoremove && sudo apt autoclean
# Check disk usage
df -h
# Check memory usage
free -h
# Check system uptime and load
uptime# Create backup directory
mkdir -p ~/server-backups
# Backup important configurations
sudo cp /etc/ssh/sshd_config ~/server-backups/
sudo cp /etc/fail2ban/jail.local ~/server-backups/
sudo cp -r /etc/ufw ~/server-backups/
# Make backups readable by your user
sudo chown -R $USER:$USER ~/server-backups/SSH Connection Issues:
# Check SSH service status
sudo systemctl status sshd
# Check if SSH is listening on correct port
sudo netstat -tlnp | grep :2222
# Check SSH logs
sudo journalctl -u sshUFW Issues:
# Check UFW status
sudo ufw status verbose
# Reset UFW if needed
sudo ufw --force reset
# Reload UFW rules
sudo ufw reloadFail2Ban Issues:
# Check Fail2Ban logs
sudo journalctl -u fail2ban
# Restart Fail2Ban
sudo systemctl restart fail2ban
# Check configuration syntax
sudo fail2ban-client -d- Changed default SSH port
- Disabled root login via SSH
- Set up SSH key authentication
- Disabled password authentication
- Configured UFW firewall
- Installed and configured Fail2Ban
- Set up automatic security updates
- Disabled unnecessary services
- Created configuration backups
- Tested all configurations
- Always test SSH connections in a new terminal before closing your current session
- Keep your SSH private key secure and create backups
- Document your custom SSH port and keep it secure
- Regularly monitor logs for suspicious activity
- Keep your system updated with security patches
- Consider setting up monitoring tools like Nagios or Zabbix for production servers
This setup provides a solid foundation for a secure Ubuntu/Debian server suitable for web development and production environments.