Authelia, nginx e autenticação MFA no nosso homelab.

Olá a todos,

Hoje, vamos explorar um tópico que irá aumentar em muito a segurança dos nossos serviços web: a integração do Authelia no Nginx Reverse Proxy.
Perguntam certamente porque? O que temos a ganhar sobre a nossa boa e confiável basic_auth do apache? A resposta é quase sempre a mesma: Because google made me do it… E a segurança também o exige.
Como sabem  google está aos poucos e poucos a matar o basic_auth como forma de autenticação. Começou pela autenticação em serviços deles, como por exemplo gmail (pop3s/imaps/smtps), para agora estar a ser já enforced em alguns sites já. O chromium e derivados já estão simplesmente a mostrar erros 401 e 403 em sites que tenham apenas basic authentication enabled.
Claro que existem outros browser – eu pessoalmente uso um da concorrência á google – mas sei que quando isto começa que será apenas uma questão de tempo até aos outros seguirem o exemplo e mais cedo ou mais tarde este método será deprecated de vez e a funcionar em muito menos sitios.
Como não gosto de esperar que o machado caia no meu pescoço, meti pés a caminho e implementei um sistema baseado em authelia, nginx e apache para conseguir o efeito desejado.

Conhecendo o Authelia

GitHub - authelia/authelia: The Single Sign-On Multi-Factor portal for web apps

Antes de mergulharmos nas entranhas da integração, vamos relembrar o que torna o Authelia uma ferramenta fundamental nos dias de hoje.
Em termos simples, o Authelia é um autenticador multifator que eleva a segurança dos seus serviços online. Mas por que escolher este em particular? Calhou. Entre vários que vi, pareceu-me ser o que tinha uma comunidade mais activa e menos reports de falhas de segurança.

Nginx: É o heroi desta vez? Que é que aconteceu com o apache?

Agora, a resposta para a pergunta que estão a fazer: Por que optar pelo nginx como o nosso reverse proxy se já estou a usar Apache? Porque para além da sua reputação de desempenho sólido, o nginx oferece uma flexibilidade incrível. Combinado ao Authelia, cria-se uma barreira de segurança robusta.
O Apache – e ainda o utilizo na minha infraestrutura para funções semelhantes – falta lhe algo que o Nginx tem: forward auth, que é a componente que interage com o authelia para garantir o processo de autenticação.

Quais as vantagens que o Authelia nos dá?

Vantagem #1: Autenticação Multifator sem Complicações

O Authelia simplifica a implementação da autenticação multifator, tornando o processo acessível até mesmo para administradores menos experientes. Na prática, isto significa uma camada extra de proteção sem a dor de cabeça das configurações complexas.

Vantagem #2: Gestão Centralizada de Acessos

A gestão de acessos pode ser uma verdadeira dor de cabeça. Com a integração do authelia no nginx, ganhamos uma solução elegante para este dilema. A capacidade de gerenciar acessos centralmente torna simples controlar quem pode acessar os serviços web com apenas alguns cliques.
O authelia tem ainda integração seamless com o freeipa/ldap. Para quem tem as coisas montadas com um nível extra de autenticação e IDM centralizado, sabe a mais valia que isto é.

Vantagem #3: Regras de Autenticação Personalizadas

O authelia não segue o modelo “one-size-fits-all”. Ele permite a criação de regras personalizadas para autenticação, adaptadas às necessidades específicas do nosso ambiente. Seja autenticação de dois fatores baseada em localização geográfica ou regras específicas para determinados utilizadores, o authelia nativamente torna isso possível.

Vantagem #4: Auditoria, Auditoria, Auditoria.

A auditoria é vital para a segurança dos nossos sistemas. Este tipo de integração facilita o tracking de quem acedeu ao quê e quando. Isto não apenas aumenta a segurança, mas também simplifica o cumprimento de requisitos regulamentares que voçes, ou a vossa empresa possa ter.

Instalação Passo a Passo

Agora, o nosso momento prático. Vamos detalhar um guia passo a passo para integrar o authelia no nosso nginx reverse proxy. No fim deixarei templates de como está o meu configurado para vos auxilar no vosso caminho:

  1. Instalação do nginx: Se ainda não fizeram isso, comecem a instalar o nginx no vosso servidor. Configurem corretamente os blocos de servidor para os seus serviços web.
  2. Instalação do authelia: Sigam as instruções de instalação do authelia no site oficial. Configure os arquivos de configuração de acordo com as suas necessidades.
  3. Configuração do nginx para authelia: Ajustem a configuração do nginx para redirecionar o tráfego através do authelia antes de alcançar os seus serviços web. Configurem blocos de localização específicos no arquivo de configuração do nginx.
  4. Configuração do authelia para nginx: Assegurem-se de que o Authelia está configurado para autenticar pedidos do nginx. Isso envolve a sincronização de alguns parâmetros chave entre o nginx e authelia e configurações entre os dois sistemas.
  5. Teste e Ajuste: Antes de implementarem em produção, façam testes rigorosos. Certifiquem-se de que a autenticação funciona conforme esperado e ajustem as configurações conforme necessário.

E sobre os templates?

Configuração do vhost em apache, que irá responder externamente a vossa rede pelo authelia. É através para este site/ponto que o nginx vos irá enviar para autenticação:

<VirtualHost *:443>

ServerName myauth.myfancydomain.com:443
ServerAdmin [email protected]
Options +FollowSymLinks
SSLEngine on
SSLCertificateKeyFile /etc/letsencrypt/live/myfancydomain.com/privkey.pem
SSLCertificateFile /etc/letsencrypt/live/myfancydomain.com/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/myfancydomain.com/chain.pem

ErrorLog "| /usr/bin/logger -treverse_proxy_auth.myfancydomain.com -plocal6.err"
CustomLog "| /usr/bin/logger -treverse_proxy_auth.myfancydomain.com -plocal6.notice" combined

SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
SSLCompression Off
SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES256-SHA256:AES128-SHA256:AES128-SHA:DHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA:RC4-SHA:!aNULL:!eNULL:!ADH:!EXP:!LOW:!DES:!MD5:!PSK:!SRP:!DSS:!RC4

SSLProxyEngine On
ProxyPass / https://autheliavip.myinternaldomain.xpto:9091/ # CORRIGIR PARA O FQDN INTERNO DO VOSSO AUTHELIA
ProxyPassReverse / https://autheliavip.myinternaldomain.xpto:9091/ # CORRIGIR PARA O FQDN INTERNO DO VOSSO AUTHELIA
ProxyRequests Off
ProxyPreserveHost On
RemoteIPProxyProtocol On
RemoteIPHeader X-Forwarded-For

RewriteEngine On 
RewriteCond %{REQUEST_METHOD} ^TRACE 
RewriteRule .* - [F]

SSLProxyVerify none
SSLProxyCheckPeerCN on
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on

</VirtualHost>

Configuração do server block (vhost) do nginx para autenticação do site contra o authelia:

server {
server_name mysite.myfancydomain.com;
index index.html;
location /authelia {
internal;
set $upstream_authelia https://autheliavip.myinternaldomain.xpto:9091/api/verify;  # CORRIGIR PARA O FQDN INTERNO DO VOSSO AUTHELIA
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 / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://dockervip03.net.xpto:8443/; # CORRIGIR PARA O IP DO VOSSO APP AUTENTICADA PELO AUTHELIA
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://myauthelia.nuneshiggs.com/?rd=$target_url; 
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 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 https:// $scheme://;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 64 256k;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
}
listen 443 ssl;

ssl_certificate "/etc/letsencrypt/live/myfancydomain.com/cert.pem";
ssl_certificate_key "/etc/letsencrypt/live/myfancydomain.com/privkey.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

Configuração do authelia em si:

Esta é a *minha* configuração do authelia. A vossa será certamente diferente pois está intimamente ligada a minha infraestrutura e o que não faltam são exemplos na net para vos ajudar. Se isso não funcionar, sabem onde me achar 🙂

Este é um yaml file. Tem de ter muito respeito com as indentações sobre a pena do ficheiro não ser lido pelo authelia. Recomendo o visual studio code para acertarem elas.

Configuration

Chegamos ao fim de mais um post técnico, desta forma direcionado para criar um sistema multi level de autenticação. O processo aqui descrito pode parecer complexo, mas até é bastante simples, e os resultados são muito bons para o tempo que irão investir nele.
O authelia tem ainda outra vantagem. Com DB de backend, podem como eu, implementar dois containers em hosts separados a fazerem load balancing c/failover em caso de problemas garantido assim alta disponibilidade no serviço.

Se tiverem duvidas ou reparos, sabem onde me encontrar.
Até ao próximo post.

Um abraço.
Nuno