Appearance
LXC: Ory IAM (Planeado)
En Planificación
Este contenedor aún no está implementado. La documentación describe la arquitectura planificada basada en las mejores prácticas para la integración de IAM.
Especificación del Contenedor (Planeada)
Tipo: LXC (no privilegiado con soporte Docker)
SO: Debian 13 (trixie)
Hostname: ory-iam
Estado: planeado
Recursos:
RAM: 2 GB
Disco: 10 GB
CPU Shares: 1024Resumen de Arquitectura
graph LR
subgraph "LXC: Ory IAM"
Kratos[Ory Kratos<br/>Gestión de Identidad]
Hydra[Ory Hydra<br/>Proveedor OAuth2/OIDC]
end
subgraph "Reverse Proxy (OPNSense)"
CaddyAuth[auth.domain.eu<br/>→ UI Kratos]
CaddyAPI[api.auth.domain.eu<br/>→ API Kratos]
CaddyOAuth[oauth.domain.eu<br/>→ Hydra]
end
subgraph "Contenedor PostgreSQL"
DBKratos[(BD Kratos)]
DBHydra[(BD Hydra)]
end
subgraph "Contenedor Frontend"
Astro[Apps AstroJS<br/>Auth basada en Sesión]
end
CaddyAuth --> Kratos
CaddyAPI --> Kratos
CaddyOAuth --> Hydra
Kratos -->|SQL| DBKratos
Hydra -->|SQL| DBHydra
Kratos -.->|Flujo de Login| Hydra
Astro -->|Cookies Sesión| CaddyAuth
Astro -->|Tokens OAuth2| CaddyOAuthComponentes
Ory Kratos (Gestión de Identidad)
Función: Registro de usuario, login, reseteo de contraseña
Base de Datos: Base de datos PostgreSQL dedicada
Métodos de Auth:
- Email/Contraseña
- Login Social (vía Hydra)
- Autenticación Multi-Factor (TOTP)
- WebAuthn/Passkeys
Características:
- Flujos de Auto-Servicio (sin intervención admin para registro)
- Recuperación de Cuenta vía Email
- Verificación de Email
- Gestión de Sesión (basada en Cookies)Ory Hydra (OAuth2/OIDC)
Función: Proveedor OAuth2 para Apps de Terceros
Base de Datos: Base de datos PostgreSQL separada
Protocolos:
- OAuth2 (Flujo de Código de Autorización)
- OpenID Connect (OIDC)
- Introspección/Revocación de Tokens
Casos de Uso:
- Single Sign-On (SSO) para subdominios p2d2
- Acceso API para clientes externos
- Integración app móvilInstalación (Enfoque Docker Compose)
Prerrequisitos
# Crear contenedor LXC (en host Proxmox)
pct create <VMID> <DEBIAN13_TEMPLATE> \
--hostname ory-iam \
--cores 2 \
--memory 2048 \
--rootfs <STORAGE>:10 \
--net0 name=eth0,bridge=vmbr1 \
--unprivileged 1 \
--features nesting=1 # Para soporte Docker
# Iniciar contenedor e instalar Docker
pct start <VMID>
pct enter <VMID>
apt update && apt install -y docker.io docker-composeEstructura Docker Compose
# /opt/ory/docker-compose.yml (simplificado)
version: '3.8'
services:
kratos:
image: oryd/kratos:latest
environment:
- DSN=postgres://<USER>:<PASS>@<DB_HOST>:<PORT>/ory_kratos?sslmode=disable
- SERVE_PUBLIC_BASE_URL=https://api.auth.domain.eu
- SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=https://www.domain.eu
volumes:
- ./kratos-config:/etc/config/kratos
command: serve --config /etc/config/kratos/kratos.yml
hydra:
image: oryd/hydra:latest
environment:
- DSN=postgres://<USER>:<PASS>@<DB_HOST>:<PORT>/ory_hydra?sslmode=disable
- URLS_SELF_ISSUER=https://oauth.domain.eu
- URLS_LOGIN=https://auth.domain.eu/login
- URLS_CONSENT=https://auth.domain.eu/consent
command: serve allGestión de Secretos
¡NUNCA almacene secretos directamente en docker-compose.yml! Use:
- Archivos
.env(no commitear a Git) - Docker Secrets
- Gestores de Secretos Externos (Vault, SOPS) :::
Configuración Caddy (OPNSense)
# Config Personalizada: /usr/local/etc/caddy/caddy.d/ory-iam.conf
# UI Login/Registro
auth.domain.eu {
reverse_proxy <ORY_IAM_CONTAINER>:<KRATOS_UI_PORT>
}
# API Pública Kratos
api.auth.domain.eu {
reverse_proxy <ORY_IAM_CONTAINER>:<KRATOS_API_PORT>
}
# Endpoints Hydra OAuth2
oauth.domain.eu {
reverse_proxy <ORY_IAM_CONTAINER>:<HYDRA_PORT>
}
# API Admin (solo interna)
admin.auth.domain.eu {
@internal {
remote_ip <INTERNAL_NETWORK_RANGE>
}
handle @internal {
reverse_proxy <ORY_IAM_CONTAINER>:<ADMIN_PORT>
}
respond 403
}Integración con Frontend p2d2
Login Basado en Sesión (Kratos)
// src/lib/auth.ts (AstroJS)
export async function checkSession(request: Request): Promise<User | null> {
const kratosPublicUrl = process.env.KRATOS_PUBLIC_URL;
const cookie = request.headers.get('cookie');
const response = await fetch(`${kratosPublicUrl}/sessions/whoami`, {
headers: { cookie }
});
if (response.ok) {
const session = await response.json();
return session.identity;
}
return null;
}
// Middleware para rutas protegidas
export async function onRequest({ request, redirect }, next) {
const user = await checkSession(request);
if (!user) {
return redirect('/login');
}
return next();
}Flujo OAuth2 (Hydra)
// Registrar Cliente OAuth2 (una sola vez, vía API Admin)
const client = {
client_id: "p2d2-frontend",
client_secret: "<GENERATED_SECRET>",
redirect_uris: ["https://www.domain.eu/auth/callback"],
grant_types: ["authorization_code", "refresh_token"],
response_types: ["code"],
scope: "openid profile email"
};
// Solicitud de Autorización (cara al usuario)
const authUrl = `https://oauth.domain.eu/oauth2/auth` +
`?client_id=${client_id}` +
`&response_type=code` +
`&scope=openid%20profile%20email` +
`&redirect_uri=${encodeURIComponent(redirect_uri)}` +
`&state=${generateState()}`;
// Intercambio de Token (backend)
const tokenResponse = await fetch('https://oauth.domain.eu/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authCode,
redirect_uri: redirect_uri,
client_id: client_id,
client_secret: client_secret
})
});Configuración Base de Datos (Contenedor PostgreSQL)
-- Base de Datos Ory-Kratos
CREATE DATABASE ory_kratos;
CREATE USER ory_kratos WITH PASSWORD '<STRONG_RANDOM_PASSWORD>';
GRANT ALL PRIVILEGES ON DATABASE ory_kratos TO ory_kratos;
-- Base de Datos Ory-Hydra
CREATE DATABASE ory_hydra;
CREATE USER ory_hydra WITH PASSWORD '<ANOTHER_STRONG_PASSWORD>';
GRANT ALL PRIVILEGES ON DATABASE ory_hydra TO ory_hydra;
-- Las migraciones de esquema son realizadas automáticamente por Kratos/HydraMonitorización & Comprobaciones de Salud
# Comprobar endpoints de salud
curl https://api.auth.domain.eu/health/ready
curl https://oauth.domain.eu/health/ready
# Ver logs de Docker
docker-compose -f /opt/ory/docker-compose.yml logs -f
# Estado contenedor
docker ps | grep oryLista de Verificación de Seguridad
Antes de despliegue a producción:
- [ ] Reemplazar
SECRETS_SYSTEMen Hydra con secreto fuerte (min. 32 caracteres) - [ ] Mover contraseñas PostgreSQL a archivo
.env(no en docker-compose.yml) - [ ] Verificar certificados Caddy TLS para todos los dominios auth
- [ ] Hacer API Admin accesible solo vía VPN/VLAN de Gestión
- [ ] Habilitar Limitación de Tasa para endpoints de login (protección Brute-Force)
- [ ] Configurar cabeceras CORS correctamente (solo dominios propios)
- [ ] Configurar y probar servidor SMTP para envío de emails
- [ ] Configurar tarea de backup para bases de datos Ory
Hoja de Ruta de Implementación
Fase 1 (Semana 1-2): Configuración Básica
- Crear contenedor LXC e instalar Docker
- Crear bases de datos PostgreSQL
- Configuración Docker Compose Kratos
- Probar UI Login/Registro
Fase 2 (Semana 3-4): Integración Hydra
- Configurar Contenedor Hydra
- Registrar clientes OAuth2 para frontend p2d2
- Probar flujos de token
Fase 3 (Semana 5-6): Integración Frontend
- Implementar Middleware de Sesión AstroJS
- Integrar flujos de login en UI p2d2
- Pruebas E2E (Registro → Login → Solicitud Autorizada)
Fase 4 (Semana 7): Endurecimiento Producción
- Integración SMTP (Envío de email)
- Configurar Limitación de Tasa
- Configurar Monitorización
- Finalizar Documentación
Referencias
- Documentación Ory Kratos
- Documentación Ory Hydra
- Buenas Prácticas OAuth2 (RFC 8252)
- Hoja de Trucos Autenticación OWASP
Nota: Este texto fue traducido automáticamente con IA y aún no ha sido revisado por un humano.