Skip to content

Preparing new vps from scratch

cloud-init scripts >> try this instead

initial debian setup

set hostname (required on minimal Debian systems)

hostnamectl set-hostname your-server-name

Verify hostname change: Run the command below to confirm the change took effect without requiring a reboot:

hostname

Update /etc/hosts file: After changing the hostname, you must update the hosts file to prevent "unable to resolve host" errors with sudo:

# Check current hosts file
cat /etc/hosts

# Add your new hostname to localhost line or add a new line
echo "127.0.0.1 localhost $(hostname)" > /etc/hosts
# OR edit manually with:
# nano /etc/hosts

Test hostname resolution: Verify sudo works with the new hostname:

sudo echo "Hostname resolution working"

⚠️ IMPORTANT: Without updating /etc/hosts, sudo commands will fail with "unable to resolve host" errors. If this happens, you may need to close and reopen your terminal to continue.

install sudo (not included in minimal Debian)

apt update && apt install sudo

Note: If you see "Release file is expired" errors during apt update, you can:

# Option 1: Use only security updates repository temporarily
echo "deb http://deb.debian.org/debian-security $(lsb_release -cs)-security main" > /etc/apt/sources.list.d/security.list
apt update

# Option 2: Force use of expired repositories (less secure)
apt -o Acquire::Check-Valid-Until=false update

add root user to sudoers (if needed)

usermod -aG sudo root

update

update the thing to current

# Update package lists
sudo apt-get update

# Upgrade packages WITHOUT restarting services (safest option)
sudo apt-get upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --no-install-recommends

# OR if prompted about service restarts, select "none" or press Tab to select <No automatic restart>

⚠️ IMPORTANT: Avoid restarting services (especially SSH) during initial setup as this could disconnect your session. We'll do a proper reboot at the end after everything is configured.

add swap

First, check if swap already exists:

# Check current swap usage and size
free -h | grep -i swap

# See active swap devices (if any)
swapon --show

# Check if swap is already configured in fstab
grep -i swap /etc/fstab

If no swap exists or you need more, create a swap file:

# Create a 2GB swap file (adjust size as needed)
fallocate -l 2G /swapfile && chmod 600 /swapfile

mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sysctl vm.swappiness=10
sysctl vm.vfs_cache_pressure=50
# Edit sysctl configuration file
nano /etc/sysctl.conf

Add these settings to the file:

# Swap optimization settings
vm.swappiness=10
vm.vfs_cache_pressure=50

install basics

First, install essential packages missing in minimal Debian:

# Core utilities and tools
apt install -y sudo gpg gnupg curl wget vim nano

# System monitoring and network tools
apt install -y htop net-tools iftop iotop nload dnsutils iputils-ping

# Security tools
apt install -y fail2ban ufw

# Development essentials
apt install -y git make build-essential

# Container management (if needed)
apt install -y docker.io docker-compose

Verify installed packages:

# Check which packages from the list were successfully installed
dpkg -l | grep -E "sudo|gpg|curl|htop|net-tools|fail2ban|docker"

install portainer

cheatsheets/portainer-standalone/

add overlay

install zerotier

curl -s 'https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg' | gpg --import && \
if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | sudo bash; fi

add machine to overlay network

zerotier-cli join YOUR_ZERTIER_NETWORK_ID

identify ZeroTier interface (it starts with "zt")

# Look for interface that starts with zt
ifconfig | grep -A 1 zt

find ZeroTier IP address (note this for later SSH access)

# Identify your ZeroTier IP address
export INTERFACE=$(ifconfig | grep -o "zt[0-9a-zA-Z]*")
ip addr show $INTERFACE | grep "inet " | awk '{print $2}' | cut -d/ -f1

allow traffic from all zerotier network devices

# Use the actual ZeroTier interface name (not the network ID)
export INTERFACE=$(ifconfig | grep -o "zt[0-9a-zA-Z]*")
ufw allow in on $INTERFACE

add user

create mr user

adduser koad

make new user sudo

usermod -aG sudo koad

setup passwordless sudo for the user

# Create a sudoers file for koad user
echo "koad ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/koad

# Set proper permissions
chmod 440 /etc/sudoers.d/koad

# Verify the syntax is correct (prevents lockouts from bad sudoers files)
visudo -c

SSH Configuration and Reboot Safety

Before proceeding to the lockdown phase, ensure you've properly configured SSH access:

SSH Configuration:

# Check current SSH configuration
grep "PermitRootLogin\|PasswordAuthentication" /etc/ssh/sshd_config

# If needed, edit SSH config to temporarily ensure access during setup
sudo nano /etc/ssh/sshd_config

Key settings to verify in /etc/ssh/sshd_config: * PermitRootLogin yes - Temporarily enable during setup (change to no after user setup complete) * PasswordAuthentication yes - Ensure password login works until SSH keys are configured

Before rebooting: 1. Verify koad user exists: id koad 2. Confirm koad has sudo access: sudo -l -U koad 3. Test SSH access for koad user from a separate terminal window 4. Create a backup access method (SSH key, console access, etc.)

💡 TIP: For maximum safety, test SSH login as koad user before restricting root login

add user to docker group
```bash
sudo groupadd docker
sudo usermod -aG docker koad

preparing for lockdown

cheatsheets/uncomplicated-firewall/

Configure firewall rules (but don't enable UFW yet):

# Configure ZeroTier interface rules
# These will only take effect when UFW is enabled in the final step
export INTERFACE=YOUR_ZEROTIER_NETWORK_ID
ufw allow in on $INTERFACE

⚠️ DANGER: Do NOT enable UFW yet! We'll do this as the very last step before rebooting to prevent lockouts.

install keybase

curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb
sudo apt install ./keybase_amd64.deb

Final Steps

Pre-reboot verification checklist:

# Verify hostname is properly set and resolvable
hostname
sudo hostname

# Confirm user accounts are properly set up
id koad
sudo -l -U koad

# Verify SSH access works for non-root user
# Test this from a separate terminal window!

# Confirm all critical services are enabled
systemctl list-unit-files | grep enabled | grep -E 'ssh|fail2ban|docker'

# Check for any errors in main system log
tail /var/log/syslog

Enable UFW and reboot in one command:

# FINAL STEP - This will enable UFW and immediately reboot
# Only run this when everything else is verified!
sudo sh -c "ufw --force enable && reboot"

⚠️ CRITICAL: After running the above command, your SSH connection will immediately drop. You will need to reconnect through ZeroTier after the system comes back online. Make sure ZeroTier is properly configured before enabling UFW!

💡 REMINDER: After reboot, immediately verify you can log back in through ZeroTier, preferably as the non-root user (koad). If something goes wrong, you should still have console access through your VPS provider's control panel.