// OPERACIÓN: El Bunker de Seguridad
// Despliegue seguro: Blogger + Servidor de documentación en Hetzner + Cloudflare + Tailscale
*DISCLAMER* -> Por seguridad y cuidado en revelación de secretos se hace omisión de capturas de logs o detalles técnicos que puedan comprometer la seguridad de la información.
0x00 - Generación de Identidad Criptográfica (Local)
No usamos contraseñas.
Usamos llaves asimétricas.
Generamos un par de claves Ed25519, el algoritmo de curva elíptica más eficiente y seguro disponible actualmente para autenticación SSH:
$ ssh-keygen -t ed25519 -C "operador@ejemplo.com"
- -t ed25519 — Algoritmo de firma digital basado en Curve25519. Claves mas cortas, verificación más rápida y resistencia superior frente a ataques de canal lateral comparado con RSA.
- -C — Comentario identificador embebido en la clave pública. Útil para auditar ~/.ssh/authorized_keys en servidores con multiples operadores.
Resultado: Se generan dos archivos: la clave privada (permanece exclusivamente en la máquina local, nunca se transfiere) y la clave pública (.pub) que se deposita en el servidor remoto.
0x01 - Configuración del Servidor (Hetzner)
Instancia aprovisionada con Ubuntu 24.04 LTS.
Primer paso tras el despliegue: actualizar el sistema e instalar el stack web.
A. Actualización del sistema y Web Stack
$ sudo apt update && sudo apt upgrade -y
$ sudo apt install nginx php8.3-fpm php-common php-mysql -y
Esto despliega Nginx como reverse proxy / servidor web y PHP 8.3-FPM (FastCGI Process Manager) para el procesamiento de contenido dinamico.
B. Hardening SSH - Cambio de Puerto y Desactivación de Passwords
Editamos la configuración del daemon SSH:
$ sudo nano /etc/ssh/sshd_config
Modificaciones aplicadas:
- Port 4222 — Reubicamos el servicio SSH fuera del puerto estandar 22. (Esto no es seguridad real, pero elimina el ruido de bots automatizados que escanean puertos por defecto).
- PasswordAuthentication no — Se deshabilita la autenticación por contraseña. Solo se aceptan claves criptográficas.
$ sudo systemctl enable ssh # Persistencia tras reboot
$ sudo systemctl restart ssh # Aplicar cambios
0x02 - Cortafuegos Estratégico (UFW)
Definimos las reglas de acceso a nivel de red.
Política base: denegar todo el tráfico entrante y permitir solo lo estrictamente necesario.
$ sudo ufw default deny incoming # DROP en todo el tráfico entrante
$ sudo ufw default allow outgoing # Permite tráfico de salida
# Puertos públicos (Cloudflare -> Servidor)
$ sudo ufw allow 80/tcp # HTTP
$ sudo ufw allow 443/tcp # HTTPS
# SSH restringido exclusivamente a la interfaz Tailscale
$ sudo ufw allow in on tailscale0 to any port 4222 proto tcp
$ sudo ufw enable
La regla clave es la última antes del enable: el acceso SSH por el puerto 4222 solo se permite a través de la interfaz tailscale0.
Esto significa que el puerto SSH es completamente invisible desde internet público.
Solo los dispositivos autorizados dentro de la red Tailscale pueden alcanzarlo.
0x03 - DNS (Cloudflare)
Configuración DNS para el dominio ejemplo.com.
Se divide el tráfico entre el blog (Blogger) y el servidor de documentación (Hetzner).
| Registro | Nombre | Valor | Proxy | Funcion |
|---|---|---|---|---|
| A | @ | IPs de Google (Blogger) | Proxied | Raiz del blog |
| CNAME | www | ghs.google.com | DNS Only | Alias www del blog |
| A | doc | 192.168.1.100 | Proxied | Servidor Hetzner (documentacion) |
SSL/TLS en Cloudflare: Configurado en modo Full (Strict).
Esto exige un certificado válido en el servidor de origen, garantizando cifrado extremo a extremo entre el cliente, Cloudflare y el servidor Hetzner.
0x04 - Blindaje del Servidor Web (Nginx + SSL de Origen)
Instalamos certificados de origen emitidos por Cloudflare para cifrar el tramo Cloudflare <-> Servidor Hetzner.
Sin esto, el tráfico entre ambos puntos viajaría en texto plano.
A. Ubicación de Certificados
- Certificado: /etc/ssl/certs/cloudflare.crt
- Clave privada: /etc/ssl/private/cloudflare.key
# Permisos restrictivos sobre la clave privada
$ sudo chmod 600 /etc/ssl/private/cloudflare.key
$ sudo chown root:root /etc/ssl/private/cloudflare.key
B. Virtual Host - /etc/nginx/sites-available/portfolio
server {
listen 443 ssl;
server_name doc.ejemplo.com;
ssl_certificate /etc/ssl/certs/cloudflare.crt;
ssl_certificate_key /etc/ssl/private/cloudflare.key;
# Protocolos y cifrados recomendados
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.php;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
# Denegar acceso a archivos ocultos
location ~ /\. {
deny all;
}
}
Activar el sitio y verificar la configuración:
$ sudo ln -s /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled/
$ sudo nginx -t # Validar sintaxis
$ sudo systemctl reload nginx
0x05 - Capa Tailscale
Tailscale crea una red mesh privada basada en WireGuard.
Cada dispositivo autorizado recibe una IP interna del rango 100.x.x.x (CGNAT).
El servidor se vuelve invisible a internet público para administración.
# Instalación
$ curl -fsSL https://tailscale.com/install.sh | sh
# Activación y vinculación con la cuenta
$ sudo tailscale up
Tras la activación, el servidor obtiene una IP privada dentro de la red Tailscale (ejemplo: 100.x.x.x).
Esta IP es la única vía de acceso SSH al servidor, ya que el firewall UFW bloquea el puerto 4222 en todas las interfaces excepto tailscale0.
Flujo de conexion SSH:
$ ssh -p 4222 operador@100.x.x.x
Donde 100.x.x.x es la IP asignada por Tailscale al servidor.
Esta IP solo es alcanzable desde dispositivos autenticados en la misma red Tailscale.
0x06 - Bloqueo de Archivos
Si un atacante obtuviera acceso al servidor, no podria modificar los archivos críticos del sitio.
# Activar flag de inmutabilidad
$ sudo chattr +i /var/www/html/index.php
# Verificar el flag
$ lsattr /var/www/html/index.php
# Salida esperada: ----i--------e-- /var/www/html/index.php
# Desactivar (solo cuando se necesite editar)
$ sudo chattr -i /var/www/html/index.php
El atributo +i (immutable) del sistema de archivos ext4 impide cualquier operación de escritura, renombrado o eliminación sobre el archivo, incluso por el usuario root.
El flag debe ser removido explícitamente con chattr -i antes de poder realizar modificaciones.
0x07 - Comandos de Rescate Rápido
Referencia de diagnostico y recuperación ante fallos comunes:
| Problema | Comando / Accion | Descripción |
|---|---|---|
| Web no carga | sudo nginx -t | Valida la sintaxis de la configuracion de Nginx. Si hay errores, los muestra con el numero de linea exacto. |
| SSH no conecta | Consola web de Hetzner | Acceder vía consola del proveedor y ejecutar sudo systemctl restart ssh. Verificar que el puerto 4222 sigue configurado en sshd_config. |
| IP pública cambio | ssh -p 4222 operador@100.x.x.x | La IP de Tailscale es persistente e independiente de la IP pública. Conectar siempre a través de la red Tailscale. |
| Certificado SSL expirado | Panel Cloudflare > SSL > Origin Certificates | Regenerar el certificado de origen y reemplazar los archivos en el servidor. Recargar Nginx. |
| PHP no procesa | sudo systemctl status php8.3-fpm | Verificar que el servicio FPM esta activo. Reiniciar con sudo systemctl restart php8.3-fpm si es necesario. |
[EOF] - “The Security Bunker”