Add Ubuntu instance deployment guide
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>
This commit is contained in:
parent
82761e1e3f
commit
791bf2700c
1 changed files with 379 additions and 0 deletions
379
deployInstance.md
Normal file
379
deployInstance.md
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
# Ubuntu Server Instance Setup Guide
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Initial System Update](#1-initial-system-update)
|
||||
2. [Hostname & Timezone](#2-hostname--timezone)
|
||||
3. [Create a Sudo User](#3-create-a-sudo-user)
|
||||
4. [SSH Hardening](#4-ssh-hardening)
|
||||
5. [Copy SSH Key](#5-copy-ssh-key)
|
||||
6. [UFW Firewall](#6-ufw-firewall)
|
||||
7. [CrowdSec Intrusion Detection](#7-crowdsec-intrusion-detection)
|
||||
8. [Shell Setup (Zsh)](#8-shell-setup-zsh)
|
||||
9. [Verify Instance Settings](#9-verify-instance-settings)
|
||||
|
||||
---
|
||||
|
||||
## 1. Initial System Update
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt autoremove -y
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Hostname & Timezone
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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.
|
||||
|
||||
```bash
|
||||
sudo nano /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
Set the following values:
|
||||
|
||||
```bash
|
||||
# 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):
|
||||
|
||||
```bash
|
||||
Port 2222
|
||||
```
|
||||
|
||||
Test config and restart:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo ufw allow 2222/tcp
|
||||
sudo ufw delete allow ssh
|
||||
sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
Connect going forward with:
|
||||
|
||||
```bash
|
||||
ssh -p 2222 username@server-ip
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Copy SSH Key
|
||||
|
||||
Run this from your **local machine**:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
ssh username@server-ip
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. UFW Firewall
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
|
||||
sudo apt install crowdsec -y
|
||||
```
|
||||
|
||||
### Install Firewall Bouncer
|
||||
|
||||
```bash
|
||||
sudo apt install crowdsec-firewall-bouncer -y
|
||||
```
|
||||
|
||||
### Configure for nftables (default on Ubuntu 22+)
|
||||
|
||||
```bash
|
||||
sudo nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
|
||||
```
|
||||
|
||||
Confirm top of file:
|
||||
|
||||
```yaml
|
||||
mode: ${BACKEND}
|
||||
```
|
||||
|
||||
Ensure nftables is enabled:
|
||||
|
||||
```yaml
|
||||
nftables:
|
||||
ipv4:
|
||||
enabled: true
|
||||
ipv6:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
Restart bouncer:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo cscli console enroll <your-enroll-key>
|
||||
sudo systemctl restart crowdsec
|
||||
```
|
||||
|
||||
### Update Collections
|
||||
|
||||
```bash
|
||||
sudo cscli hub update
|
||||
sudo cscli collections upgrade --all
|
||||
```
|
||||
|
||||
### Whitelist Your Own IP
|
||||
|
||||
```bash
|
||||
sudo nano /etc/crowdsec/parsers/s02-enrich/whitelists.yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
name: crowdsecurity/whitelists
|
||||
description: "Whitelist trusted IPs"
|
||||
whitelist:
|
||||
reason: "trusted management IPs"
|
||||
ip:
|
||||
- "<your-home-ip>"
|
||||
- "<your-vpn-ip>"
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl restart crowdsec
|
||||
```
|
||||
|
||||
### Test CrowdSec Is Working
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
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)
|
||||
|
||||
```bash
|
||||
# Install zsh
|
||||
sudo apt install zsh -y
|
||||
|
||||
# Set as default shell
|
||||
chsh -s $(which zsh)
|
||||
```
|
||||
|
||||
Log out and back in, then verify:
|
||||
|
||||
```bash
|
||||
echo $SHELL # should return /usr/bin/zsh
|
||||
```
|
||||
|
||||
Optional — install Oh My Zsh:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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
|
||||
Loading…
Reference in a new issue