Authelia: Gateway de Autenticación de Dos Factores
Authelia es un servidor de autenticación y autorización open source que actúa como gateway delante de tus aplicaciones, añadiendo autenticación de dos factores (TOTP, WebAuthn/FIDO2), SSO y control de acceso granular basado en reglas. A diferencia de oauth2-proxy, Authelia incluye su propia interfaz de login, gestión de usuarios y un sistema de reglas de acceso muy flexible que permite definir políticas diferentes para cada dominio o ruta. Esta guía cubre la instalación con Docker, la configuración de Nginx como proxy, TOTP y las reglas de control de acceso.
Requisitos Previos
- Servidor Linux con Docker y Docker Compose
- Nginx instalado como proxy inverso
- Dominio con SSL (HTTPS obligatorio)
- Certificados SSL válidos para el dominio y subdominios
- Acceso root o sudo
Arquitectura de funcionamiento
Usuario
│
▼
Nginx (Puerto 443)
│ auth_request
▼
Authelia (Puerto 9091) ──────── Redis (sesiones)
│ └─ LDAP/archivo (usuarios)
▼
Aplicación protegida (Puerto 3000, 8080, etc.)
Instalación con Docker Compose
# Crear la estructura de directorios
mkdir -p /opt/authelia/{config,data}
cd /opt/authelia
# /opt/authelia/docker-compose.yml
services:
authelia:
image: authelia/authelia:latest
container_name: authelia
restart: unless-stopped
volumes:
- ./config:/config
- ./data:/data
ports:
- "9091:9091"
environment:
TZ: Europe/Madrid
networks:
- authelia-net
redis:
image: redis:7-alpine
container_name: authelia-redis
restart: unless-stopped
volumes:
- redis-data:/data
networks:
- authelia-net
volumes:
redis-data:
networks:
authelia-net:
driver: bridge
docker compose up -d
Configuración de Authelia
Archivo de configuración principal
cat > /opt/authelia/config/configuration.yml << 'EOF'
---
# Servidor
server:
host: 0.0.0.0
port: 9091
path: ""
# Registro y auditoría
log:
level: info
format: text
# Dominio de SSO
default_redirection_url: https://auth.tudominio.com
# Tema de la interfaz de login
theme: light
# JWT para tokens de sesión (generar con: openssl rand -hex 32)
jwt_secret: "CAMBIA_ESTE_SECRETO_JWT_CON_OPENSSL_RAND"
# Autenticación de dos factores
totp:
issuer: tudominio.com
period: 30
skew: 1
# WebAuthn (FIDO2/biometría)
webauthn:
disable: false
display_name: "Mi Dominio"
attestation_conveyance_preference: indirect
user_verification: preferred
timeout: 60s
# Duración de la autenticación (tiempo hasta que caduca la sesión)
authentication_backend:
password_reset:
disable: false
refresh_interval: 5m
# Backend de usuarios: archivo local
file:
path: /config/users_database.yml
watch: false
search:
email: false
case_insensitive: false
password:
algorithm: argon2id
argon2id:
variant: argon2id
iterations: 3
memory: 65536
parallelism: 4
key_length: 32
salt_length: 16
# Control de acceso
access_control:
default_policy: deny
rules:
# Permitir acceso al endpoint de health sin autenticación
- domain: auth.tudominio.com
policy: bypass
# Apps que requieren solo usuario y contraseña (1FA)
- domain: blog.tudominio.com
policy: one_factor
# Apps críticas que requieren 2FA obligatorio
- domain: panel.tudominio.com
policy: two_factor
- domain: "*.tudominio.com"
policy: two_factor
# Sesiones
session:
name: authelia_session
secret: "CAMBIA_ESTE_SECRETO_SESSION"
expiration: 1h
inactivity: 30m
remember_me: 1M
cookies:
- domain: tudominio.com
authelia_url: https://auth.tudominio.com
# Redis para almacenamiento de sesiones (recomendado en producción)
storage:
encryption_key: "CAMBIA_ESTE_SECRETO_STORAGE_32CHARS_MIN"
local:
path: /data/db.sqlite3
# Notificaciones (para reset de contraseña y registro de dispositivos 2FA)
notifier:
# Para entornos de prueba, usar filesystem (escribe las notificaciones en un archivo)
filesystem:
filename: /data/notifications.txt
# Para producción, usar SMTP
# smtp:
# host: smtp.tudominio.com
# port: 587
# username: [email protected]
# password: "clave-smtp"
# sender: "Authelia <[email protected]>"
# tls:
# server_name: smtp.tudominio.com
EOF
Generar los secretos necesarios
# Generar el JWT secret
openssl rand -hex 32
# Generar el session secret
openssl rand -hex 32
# Generar el storage encryption key (mínimo 20 caracteres)
openssl rand -base64 32
# Actualizar los valores en configuration.yml con los generados
Integración con Nginx
Configuración del portal de autenticación
# /etc/nginx/sites-available/authelia-portal
server {
listen 443 ssl http2;
server_name auth.tudominio.com;
ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Snippet de Nginx para la verificación de autenticación
# Crear snippets de Nginx reutilizables
sudo mkdir -p /etc/nginx/snippets/
cat > /etc/nginx/snippets/authelia-authrequest.conf << 'EOF'
# Endpoint interno de Authelia para verificar la autenticación
location = /internal/authelia/authz {
internal;
proxy_pass http://127.0.0.1:9091/api/authz/auth-request;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
EOF
cat > /etc/nginx/snippets/authelia-location.conf << 'EOF'
# Verificar autenticación en cada solicitud
auth_request /internal/authelia/authz;
auth_request_set $target_url $scheme://$http_host$request_uri;
# En caso de no autenticado, redirigir al portal de Authelia
error_page 401 =302 https://auth.tudominio.com/?rd=$target_url;
# Pasar información del usuario autenticado a la aplicación
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $name $upstream_http_remote_name;
auth_request_set $emails $upstream_http_remote_email;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Name $name;
proxy_set_header Remote-Email $emails;
EOF
Proteger una aplicación con Authelia
# /etc/nginx/sites-available/panel-protegido
server {
listen 443 ssl http2;
server_name panel.tudominio.com;
ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;
# Incluir el snippet de verificación
include /etc/nginx/snippets/authelia-authrequest.conf;
location / {
# Verificar autenticación (2FA según las reglas de Authelia)
include /etc/nginx/snippets/authelia-location.conf;
# Proxy a la aplicación real
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
sudo ln -s /etc/nginx/sites-available/authelia-portal /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/panel-protegido /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Configuración de TOTP
TOTP (Time-based One-Time Password) es el método 2FA más común, compatible con Google Authenticator, Authy y cualquier app compatible con RFC 6238.
Registro del dispositivo TOTP
- Accede a la aplicación protegida
- Authelia te redirigirá al portal de login
- Introduce el usuario y contraseña
- El sistema te pedirá registrar un dispositivo 2FA
- Escanea el código QR con Google Authenticator, Authy o similar
- Verifica con el código de 6 dígitos generado
Configuración en Authelia
# En configuration.yml
totp:
issuer: "Mi Empresa" # Nombre que aparece en la app de autenticación
algorithm: sha1 # sha1, sha256, sha512
digits: 6 # 6 u 8 dígitos
period: 30 # Segundos de validez de cada código
skew: 1 # Códigos anteriores/posteriores aceptados (tolerancia de reloj)
secret_size: 32 # Tamaño del secreto compartido en bytes
Configuración de WebAuthn
WebAuthn permite autenticación con llaves de seguridad físicas (YubiKey) o biometría del dispositivo (Touch ID, Windows Hello).
# En configuration.yml
webauthn:
disable: false
display_name: "Mi Dominio"
attestation_conveyance_preference: indirect # none, indirect, direct, enterprise
user_verification: preferred # required, preferred, discouraged
timeout: 60s
Registro de un dispositivo WebAuthn
- Tras autenticarte con usuario/contraseña, selecciona "Registrar WebAuthn"
- El navegador solicitará la llave de seguridad o biometría
- Confirmar el registro siguiendo las instrucciones del dispositivo
Reglas de Control de Acceso
# Ejemplos de reglas avanzadas en configuration.yml
access_control:
default_policy: deny
networks:
- name: red-interna
networks:
- 192.168.1.0/24
- 10.0.0.0/8
rules:
# Acceso sin autenticación desde la red interna
- domain: panel.tudominio.com
networks:
- red-interna
policy: bypass
# Solo ciertos usuarios pueden acceder al panel de admin
- domain: admin.tudominio.com
subject:
- "group:admins"
policy: two_factor
# Rutas específicas con diferente política
- domain: app.tudominio.com
resources:
- "^/api/public.*$"
policy: bypass
- domain: app.tudominio.com
resources:
- "^/admin.*$"
subject:
- "group:admins"
policy: two_factor
- domain: app.tudominio.com
policy: one_factor
# Todo lo demás requiere 2FA
- domain: "*.tudominio.com"
policy: two_factor
Gestión de Usuarios
Archivo de usuarios (para instalaciones pequeñas)
# Generar el hash de la contraseña
docker run authelia/authelia:latest authelia crypto hash generate argon2 --password "contraseña-segura"
# Crear el archivo de usuarios
cat > /opt/authelia/config/users_database.yml << 'EOF'
---
users:
admin:
displayname: "Administrador"
password: "$argon2id$v=19$m=65536,t=3,p=4$SALT$HASH"
email: [email protected]
groups:
- admins
- users
jgarcia:
displayname: "Juan García"
password: "$argon2id$v=19$m=65536,t=3,p=4$SALT$HASH"
email: [email protected]
groups:
- users
EOF
Integración con LDAP (para organizaciones con directorio)
# En configuration.yml, reemplazar la sección authentication_backend
authentication_backend:
ldap:
implementation: custom
url: ldap://ldap.empresa.com:389
start_tls: true
base_dn: dc=empresa,dc=com
additional_users_dn: ou=usuarios
users_filter: (&({username_attribute}={input})(objectClass=inetOrgPerson))
username_attribute: uid
mail_attribute: mail
display_name_attribute: cn
additional_groups_dn: ou=grupos
groups_filter: (&(member=uid={input},ou=usuarios,dc=empresa,dc=com)(objectClass=groupOfNames))
group_name_attribute: cn
user: cn=readonly,dc=empresa,dc=com
password: clave-readonly-ldap
Solución de Problemas
Authelia muestra "Internal Server Error"
# Ver los logs detallados
docker compose logs authelia --tail 50
# Errores comunes:
# - Secretos demasiado cortos (jwt_secret, session secret necesitan 64+ hex chars)
# - Permisos en /data o /config
docker exec authelia ls -la /config/ /data/
La autenticación en Nginx devuelve 401 constantemente
# Verificar que el snippet está incluido correctamente
sudo nginx -t
# Comprobar que Authelia responde
curl -v http://localhost:9091/api/health
# Ver qué responde Authelia al endpoint de auth
curl -v http://localhost:9091/api/authz/auth-request
Los códigos TOTP no funcionan
# El problema más común es el reloj del servidor desincronizado
# Verificar y sincronizar el reloj
timedatectl status
sudo timedatectl set-ntp true
chronyc tracking # Si usas chrony
Emails de notificación no llegan
# Para pruebas, usar el notifier de filesystem y revisar el archivo
cat /opt/authelia/data/notifications.txt
Conclusión
Authelia proporciona una solución completa de autenticación de dos factores y control de acceso para toda la infraestructura web, sin depender de servicios externos y con pleno control sobre los datos de autenticación. La combinación de TOTP, WebAuthn y reglas de acceso granulares por dominio, ruta o grupo de usuarios hace de Authelia la opción más flexible para proteger paneles de administración, herramientas internas y cualquier aplicación expuesta a internet.


