notes: 2.3.0 -> 2.3.1 (#352950)
[NixPkgs.git] / nixos / tests / authelia.nix
blob679c65fea087a79f2d8bd8f69830b05374e44e15
1 # Test Authelia as an auth server for Traefik as a reverse proxy of a local web service
2 import ./make-test-python.nix ({ lib, ... }: {
3   name = "authelia";
4   meta.maintainers = with lib.maintainers; [ jk ];
6   nodes = {
7     authelia = { config, pkgs, lib, ... }: {
8       services.authelia.instances.testing = {
9         enable = true;
10         secrets.storageEncryptionKeyFile = "/etc/authelia/storageEncryptionKeyFile";
11         secrets.jwtSecretFile = "/etc/authelia/jwtSecretFile";
12         settings = {
13           authentication_backend.file.path = "/etc/authelia/users_database.yml";
14           access_control.default_policy = "one_factor";
15           session.domain = "example.com";
16           storage.local.path = "/tmp/db.sqlite3";
17           notifier.filesystem.filename = "/tmp/notifications.txt";
18         };
19       };
21       # These should not be set from nix but through other means to not leak the secret!
22       # This is purely for testing purposes!
23       environment.etc."authelia/storageEncryptionKeyFile" = {
24         mode = "0400";
25         user = "authelia-testing";
26         text = "you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this";
27       };
28       environment.etc."authelia/jwtSecretFile" = {
29         mode = "0400";
30         user = "authelia-testing";
31         text = "a_very_important_secret";
32       };
33       environment.etc."authelia/users_database.yml" = {
34         mode = "0400";
35         user = "authelia-testing";
36         text = ''
37           users:
38             bob:
39               disabled: false
40               displayname: bob
41               # password of password
42               password: $argon2id$v=19$m=65536,t=3,p=4$2ohUAfh9yetl+utr4tLcCQ$AsXx0VlwjvNnCsa70u4HKZvFkC8Gwajr2pHGKcND/xs
43               email: bob@jim.com
44               groups:
45                 - admin
46                 - dev
47         '';
48       };
50       services.traefik = {
51         enable = true;
53         dynamicConfigOptions = {
54           tls.certificates =
55             let
56               certDir = pkgs.runCommand "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
57                 openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=example.com/CN=auth.example.com/CN=static.example.com' -days 36500
58                 mkdir -p $out
59                 cp key.pem cert.pem $out
60               '';
61             in
62             [{
63               certFile = "${certDir}/cert.pem";
64               keyFile = "${certDir}/key.pem";
65             }];
66           http.middlewares.authelia.forwardAuth = {
67             address = "http://localhost:9091/api/verify?rd=https%3A%2F%2Fauth.example.com%2F";
68             trustForwardHeader = true;
69             authResponseHeaders = [
70               "Remote-User"
71               "Remote-Groups"
72               "Remote-Email"
73               "Remote-Name"
74             ];
75           };
76           http.middlewares.authelia-basic.forwardAuth = {
77             address = "http://localhost:9091/api/verify?auth=basic";
78             trustForwardHeader = true;
79             authResponseHeaders = [
80               "Remote-User"
81               "Remote-Groups"
82               "Remote-Email"
83               "Remote-Name"
84             ];
85           };
87           http.routers.simplehttp = {
88             rule = "Host(`static.example.com`)";
89             tls = true;
90             entryPoints = "web";
91             service = "simplehttp";
92           };
93           http.routers.simplehttp-basic-auth = {
94             rule = "Host(`static-basic-auth.example.com`)";
95             tls = true;
96             entryPoints = "web";
97             service = "simplehttp";
98             middlewares = [ "authelia-basic@file" ];
99           };
101           http.services.simplehttp = {
102             loadBalancer.servers = [{
103               url = "http://localhost:8000";
104             }];
105           };
107           http.routers.authelia = {
108             rule = "Host(`auth.example.com`)";
109             tls = true;
110             entryPoints = "web";
111             service = "authelia@file";
112           };
114           http.services.authelia = {
115             loadBalancer.servers = [{
116               url = "http://localhost:9091";
117             }];
118           };
119         };
121         staticConfigOptions = {
122           global = {
123             checkNewVersion = false;
124             sendAnonymousUsage = false;
125           };
127           entryPoints.web.address = ":443";
128         };
129       };
131       systemd.services.simplehttp =
132         let fakeWebPageDir = pkgs.writeTextDir "index.html" "hello"; in
133         {
134           script = "${pkgs.python3}/bin/python -m http.server --directory ${fakeWebPageDir} 8000";
135           serviceConfig.Type = "simple";
136           wantedBy = [ "multi-user.target" ];
137         };
138     };
139   };
141   testScript = ''
142     start_all()
144     authelia.wait_for_unit("simplehttp.service")
145     authelia.wait_for_unit("traefik.service")
146     authelia.wait_for_unit("authelia-testing.service")
147     authelia.wait_for_open_port(443)
148     authelia.wait_for_unit("multi-user.target")
150     with subtest("Check for authelia"):
151       # expect the login page
152       assert "Login - Authelia", "could not reach authelia" in \
153         authelia.succeed("curl --insecure -sSf -H Host:auth.example.com https://authelia:443/")
155     with subtest("Check contacting basic http server via traefik with https works"):
156       assert "hello", "could not reach raw static site" in \
157         authelia.succeed("curl --insecure -sSf -H Host:static.example.com https://authelia:443/")
159     with subtest("Test traefik and authelia"):
160       with subtest("No details fail"):
161         authelia.fail("curl --insecure -sSf -H Host:static-basic-auth.example.com https://authelia:443/")
162       with subtest("Incorrect details fail"):
163         authelia.fail("curl --insecure -sSf -u 'bob:wordpass' -H Host:static-basic-auth.example.com https://authelia:443/")
164         authelia.fail("curl --insecure -sSf -u 'alice:password' -H Host:static-basic-auth.example.com https://authelia:443/")
165       with subtest("Correct details pass"):
166         assert "hello", "could not reach authed static site with valid credentials" in \
167           authelia.succeed("curl --insecure -sSf -u 'bob:password' -H Host:static-basic-auth.example.com https://authelia:443/")
168   '';