servidor
sidebar_position: 3 title: Documentación del 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
| Puerto | Servicio | Justificación |
|---|---|---|
| 22 | SSH | Acceso administrativo remoto. Solo autenticación por llave pública — login por contraseña deshabilitado, acceso root remoto deshabilitado. |
| 80 | HTTP | Redirección obligatoria a HTTPS (Let's Encrypt / Certbot). |
| 443 | HTTPS | Tráfico cifrado de la Landing, Docs y APIs vía proxy inverso (Nginx). |
| 3306 | MySQL | Expuesto 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:
| Jail | Protege contra |
|---|---|
sshd | Fuerza bruta por SSH |
nginx-http-auth | Fuerza bruta contra auth básica de nginx |
nginx-limit-req | IPs que exceden el límite de peticiones repetidamente |
nginx-botsearch | Escaneo de rutas típicas de bots/exploits |
mysqld-auth | Fuerza 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
| Servicio | Versión | Gestión |
|---|---|---|
| Docker | — | systemd |
| SQL Server | 2022 (contenedor) | Docker, --restart unless-stopped |
| MySQL | 8.0 (contenedor) | Docker, --restart unless-stopped |
| Backend .NET | .NET 10 / ASP.NET Core | systemd (backendcore.service) |
| nginx | — | systemd |
| fail2ban | — | systemd |
Dominios asociados
| Subdominio | Propósito |
|---|---|
anti-corruption-layer.andrescortes.dev | Landing / frontend |
api.anti-corruption-layer.andrescortes.dev | Backend API |
docs.anti-corruption-layer.andrescortes.dev | Documentación (Docusaurus) |
Variables de entorno (solo nombres, sin valores)
Ubicadas en /etc/backendcore.env (permisos 600, fuera de Git):
ConnectionStrings__SqlServerConnectionStrings__MySqlJwt__KeyJwt__IssuerJwt__AudienceGitHub__ClientIdGitHub__ClientSecretGoogle__ClientIdGoogle__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).