add debug output to authelia with mitmdump module

This commit is contained in:
ibizaman 2025-07-29 23:56:23 +02:00 committed by Pierre Penninckx
parent 3184015d67
commit b2c5637cfc
5 changed files with 121 additions and 36 deletions

View file

@ -68,6 +68,9 @@
"blocks-authelia-options-shb.authelia.dcdomain": [
"blocks-authelia.html#blocks-authelia-options-shb.authelia.dcdomain"
],
"blocks-authelia-options-shb.authelia.debug": [
"blocks-authelia.html#blocks-authelia-options-shb.authelia.debug"
],
"blocks-authelia-options-shb.authelia.domain": [
"blocks-authelia.html#blocks-authelia-options-shb.authelia.domain"
],
@ -305,6 +308,9 @@
"blocks-authelia-tests": [
"blocks-authelia.html#blocks-authelia-tests"
],
"blocks-authelia-troubleshooting": [
"blocks-authelia.html#blocks-authelia-troubleshooting"
],
"blocks-lldap": [
"blocks-lldap.html#blocks-lldap"
],

View file

@ -13,6 +13,8 @@ let
autheliaCfg = config.services.authelia.instances.${fqdn};
inherit (lib) hasPrefix;
listenPort = if cfg.debug then 9090 else 9091;
in
{
options.shb.authelia = {
@ -303,6 +305,15 @@ in
readOnly = true;
default = { path = "/var/lib/redis-authelia"; };
};
debug = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Set logging level to debug and add a mitmdump instance
to see exactly what Authelia receives and sends back.
'';
};
};
config = lib.mkIf cfg.enable {
@ -347,7 +358,7 @@ in
AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = lib.mkIf (!(builtins.isString cfg.smtp)) (toString cfg.smtp.password.result.path);
};
settings = {
server.address = "tcp://127.0.0.1:9091";
server.address = "tcp://127.0.0.1:${toString listenPort}";
# Inspired from https://github.com/lldap/lldap/blob/7d1f5abc137821c500de99c94f7579761fc949d8/example_configs/authelia_config.yml
authentication_backend = {
@ -446,6 +457,8 @@ in
address = "tcp://127.0.0.1:9959";
};
};
log.level = if cfg.debug then "debug" else "info";
};
settingsFiles = [ "/var/lib/authelia-${fqdn}/oidc_clients.yaml" ];
@ -485,6 +498,8 @@ in
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
@ -513,6 +528,19 @@ in
'';
};
# I would like this to live outside of the Authelia module.
# This will require a reverse proxy contract.
# Actually, not sure a full reverse proxy contract is needed.
shb.mitmdump.instances."authelia-${fqdn}" = lib.mkIf cfg.debug {
listenPort = 9091;
upstreamPort = 9090;
after = [ "authelia-${fqdn}.service" ];
enabledAddons = [ config.shb.mitmdump.addons.logger ];
extraArgs = [
"--set" "verbose_pattern=/api"
];
};
services.redis.servers.authelia = {
enable = true;
user = autheliaCfg.user;

View file

@ -6,6 +6,11 @@ This block sets up an [Authelia][] service for Single-Sign On integration.
[Authelia]: https://www.authelia.com/
Compared to the upstream nixpkgs module, this module is tightly integrated
with SHB which allows easy configuration of SSO with [OIDC integration](#blocks-authelia-shb-oidc)
or with [forward auth integration](#blocks-authelia-shb-forward-auth)
as well as some extensive [troubleshooting](#blocks-authelia-troubleshooting) features.
## Global Setup {#blocks-authelia-global-setup}
Authelia cannot work without SSL and LDAP.
@ -221,6 +226,19 @@ shb.nginx.vhosts = [
This configuration assumes usage of the [SSL block][].
## Troubleshooting {#blocks-authelia-troubleshooting}
Set the [debug][opt-debug] option to `true` to:
[opt-debug]: #blocks-authelia-options-shb.authelia.debug
- Set logging level to `"debug"`.
- Add an [shb.mitmdump][] instance in front of Authelia
which prints all requests and responses headers and body
to the systemd service `mitmdump-authelia-${config.shb.authelia.subdomain}.${config.shb.authelia.domain}.service`.
[shb.mitmdump]: ./blocks-mitmdump.html
## Tests {#blocks-authelia-tests}
Specific integration tests are defined in [`/test/blocks/authelia.nix`](@REPO@/test/blocks/authelia.nix).

View file

@ -15,6 +15,7 @@ in
../../modules/blocks/authelia.nix
../../modules/blocks/hardcodedsecret.nix
../../modules/blocks/lldap.nix
../../modules/blocks/mitmdump.nix
../../modules/blocks/postgresql.nix
];
@ -109,48 +110,79 @@ in
${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096
'') + "/private.pem";
};
specialisation = {
withDebug.configuration = {
shb.authelia.debug = true;
};
};
};
testScript = { nodes, ... }: ''
testScript = { nodes, ... }:
let
specializations = "${nodes.machine.system.build.toplevel}/specialisation";
in
''
import json
start_all()
machine.wait_for_unit("lldap.service")
machine.wait_for_unit("authelia-authelia.machine.com.service")
machine.wait_for_open_port(9091)
endpoints = json.loads(machine.succeed("curl -s http://machine.com/.well-known/openid-configuration"))
auth_endpoint = endpoints['authorization_endpoint']
def tests():
machine.wait_for_unit("lldap.service")
machine.wait_for_unit("authelia-authelia.machine.com.service")
machine.wait_for_open_port(9091)
machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=other"
+ "&redirect_uri=http://client1.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=99999999'"
)
endpoints = json.loads(machine.succeed("curl -s http://machine.com/.well-known/openid-configuration"))
auth_endpoint = endpoints['authorization_endpoint']
print(f"auth_endpoint: {auth_endpoint}")
if auth_endpoint != "http://machine.com/api/oidc/authorization":
raise Exception("Unexpected auth_endpoint")
machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=client1"
+ "&redirect_uri=http://client1.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=11111111'"
)
resp = machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=other"
+ "&redirect_uri=http://client1.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=99999999'"
)
print(resp)
if resp != "":
raise Exception("unexpected response")
machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=client2"
+ "&redirect_uri=http://client2.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=22222222'"
)
resp = machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=client1"
+ "&redirect_uri=http://client1.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=11111111'"
)
print(resp)
if "Found" not in resp:
raise Exception("unexpected response")
resp = machine.succeed(
"curl -f -s '"
+ auth_endpoint
+ "?client_id=client2"
+ "&redirect_uri=http://client2.machine.com/redirect"
+ "&scope=openid%20profile%20email"
+ "&response_type=code"
+ "&state=22222222'"
)
print(resp)
if "Found" not in resp:
raise Exception("unexpected response")
with subtest("no debug"):
tests()
with subtest("with debug"):
machine.succeed('${specializations}/withDebug/bin/switch-to-configuration test')
tests()
'';
};
}

View file

@ -188,10 +188,11 @@ in
};
imports = [
baseImports
../modules/blocks/postgresql.nix
../modules/blocks/authelia.nix
../modules/blocks/nginx.nix
../modules/blocks/hardcodedsecret.nix
../modules/blocks/mitmdump.nix
../modules/blocks/nginx.nix
../modules/blocks/postgresql.nix
];
config = {
# HTTP(s) server port.