Acceso seguro con doble factor con Authelia y NGINX Proxy Manager
En este post vamos a seguir yendo un poco más allá en la seguridad de nuestro NAS y de los servicios que montamos en él.
Para ello vamos a montar y configurar login de usuario con usuario, contraseña y verificación de doble factor para aquellos contenedores que, por defecto, no tienen esta forma de hacer login en su configuración de forma nativa.
¿Qué tenemos que tener?
- Un dispositivo que ejecute docker, en nuestro caso el NAS, pero podemos hacerlo en un ordenador, una raspberry pi o cualquier otro dispositivo donde podamos montar docker.
- Portainer instalado, ya que lo haremos a través de portainer, aunque podemos hacerlo a través de Linux y docker-compose y para ello pondré los archivos por aquí.
- Dominio propio
- NGINX Proxy Manager como gestor de nuestros proxys inversos.
Paso 1
- Vamos a Portainer, y nos vamos a stack
- Le damos al stack el nombre de authelia y pegamos el código del docker-compose que está en este archivo
- Antes de darle al botón DEPLOY STACK, tendrémos que ir a FILE STATION y crear las carpetas que pongamos en la ruta desde la que el contenedor cogerá la información.
- Ahora cuando pulsamos sobre DEPLOY STACK, nos pasará algo que no es lo habitual y es que el contenedor no se inicia, sino que se para. Si entramos al log del contenedor, veremos que nos dice que el archivo configuration.yml no está, o no está correctamente configurado.
- Entramos en la carpeta config y borramos el archivo configuration.yml que existe.
- Nos bajamos este archivo y lo colocamos dentro de la misa carpeta donde hemos borrado el anterior.
- Tendremos que hacer los cambios que os comento en el mismo archivo
# yamllint disable rule:comments-indentation
---
###############################################################################
# Authelia Configuration #
###############################################################################
theme: dark #light/dark Elige el tema que más te guste
jwt_secret: 1234567890abcdefghifjkl #Visita https://www.grc.com/passwords.htm y copia el numero largo de la ventana que se llama 64 random hexadecimal characters (0-9 and A-F):
default_redirection_url: https://google.com/ #Aqui hará una redireccion si no existe ningun dominio en nuestro archivo
server:
host: 0.0.0.0 #No tocar, hay que dejarlo así
port: 9091 #Este es el puerto por defecto, no cambiarlo
path: ""
buffers:
read: 4096
write: 4096
enable_pprof: false
enable_expvars: false
disable_healthcheck: false
tls:
key: ""
certificate: ""
log:
level: debug
totp:
issuer: yourdomain.com #tu nombre de dominio. No es el subdominio, sino que es el fulanito.es
period: 30
skew: 1
authentication_backend:
password_reset:
disable: false
refresh_interval: 5m
file:
path: /config/users_database.yml #Este es el archivo que hemos creado con los usuarios, se configura en el archivo user_database.yml que tenéis en la carpeta
password:
algorithm: argon2id
iterations: 1
key_length: 32
salt_length: 16
memory: 1024
parallelism: 8
access_control:
default_policy: two_factor #yo elijo doble factor por defecto
rules:
## bypass rule
- domain:
- "auth.yourdomain.com" #Debe ser tu subdominio creado para authelia
policy: bypass
- domain:
- "sub1.yourdomain.com" #Debes poner el dominio de uno de los proxys inversos si quieres que tenga solo una validación sencilla tipo usuario/contraseña
policy: one_factor
- domain:
- "sub2.yourdomain.com" #Debes poner el dominio de uno de los proxys inversos si quieres que tenga solo una validación de doble factor tipo usuario/contraseña y codigo cambiante cada 30 segundos
policy: two_factor
#Cada vez que modifiquemos un dominio, hay que parar y arrancar el contenedor de authelia para que ejecute los cambios.
session:
name: authelia_session
secret: unsecure_session_secret #Visita https://www.grc.com/passwords.htm y copia el numero largo de la ventana que se llama 64 random hexadecimal characters (0-9 and A-F):
expiration: 3600 # 1 hour
inactivity: 300 # 5 minutes
domain: yourdomain.com # tu nombre de dominio. No es el subdominio, sino que es el fulanito.es
regulation:
max_retries: 3
find_time: 10m
ban_time: 12h
#Numero de intentos en un tiempo antes de ser baneado durante la duración que pongamos. En este caso si introduce 3 intentos erróneos en 10 minutos, será baneado 12 horas.
storage:
local:
path: /config/db.sqlite3 #Base de datos que se crea con los usuarios, no es necesario complicarse la vida para usar Authelia de forma particular
encryption_key: you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this #borrar el texto y sustituirlo por una cadena de 20 caracteres alternados con letras y números.
notifier:
disable_startup_check: true #true/false
smtp:
username: [email protected] #tu usuario de correo
password: Y0uRp@55W0rD! #Creamos una contraseña de aplicacion en goggle, la copiamos y la pegamos aquí
host: smtp.gmail.com #email smtp server, este es correcto si usas gmail
port: 587 #email smtp port, es este el que se utiliza si usas gmail
sender: [email protected] #el correo de quien lo envia, poen el mismo que tu usuario
identifier: localhost
subject: "[Authelia] {title}" #email subject
Ojo que la contraseña en el mail, no es la contraseña de acceso al mail sino una contraseña de aplicación creada específicamente para esto.
Paso 2
Una vez que hayamos configurado correctamente el archivo CONFIGURATION.YML y antes de volver a poner en marcha ell contenedor de nuevo, hay que configurar el archivo USER_DATABASE.YML.
Cuando abramos este archivo, nos vamos a encontrar con lo siguiente
users:
user1: #username for user 1. Cambia el nombre al que más te guste, este será el que usemos para el login
displayname: "User Name 1" #Cambia el nombre al que más te guste, introducelo entre las comillas
password: "$argon2i$v=19$m=1024,t=1,p=8$eTQ3MXdqOGFiaDZoMUtMVw$OeHWQSg9zGKslOepe5t4D1T9BZJjHA1Z+doxZrZYDgI"
#La creamos con https://argon2.online/
#En plain text input, ponemos la contraseña que queremos para hacer el login en authelia
#Seleccionamos el boton de argon2id
#Pulsamos en la tuerca de salt y nos deben salir unas letras en ese recuadro
#Configramos con los siguientes parametros parallelism Factor: 8 memory cost: 1024 iterations: 1 hash length: 32
#Pulsamos en generate hash y nos debe dar algo asi en el campo outputin Encoded Form $argon2id$v=19$m=1024,t=1,p=8$NTEwNGFYVHNGNlo2OGxwOA$rPYzg2lYoNH7MQ5pv6m3isHCCcJYnf+1A/uIiMUrUhE
email: [email protected] #tu correeo electronico
groups: #si quieres crear un grupo o grupos, cambia los nombres a continuacion
- admins
- dev
#Cada vez que creemos un usuario, hay que parar y arrancar el contenedor de authelia para que ejecute los cambios.
Para obtener el enlace de la forma correcta, sólo tendremos que seguir los pasos en el orden que está comentado en el archivo.
Lo guardamos en la misma carpeta CONFIG y ahora sí, podemos arrancar el contenedor de Authelia.
Para verificar que funciona bien, en una navegador iremos a la direccion http://IPDELNAS:PUERTOELEGIDO y pulsamos intro. Deberíamos ver algo así.
Paso 3
Comenzamos la configuración de nuestros proxys inversos en NGINX Proxy Manager, para ello previamente hemos tenido que crear los subdominios en nuestro dominio.
En mi caso he creado el subdominio autheliaprueba y metube.
En NGINX Proxy Manager añado un nuevo host para el proxy autheliaprueba.bilito.es con la el subdominio correcto, la dirección IP del contenedor y el puerto elegido.
Creo el certificado SSL y guardo.
Vuelvo a editar el proxy y en SSL selecciono los cuatro checks y me voy a la pestaña de ADVANCED, donde tengo que pegar el siguiente código
location / {
set $upstream_authelia http://IPDELNAS:9091; # Tenemos que poner la IP del nas:puerto elegido
proxy_pass $upstream_authelia;
client_body_buffer_size 128k;
#Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# Advanced Proxy Config
send_timeout 5m;
proxy_read_timeout 360;
proxy_send_timeout 360;
proxy_connect_timeout 360;
# Basic Proxy Config
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;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
# If behind reverse proxy, forwards the correct IP, assumes you're using Cloudflare. Adjust IP for your Docker network.
set_real_ip_from 192.168.0.0/24; #Aqui tienes que poner el rango de la tu red de casa
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
}
Haremos los cambios que os pongo indentificados en los comentarios, en la linea 2 y en la línea 31 del archivo.
Ahora añado un nuevo host para el proxy metube.bilito.es con la el subdominio correcto, la dirección IP del contenedor y el puerto elegido.
Creo el certificado SSL y guardo.
Vuelvo a editar el proxy y en SSL selecciono los cuatro checks y me voy a la pestaña de ADVANCED, donde tengo que pegar el siguiente código
location /authelia {
internal;
set $upstream_authelia http://IPDELNAS:9091/api/verify; #Tenemos que poner la IP del nas:puerto elegido
proxy_pass_request_body off;
proxy_pass $upstream_authelia;
proxy_set_header Content-Length "";
# Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
client_body_buffer_size 128k;
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 4 32k;
send_timeout 5m;
proxy_read_timeout 240;
proxy_send_timeout 240;
proxy_connect_timeout 240;
}
location / {
set $upstream_nombredelcontenedor http://IPDELNAS:PUERTODELDOCKER; #Tenemos que poner la IP del nas:puerto elegido del contenedor sobre el que queremos crear el acceso seguro
proxy_pass $upstream_nombredelcontenedor ; #cambiar por el nombre del contenedor de la linea de arriba
auth_request /authelia;
auth_request_set $target_url $scheme://$http_host$request_uri;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
error_page 401 =302 https://auth.dominio.es/?rd=$target_url; #Cambiar auth.dominio.es por el subdominio elegido para la validacion de authelia
client_body_buffer_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
send_timeout 5m;
proxy_read_timeout 360;
proxy_send_timeout 360;
proxy_connect_timeout 360;
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;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
set_real_ip_from 192.168.0.0/16; #Aqui tienes que poner el rango de la tu red de casa, por ejemplo 192.168.1.0, dejando el /16
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
Hacemos los cambios que comento en las lineas 3, 33, 34, 42 y 67.
Una vez hecho estos cambios reinciamos el contenedor de authelia para que se apliquen de forma correcta.
Paso 4
Una vez reinciado el contenedor, si accedemos en el ejemplo creado a https://metube.bilito.es accederemos a la misma pantalla de comprobacion de funcionamiento
Introducimos el usuario creado en el archivo USER_DATABASE.yml y la contraseña que habáimos elegido.
Nos debe de salir una ventana en la que nos pide que registremos un dispositivo para la gestión del doble factor. Al pulsar en el enlace nos saldrá que nos ha enviado un correo a la dirección configurada.
En este correo hay un enlace, que debemos pulsar.
Al pulsar nos mostrará una ventana con un código QR para descargar Google authenticator y un enlace web debajo de este código QR.
En mi caso lo que hago es copiar ese código y configurarlo en bitwarden que es mi app de contraseñas, edito y le pongo ese dirección en el doble factor. Le doy a guardar y ya esta generando un código que cambia cada 30 segundos.
Cuando pulsemos sobre el botón HECHO, nos pedirá ese código y ya nos dejará entrar de forma correcta al proxy inverso creado de forma segura.
Mi nombre es David Rodríguez, apasionado por un millón de cosas que lleven placas y chips dentro.
Puedes encontrarme como @_Bilito en twitter y en grupo de Telegram de Synology NAS https://t.me/synologyNAS
Tengo un un canal de youtube que complementa al blog https://www.youtube.com/@_Bilito y que me harías un gran favor si te subscribes.
También colaboro en podcast como Bateria 2x100 https://pod.link/1115144939 y también hemos comenzado otra aventura en otro podcast Detras del Mostrador