VPS 配置避坑 Configuration Pitfalls Guide
Pitfall #1: Changing SSH Port But Forgetting Firewall Rules
First thing on a new VPS: change the SSH port from 22 (too many bots scanning). I changed it to 2222, restarted sshd, happily disconnected — then discovered: I could never connect again.
# Execute on VPS via VNC/console in provider control panel
sudo ufw allow 2222/tcp
sudo systemctl restart sshd
**Root cause**: Ubuntu 24.04 has UFW enabled by default (sudo ufw enable), with default deny incoming. Changing the SSH port doesn't automatically update the firewall rules.
**Verification**: RackNerd $2.24/month KVM VPS, Ubuntu 24.04 LTS default UFW status is inactive, but some provider images default to active. Confirm with sudo ufw status verbose.
Prevention: Add firewall rule BEFORE changing the port:
# Before changing port
CURRENT_PORT=$(grep ^Port /etc/ssh/sshd_config | awk '{print $2}')
sudo ufw allow $CURRENT_PORT/tcp comment "SSH port"
---
Pitfall #2: UFW Default Rules Break Docker Networking
After fixing SSH, I installed Docker following the official docs:
sudo apt update && sudo apt install docker.io
sudo systemctl start docker
sudo docker run -d -p 8080:80 nginx:alpine
Accessing http://your-vps-ip:8080 locally — **connection refused**.
# Check container status
sudo docker ps
# CONTAINER ID IMAGE STATUS
# abc123 nginx:alpine Up 2 minutes
# Check port listening
sudo ss -tlnp | grep 8080
# No output = not listening
**Root cause**: UFW's deny incoming blocks Docker's port mapping. Docker daemon creates its own iptables rules on startup, but if UFW starts after Docker, UFW rules override Docker's.
Solutions:
# Method 1: Open Docker port via UFW (recommended)
sudo ufw allow 8080/tcp comment "Docker nginx"
# Method 2: Disable UFW (testing only!)
sudo ufw disable
Verification: Docker official docs (docs.docker.com/engine/install/ubuntu) explicitly document UFW compatibility issues, verified April 2026.
---
Pitfall #3: Swap Too Small Causes MySQL OOM Kill
Deploying WordPress, set up LEMP stack (Linux+Nginx+MySQL+PHP). Importing a 2GB SQL file, MySQL crashes:
sudo dmesg | grep -i kill
# [ 123.456] Out of Memory: Kill process 9876 (mysqld) score 892 or sacrifice child
Root cause: RackNerd $2.24/month plan has only 512MB RAM with no Swap. MySQL imports need temporary memory buffers — without Swap, it dies.
Solution: Add Swap file (2GB recommended for production):
# Create 2GB Swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Permanent: add to fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Verify
free -h
# total used free shared buff/cache available
# Mem: 512Mi 256Mi 87Mi 12Mi 169Mi 187Mi
# Swap: 2.0Gi 0B 2.0Gi
Verification: AWS EC2 t3.micro (1GB RAM) has no Swap by default. Tests show MySQL importing SQL files over 500MB triggers OOM.
---
Pitfall #4: SSH Key Permissions Too Wide Gets Rejected
After configuring everything, set up passwordless login. Changed private key permissions to 777 (for easier debugging):
chmod 777 ~/.ssh/id_rsa
SSH connect again: Permission denied (publickey).
ssh -v -i ~/.ssh/id_rsa root@your-vps-ip
# debug1: key_load_public: no such file or public key in memory
# debug1: identity file /root/.ssh/id_rsa type 0
# Permission denied (publickey).
Root cause: SSH requires private key file permissions ≤600 (strict mode requires ≤400). 777 means "everyone can read/write" — SSH refuses to use the key.
Correct approach:
chmod 400 ~/.ssh/id_rsa # Private key: owner read only
chmod 600 ~/.ssh/id_rsa # Private key: owner read/write (equivalent)
chmod 700 ~/.ssh/ # Directory: owner only
**Verification**: OpenSSH 9.0+ (Ubuntu 24.04 default) enables PubkeyAuthentication yes by default, enforcing private key permissions ≤600.
---
Pitfall #5: Timezone Not Set Causes Certbot Renewal Failure
Certificate about to expire, manually renew:
sudo certbot renew --dry-run
# Challenge failed for example.com
# Error: invalid: {"type":"http-01","error":"unauthorized"}
After a day of debugging, discovered Let's Encrypt HTTP-01 challenge depends on accurate time — if your server time differs from CA time by hours, the CA rejects directly.
Root cause: Timezone error causes system time deviation. TLS handshake certificate verification and CRL checks both depend on correct time.
Diagnosis and fix:
# Diagnose
date # Current system time
timedatectl # Timezone and time status
# Example output: UTC 2026 Mon May 11 14:30:00 (should be Asia/Shanghai 22:30)
# Fix to CST
sudo timedatectl set-timezone Asia/Shanghai
# Verify
date
# Mon May 11 22:30:00 CST 2026
# Retry certificate
sudo certbot certonly --webroot -w /var/www/html -d example.com
**Verification**: Let's Encrypt CA server time is UTC-based, requiring request time error within ±24 hours. Certbot v5.5.0 (verified April 2026) outputs Authorization invalid instead of clear time error messages when timezone is wrong.
---
Complete Configuration Checklist (Avoid Repeat Mistakes)
Run in order after each new VPS deployment:
# 1. Timezone + time
sudo timedatectl set-timezone Asia/Shanghai
sudo apt install ntpdate && sudo ntpdate cn.pool.ntp.org
# 2. Swap (required for 512MB RAM plans)
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 3. SSH port (add rule BEFORE changing)
sudo ufw allow 22/tcp comment 'SSH temp'
# Edit /etc/ssh/sshd_config Port 2222
sudo ufw delete allow 22/tcp
sudo ufw allow 2222/tcp comment 'SSH'
sudo systemctl restart sshd
# 4. UFW rules (after changing SSH port)
sudo ufw default deny incoming
sudo ufw allow 2222/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
# 5. Docker (if needed)
sudo apt install docker.io
sudo usermod -aG docker $USER # Add current user to docker group
sudo systemctl enable docker
sudo ufw allow 8080/tcp comment 'Docker app' # Open your app port
---
Summary
These 5 pitfalls cover network, firewall, resources, permissions, and time — each cost me hours of debugging. Core lesson: VPS configuration is a chain reaction; any single failure cascades.
Related Articles:
- 2026 Complete Guide to VPS Development Environment Setup: 10-Step Process
- Ubuntu 24.04 + Docker + UFW Firewall: The 3-Day Nightmare
**WordPress Plugin Development Book** — Learn to build WordPress plugins from scratch
👉 Try MiniMax API now: https://platform.minimaxi.com/subscribe/token-plan?code=E5yur9NOub&source=link
🔗 Related Tech Articles
Deep dive into related technical topics: