VPS Setup¶
Overview¶
Baseline hardening procedure for a fresh VPS prior to installing cluster tooling (k3s, Helm, ArgoCD). Establishes a non-root administrative user with SSH key authentication and a restrictive firewall policy.
Scope¶
- Provider: Greencloud
- OS: Ubuntu 22.04/24.04
- Spec: 8GB RAM / 4vCPU / 88GB SSD
- Result:
novauser with sudo privileges, SSH key-based login, UFW firewall active
Prerequisites¶
- Root SSH access to the VPS
- Local SSH keypair (public key present in
/root/.ssh/authorized_keyson the VPS)
Procedure¶
1. System update¶
apt update && apt upgrade -y
2. Create administrative user¶
adduser nova
usermod -aG sudo nova
passwd nova
The password is a fallback credential only; SSH key authentication is the primary access method (Step 3).
3. Provision SSH key access¶
Cloud images do not propagate the root user's authorized_keys to newly created users. Copy explicitly:
mkdir -p /home/nova/.ssh
cp /root/.ssh/authorized_keys /home/nova/.ssh/authorized_keys
chown -R nova:nova /home/nova/.ssh
chmod 700 /home/nova/.ssh
chmod 600 /home/nova/.ssh/authorized_keys
4. Firewall configuration (UFW)¶
apt install ufw -y
ufw allow OpenSSH
ufw allow 80/tcp # HTTP ingress
ufw allow 443/tcp # HTTPS ingress
ufw allow from <ADMIN_PUBLIC_IP> to any port 6443 proto tcp
ufw enable
Only the ports required for SSH and HTTP(S) ingress are public. The k3s API is restricted to the operator's public IP; omit this rule when kubectl runs only on the VPS.
Verification¶
From a local machine (not a su nova session on the VPS — this does not exercise the SSH auth path):
ssh nova@<VPS_IP>
sudo whoami
# expected: root
sudo ufw status
# expected: 22, 80, 443, 6443 in ALLOW state
Known Issue: Permission denied (publickey)¶
Symptom: SSH rejects both key and password auth for the new user, even after setting PasswordAuthentication yes in /etc/ssh/sshd_config.
Cause: OpenSSH applies the first matching directive it encounters. sshd_config typically contains Include /etc/ssh/sshd_config.d/*.conf near the top of the file. If a drop-in file in that directory sets PasswordAuthentication no, it takes precedence over any conflicting directive appearing later in the main config file. Cloud-init frequently generates such drop-in files.
Diagnosis:
sudo sshd -T | grep -i passwordauthentication # effective value, not raw file content
grep -n "^Include" /etc/ssh/sshd_config
grep -rn "PasswordAuthentication" /etc/ssh/sshd_config.d/
Resolution: Provisioning SSH key access (Step 3) resolves this without modifying sshd_config. Editing the drop-in file directly is an alternative but is not recommended, as password authentication is a weaker access control than key-based authentication.