Skip to content

Configurar un VPS desde cero ​

Un VPS recién creado es como una casa nueva sin cerraduras: funciona, pero cualquiera puede intentar entrar. En esta lección vas a crear un servidor Ubuntu y dejarlo seguro y listo para alojar sitios: usuario administrador, SSH con llaves, firewall, actualizaciones automáticas y más.

Concepto ​

El proceso estándar de "primeros 15 minutos" en cualquier VPS es:

  1. Crear el servidor con tu llave SSH.
  2. Actualizar el sistema.
  3. Crear un usuario con sudo (no trabajar como root).
  4. Endurecer SSH.
  5. Activar el firewall (ufw).
  6. Ajustes: zona horaria, swap, actualizaciones automáticas, fail2ban.
  7. Apuntar el dominio.

Lo harás una vez a mano para entenderlo y al final tendrás un script que lo automatiza.

Paso 1: crear el VPS ​

En el proveedor que elijas (DigitalOcean, Hetzner, Vultr, Linode, Contabo, Hostinger VPS):

  • Sistema: Ubuntu 24.04 LTS (soporte hasta 2029).
  • Plan: 1 vCPU / 1–2 GB RAM basta para empezar con varios sitios pequeños.
  • Región: la más cercana a los usuarios del cliente.
  • Autenticación: SSH key → pega tu llave pública (ver SSH y llaves).
  • Nombre: algo descriptivo, p. ej. web-clientes-01.

Anota la IP pública. Usaremos 203.0.113.10 como ejemplo.

Paso 2: primer acceso y actualización ​

bash
# Desde tu computadora
ssh root@203.0.113.10

# Ya en el servidor: actualizar todo
apt update && apt upgrade -y

# Si pide reiniciar (kernel nuevo)
reboot

Paso 3: crear tu usuario administrador ​

bash
# Crear el usuario (te pedirá contraseña: úsala para sudo)
adduser deploy

# Darle permisos de administrador
usermod -aG sudo deploy

# Copiar las llaves autorizadas de root al nuevo usuario
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

En otra terminal de tu computadora, comprueba:

bash
ssh deploy@203.0.113.10
sudo whoami   # debe responder: root

Paso 4: endurecer SSH ​

bash
sudo nano /etc/ssh/sshd_config
txt
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
bash
# Revisa si un archivo en sshd_config.d reactiva las contraseñas
grep -r "PasswordAuthentication" /etc/ssh/sshd_config.d/

sudo sshd -t && sudo systemctl restart ssh

Prueba antes de cerrar

Mantén abierta tu sesión actual y abre una nueva con ssh deploy@203.0.113.10. Si entra, todo bien. Si no, corrige desde la sesión que sigue abierta.

Paso 5: firewall con ufw ​

ufw (Uncomplicated Firewall) bloquea todo excepto los puertos que permitas.

bash
# Política por defecto: bloquear entradas, permitir salidas
sudo ufw default deny incoming
sudo ufw default allow outgoing

# ¡PRIMERO permite SSH o te quedarás fuera!
sudo ufw allow OpenSSH

# Web
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Activar
sudo ufw enable

# Ver reglas
sudo ufw status verbose

Más adelante, al instalar Nginx o Apache, puedes usar sus perfiles: sudo ufw allow 'Nginx Full' o sudo ufw allow 'Apache Full'.

Error común

Abrir el puerto de MySQL (3306) o PostgreSQL (5432) a todo internet "para conectarme desde mi casa". Nunca. Usa un túnel SSH:

bash
# En tu computadora: el puerto 3307 local apunta al 3306 del servidor
ssh -L 3307:127.0.0.1:3306 deploy@203.0.113.10
# Luego conecta tu cliente (DBeaver, TablePlus, Workbench) a 127.0.0.1:3307

Docker y ufw

Docker manipula iptables directamente y los puertos publicados con -p se saltan ufw. Lo verás en Docker: publica servicios internos solo en 127.0.0.1.

Paso 6: ajustes recomendados ​

Zona horaria y nombre del host ​

bash
sudo timedatectl set-timezone America/Mexico_City
timedatectl

sudo hostnamectl set-hostname web-clientes-01

Swap (memoria de respaldo) ​

En VPS con 1–2 GB de RAM, un archivo swap evita que procesos como npm install o composer maten al servidor por falta de memoria.

bash
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Hacerlo permanente
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Usar swap solo cuando haga falta
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

free -h

Actualizaciones de seguridad automáticas ​

bash
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades   # responde "Yes"

# Ver configuración
cat /etc/apt/apt.conf.d/20auto-upgrades

Debe contener:

txt
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Fail2ban ​

bash
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Herramientas útiles ​

bash
sudo apt install -y git curl wget unzip htop ncdu

Paso 7: apuntar el dominio ​

En el panel DNS:

txt
A      @     203.0.113.10
CNAME  www   tudominio.com.

Comprueba con dig +short tudominio.com. Ya puedes instalar Nginx o Apache.

Ejemplo: script de configuración inicial ​

Guárdalo como setup-vps.sh, súbelo y ejecútalo como root en un servidor nuevo. Revísalo y ajusta las variables antes de usarlo.

bash
#!/usr/bin/env bash
# setup-vps.sh — configuración inicial de Ubuntu 24.04
# Uso: bash setup-vps.sh
set -euo pipefail

NUEVO_USUARIO="deploy"
ZONA_HORARIA="America/Mexico_City"
SWAP_GB=2

echo "==> Actualizando sistema"
apt update && apt upgrade -y
apt install -y ufw fail2ban unattended-upgrades git curl wget unzip htop

echo "==> Creando usuario $NUEVO_USUARIO"
if ! id "$NUEVO_USUARIO" &>/dev/null; then
  adduser --disabled-password --gecos "" "$NUEVO_USUARIO"
  usermod -aG sudo "$NUEVO_USUARIO"
  # sudo sin contraseña (cómodo para automatizar; quítalo si prefieres pedirla)
  echo "$NUEVO_USUARIO ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-$NUEVO_USUARIO
  chmod 440 /etc/sudoers.d/90-$NUEVO_USUARIO
fi
rsync --archive --chown="$NUEVO_USUARIO:$NUEVO_USUARIO" /root/.ssh "/home/$NUEVO_USUARIO"

echo "==> Endureciendo SSH"
cat > /etc/ssh/sshd_config.d/99-seguro.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
EOF
# Desactivar archivos del proveedor que reactiven contraseñas
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config.d/*.conf || true
sshd -t && systemctl restart ssh

echo "==> Firewall"
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

echo "==> Zona horaria"
timedatectl set-timezone "$ZONA_HORARIA"

echo "==> Swap de ${SWAP_GB}G"
if [ ! -f /swapfile ]; then
  fallocate -l "${SWAP_GB}G" /swapfile
  chmod 600 /swapfile
  mkswap /swapfile
  swapon /swapfile
  echo '/swapfile none swap sw 0 0' >> /etc/fstab
  echo 'vm.swappiness=10' > /etc/sysctl.d/99-swappiness.conf
  sysctl --system >/dev/null
fi

echo "==> Actualizaciones automáticas y fail2ban"
cat > /etc/apt/apt.conf.d/20auto-upgrades <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF
systemctl enable --now fail2ban

echo "==> Listo. Prueba en otra terminal: ssh $NUEVO_USUARIO@$(curl -s https://ifconfig.me)"

Buena práctica

Guarda este script en un repositorio privado. Cada servidor nuevo quedará configurado igual en dos minutos. Herramientas como Ansible o cloud-init llevan esta idea al siguiente nivel.

Checklist del VPS ​

  • [ ] Ubuntu LTS actualizado
  • [ ] Usuario con sudo, sin trabajar como root
  • [ ] Acceso solo con llave SSH, root deshabilitado
  • [ ] ufw activo con solo 22, 80 y 443
  • [ ] Bases de datos sin puertos públicos
  • [ ] Zona horaria correcta
  • [ ] Swap configurado
  • [ ] unattended-upgrades y fail2ban activos
  • [ ] Snapshots o respaldos activados en el proveedor
  • [ ] Dominio apuntando a la IP

Ejercicios ​

  1. Escribe los comandos para permitir en ufw el puerto 2222 (SSH personalizado) y quitar la regla de OpenSSH.
  2. Tu servidor tiene 1 GB de RAM y npm run build se muere con "Killed". ¿Qué haces?
  3. ¿Por qué se recomienda un usuario normal con sudo en lugar de trabajar como root?
Ver solución
  1. Primero cambias Port 2222 en sshd_config y luego:
bash
sudo ufw allow 2222/tcp
sudo systemctl restart ssh
# prueba: ssh -p 2222 deploy@IP  — y solo entonces:
sudo ufw delete allow OpenSSH
  1. Es falta de memoria: crea un swap de 2 GB (sección Swap) o compila en tu computadora / en CI y sube solo el resultado.
  2. Porque un error con root no tiene red de seguridad, los bots atacan siempre al usuario root, y sudo deja registro de quién hizo qué.

Resumen ​

  • Crea el VPS con Ubuntu LTS y tu llave SSH.
  • Actualiza, crea un usuario sudo y desactiva root y contraseñas.
  • ufw: denegar todo, permitir OpenSSH, 80 y 443.
  • Añade swap, zona horaria, unattended-upgrades y fail2ban.
  • Automatiza todo con un script para repetirlo en cada servidor.
  • Siguiente: Apache.

Academia Web — aprende, copia y construye.