Saltar al contenido principal

servidor


Documentación del Servidor

Información general

  • Proveedor: Hetzner
  • Sistema operativo: Ubuntu 26.04 LTS
  • Hostname: anti-corruption-layer
  • Ambiente: Producción

Puertos abiertos

PuertoServicioJustificación
22SSHAcceso administrativo remoto. Solo autenticación por llave pública — login por contraseña deshabilitado, acceso root remoto deshabilitado.
80HTTPRedirección obligatoria a HTTPS (Let's Encrypt / Certbot).
443HTTPSTráfico cifrado de la Landing, Docs y APIs vía proxy inverso (Nginx).
3306MySQLExpuesto intencionalmente: los estudiantes necesitan conectarse directo a su base de datos desde sus propias herramientas (MySQL Workbench, DBeaver, su propio código). Mitigado con: usuario/contraseña por base, límite de conexiones concurrentes (MAX_USER_CONNECTIONS 5), y fail2ban con jail dedicado contra fuerza bruta.

Todos los demás puertos están cerrados por firewall (UFW). SQL Server (1433) corre solo en 127.0.0.1, nunca expuesto — es la base de control interna, sin motivo para ser pública.

Firewall (UFW)

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Protección contra fuerza bruta (fail2ban)

5 jails activos:

JailProtege contra
sshdFuerza bruta por SSH
nginx-http-authFuerza bruta contra auth básica de nginx
nginx-limit-reqIPs que exceden el límite de peticiones repetidamente
nginx-botsearchEscaneo de rutas típicas de bots/exploits
mysqld-authFuerza bruta contra MySQL

Mitigación de DoS (Nginx)

Configurado en nginx.conf (zonas globales) y aplicado en cada server {}:

limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

client_body_timeout 10s;
client_header_timeout 10s;
send_timeout 10s;

Cada sitio (backend, frontend, docs) aplica:

limit_conn addr 10;
limit_req zone=req_limit burst=20 nodelay;

También se bloquean explícitamente user-agents típicos de escaneo (curl, nmap, sqlmap, nikto, etc.) fuera de pruebas manuales autorizadas.

Servicios instalados

ServicioVersiónGestión
Dockersystemd
SQL Server2022 (contenedor)Docker, --restart unless-stopped
MySQL8.0 (contenedor)Docker, --restart unless-stopped
Backend .NET.NET 10 / ASP.NET Coresystemd (backendcore.service)
nginxsystemd
fail2bansystemd

Dominios asociados

SubdominioPropósito
anti-corruption-layer.andrescortes.devLanding / frontend
api.anti-corruption-layer.andrescortes.devBackend API
docs.anti-corruption-layer.andrescortes.devDocumentación (Docusaurus)

Variables de entorno (solo nombres, sin valores)

Ubicadas en /etc/backendcore.env (permisos 600, fuera de Git):

  • ConnectionStrings__SqlServer
  • ConnectionStrings__MySql
  • Jwt__Key
  • Jwt__Issuer
  • Jwt__Audience
  • GitHub__ClientId
  • GitHub__ClientSecret
  • Google__ClientId
  • Google__ClientSecret

Ciclo de vida (TTL) de bases de datos

Ejecutado vía cron diario (3:00 AM):

0 3 * * * /home/corruption/run_ttl_check.sh # SQL Server
0 3 * * * /home/corruption/run_mysql_ttl_check.sh # MySQL

Las bases sin actividad por más de 7 días quedan desactivadas (SQL Server: OFFLINE; MySQL: se revoca el acceso del usuario, sin borrar los datos).