Step-by-step setup guide covering system updates, hostname/timezone, sudo user creation, SSH hardening, UFW firewall, CrowdSec with nftables bouncer, Zsh shell setup, and instance verification commands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.1 KiB
Ubuntu Server Instance Setup Guide
Table of Contents
- Initial System Update
- Hostname & Timezone
- Create a Sudo User
- SSH Hardening
- Copy SSH Key
- UFW Firewall
- CrowdSec Intrusion Detection
- Shell Setup (Zsh)
- Verify Instance Settings
1. Initial System Update
sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y
2. Hostname & Timezone
# Set hostname
sudo hostnamectl set-hostname your-hostname
# Set timezone to Nairobi
sudo timedatectl set-timezone Africa/Nairobi
# Enable NTP time sync
sudo timedatectl set-ntp true
sudo apt install systemd-timesyncd -y
sudo systemctl enable --now systemd-timesyncd
# Verify
hostnamectl
timedatectl status
Expected NTP output:
NTP service: active
System clock synchronized: yes
3. Create a Sudo User
# Create user
sudo adduser username
# Add to sudo group
sudo usermod -aG sudo username
# Verify
groups username
4. SSH Hardening
Important: Copy your SSH key (Step 5) BEFORE disabling password authentication or you will lock yourself out.
sudo nano /etc/ssh/sshd_config
Set the following values:
# Disable root login
PermitRootLogin no
# Disable password authentication (keys only — do AFTER copying SSH key)
PasswordAuthentication no
# Disable empty passwords
PermitEmptyPasswords no
# Only allow specific users
AllowUsers your-username
# Disable X11 forwarding
X11Forwarding no
# Reduce login grace time
LoginGraceTime 30
# Limit authentication attempts
MaxAuthTries 3
# Limit simultaneous unauthenticated connections
MaxStartups 3:50:10
# Disable unused authentication methods
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
# SSH protocol 2 only
Protocol 2
# Idle timeout (10 minutes)
ClientAliveInterval 300
ClientAliveCountMax 2
Optionally change the default SSH port (reduces bot noise):
Port 2222
Test config and restart:
sudo sshd -t # test for errors first
sudo systemctl restart sshd
Before closing your session open a second SSH connection to confirm you can still log in.
If you changed the port, update UFW before restarting sshd:
sudo ufw allow 2222/tcp
sudo ufw delete allow ssh
sudo systemctl restart sshd
Connect going forward with:
ssh -p 2222 username@server-ip
5. Copy SSH Key
Run this from your local machine:
ssh-copy-id username@server-ip
# If using a non-standard port
ssh-copy-id -p 2222 username@server-ip
# If specifying a key explicitly
ssh-copy-id -i ~/.ssh/id_rsa.pub username@server-ip
Test passwordless login:
ssh username@server-ip
6. UFW Firewall
# Set default rules
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (do this BEFORE enabling)
sudo ufw allow ssh
# Or if using custom port:
sudo ufw allow 2222/tcp
# Allow web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable firewall
sudo ufw enable
# Verify
sudo ufw status verbose
Add any additional ports your services need:
# Grafana
sudo ufw allow 3000/tcp
# Webhook receiver
sudo ufw allow 8888/tcp
# PostgreSQL (only if external access needed)
sudo ufw allow 5432/tcp
7. CrowdSec Intrusion Detection
Install CrowdSec
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec -y
Install Firewall Bouncer
sudo apt install crowdsec-firewall-bouncer -y
Configure for nftables (default on Ubuntu 22+)
sudo nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
Confirm top of file:
mode: ${BACKEND}
Ensure nftables is enabled:
nftables:
ipv4:
enabled: true
ipv6:
enabled: false
Restart bouncer:
sudo systemctl restart crowdsec-firewall-bouncer
sudo systemctl status crowdsec-firewall-bouncer
Enroll with CrowdSec Console (Recommended)
Register at https://app.crowdsec.net, grab your enroll key, then:
sudo cscli console enroll <your-enroll-key>
sudo systemctl restart crowdsec
Update Collections
sudo cscli hub update
sudo cscli collections upgrade --all
Whitelist Your Own IP
sudo nano /etc/crowdsec/parsers/s02-enrich/whitelists.yaml
name: crowdsecurity/whitelists
description: "Whitelist trusted IPs"
whitelist:
reason: "trusted management IPs"
ip:
- "<your-home-ip>"
- "<your-vpn-ip>"
sudo systemctl restart crowdsec
Test CrowdSec Is Working
# Add a test ban
sudo cscli decisions add --ip 1.2.3.4 --duration 5m --reason "test"
# Verify it registered
sudo cscli decisions list
# Remove the test ban
sudo cscli decisions delete --ip 1.2.3.4
Useful CrowdSec Commands
sudo cscli decisions list # active bans
sudo cscli alerts list # recent alerts
sudo cscli bouncers list # registered bouncers
sudo cscli collections list # installed collections
sudo cscli metrics # ingestion metrics
8. Shell Setup (Zsh)
# Install zsh
sudo apt install zsh -y
# Set as default shell
chsh -s $(which zsh)
Log out and back in, then verify:
echo $SHELL # should return /usr/bin/zsh
Optional — install Oh My Zsh:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
9. Verify Instance Settings
Run this to get a full summary of the instance:
echo "=== HOSTNAME ===" && hostnamectl | grep -E "hostname|OS|Kernel" && \
echo "=== CPU ===" && lscpu | grep -E "Model name|CPU\(s\):" && \
echo "=== RAM ===" && free -h | grep Mem && \
echo "=== DISK ===" && df -h / && \
echo "=== IP ===" && ip addr show | grep "inet " && \
echo "=== TIMEZONE ===" && timedatectl | grep -E "Time zone|NTP|synchronized"
Or individually:
hostnamectl # hostname, OS, kernel
lscpu | grep -E "Model|CPU\(s\)" # CPU
free -h # RAM
df -h # disk
ip addr show # network interfaces
ss -tlnp # listening ports
timedatectl # timezone and NTP
sudo ufw status verbose # firewall rules
sudo systemctl status crowdsec # CrowdSec status
sudo systemctl status crowdsec-firewall-bouncer # bouncer status
Quick Reference Checklist
- System updated (
apt update && apt upgrade) - Hostname set
- Timezone set to
Africa/Nairobi - NTP enabled and syncing
- Sudo user created
- SSH key copied to server
- SSH hardened (no root login, no password auth)
- UFW enabled with correct ports open
- CrowdSec installed and running
- Firewall bouncer installed and running
- Own IP whitelisted in CrowdSec
- Zsh set as default shell