Server Setup

You just got a fresh VPS. It's running Ubuntu, has a root password, and that's it. Let's make it production-ready.

Step 1: First Login

Terminal
$ssh root@your-server-ip
root@your-server-ip's password:

Step 2: Update Everything

Terminal
$apt update && apt upgrade -y
Reading package lists... ...

Step 3: Create a Regular User

Never work as root. Create a user with sudo access:

Terminal
$adduser deploy
Adding user 'deploy'... New password:
$usermod -aG sudo deploy
$su - deploy
deploy@server:~$

Step 4: Set Up SSH Keys

On your local machine:

Terminal
$# Generate key if you don't have one
$ssh-keygen -t ed25519 -C 'your@email.com'
$
$# Copy to server
$ssh-copy-id deploy@your-server-ip

Or manually on the server:

Terminal
$mkdir -p ~/.ssh
$chmod 700 ~/.ssh
$nano ~/.ssh/authorized_keys
(paste your public key)
$chmod 600 ~/.ssh/authorized_keys

Step 5: Secure SSH

Terminal
$sudo nano /etc/ssh/sshd_config

Change these settings:

# Disable root login
PermitRootLogin no

# Disable password authentication
PasswordAuthentication no

# Optionally change port
# Port 2222
Terminal
$sudo systemctl restart sshd

Don't Lock Yourself Out

Before disabling password auth, make sure your SSH key works! Open a new terminal and test logging in with the key.

Step 6: Set Up Firewall

Terminal
$# Install ufw if not present
$sudo apt install ufw
$
$# Allow SSH first!
$sudo ufw allow ssh
$
$# Allow web traffic
$sudo ufw allow 80/tcp
$sudo ufw allow 443/tcp
$
$# Enable firewall
$sudo ufw enable
$
$# Check status
$sudo ufw status
Status: active To Action From 22/tcp ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere

Step 7: Install Essential Tools

Terminal
$sudo apt install -y \ git \ curl \ wget \ vim \ htop \ unzip \ fail2ban

Step 8: Configure fail2ban

Protect against brute force attacks:

Terminal
$sudo systemctl enable --now fail2ban
$sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 0 | `- Total failed: 15 `- Actions |- Currently banned: 2 `- Total banned: 5

Step 9: Set Timezone

Terminal
$sudo timedatectl set-timezone UTC
$timedatectl
Time zone: UTC (UTC, +0000)

Step 10: Automatic Security Updates

Terminal
$sudo apt install unattended-upgrades
$sudo dpkg-reconfigure -plow unattended-upgrades
(select Yes)

Server Setup Checklist

□ System updated
□ Non-root user created
□ User added to sudo group
□ SSH keys configured
□ Root login disabled
□ Password auth disabled
□ Firewall enabled (SSH allowed)
□ fail2ban installed
□ Timezone set
□ Automatic updates enabled

Install a Web Server

Nginx

Terminal
$sudo apt install nginx
$sudo systemctl enable --now nginx
$curl localhost
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title>

Let's Encrypt SSL

Terminal
$sudo apt install certbot python3-certbot-nginx
$sudo certbot --nginx -d yourdomain.com
(follow prompts)

Complete Setup Script

hljs bash
#!/bin/bash
# server-setup.sh - Run as root on fresh Ubuntu

set -euo pipefail

USERNAME="deploy"

# Update system
apt update && apt upgrade -y

# Create user
adduser --gecos "" "$USERNAME"
usermod -aG sudo "$USERNAME"

# SSH hardening
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# Install essentials
apt install -y git curl wget vim htop unzip fail2ban ufw

# Firewall
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

# Enable services
systemctl enable --now fail2ban

# Timezone
timedatectl set-timezone UTC

# Automatic updates
apt install -y unattended-upgrades
echo 'Unattended-Upgrade::Automatic-Reboot "false";' > /etc/apt/apt.conf.d/50unattended-upgrades-local

echo "Setup complete!"
echo "Remember to:"
echo "1. Add SSH key to /home/$USERNAME/.ssh/authorized_keys"
echo "2. Test SSH login before disconnecting"
echo "3. Run: systemctl restart sshd"
Knowledge Check

Why should you add your SSH key before disabling password authentication?

Key Takeaways

  • Never work as root - create a sudo user
  • SSH keys before disabling password auth
  • UFW is simple but effective firewall
  • fail2ban protects against brute force
  • Automatic security updates are essential
  • Test connectivity at each step

Next: introduction to Docker.