From 33cf4f0e8eea945984486d747cdf7c35b89ccf51 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 20 Oct 2020 14:06:37 +0000 Subject: [PATCH 1/4] nginx: factor out the generation of basic auth generation --- .../services/web-servers/nginx/default.nix | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index c0c2f27a00e..ee105369863 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -261,10 +261,7 @@ let ssl_trusted_certificate ${vhost.sslTrustedCertificate}; ''} - ${optionalString (vhost.basicAuthFile != null || vhost.basicAuth != {}) '' - auth_basic secured; - auth_basic_user_file ${if vhost.basicAuthFile != null then vhost.basicAuthFile else mkHtpasswd vhostName vhost.basicAuth}; - ''} + ${mkBasicAuth vhostName vhost} ${mkLocations vhost.locations} @@ -295,7 +292,16 @@ let ${optionalString (config.proxyPass != null && cfg.recommendedProxySettings) "include ${recommendedProxyConfig};"} } '') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations))); - mkHtpasswd = vhostName: authDef: pkgs.writeText "${vhostName}.htpasswd" ( + + mkBasicAuth = name: zone: optionalString (zone.basicAuthFile != null || zone.basicAuth != {}) (let + auth_file = if zone.basicAuthFile != null + then zone.basicAuthFile + else mkHtpasswd name zone.basicAuth; + in '' + auth_basic secured; + auth_basic_user_file ${auth_file}; + ''); + mkHtpasswd = name: authDef: pkgs.writeText "${name}.htpasswd" ( concatStringsSep "\n" (mapAttrsToList (user: password: '' ${user}:{PLAIN}${password} '') authDef) From c7bf3828f04e512a6ef2691f7e48d527961f3692 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 20 Oct 2020 14:11:21 +0000 Subject: [PATCH 2/4] nginx: add basic auth support for locations --- .../services/web-servers/nginx/default.nix | 1 + .../web-servers/nginx/location-options.nix | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index ee105369863..e9630d379f3 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -290,6 +290,7 @@ let ${optionalString (config.return != null) "return ${config.return};"} ${config.extraConfig} ${optionalString (config.proxyPass != null && cfg.recommendedProxySettings) "include ${recommendedProxyConfig};"} + ${mkBasicAuth "sublocation" config} } '') (sortProperties (mapAttrsToList (k: v: v // { location = k; }) locations))); diff --git a/nixos/modules/services/web-servers/nginx/location-options.nix b/nixos/modules/services/web-servers/nginx/location-options.nix index 3d9e391ecf2..793f29f09fb 100644 --- a/nixos/modules/services/web-servers/nginx/location-options.nix +++ b/nixos/modules/services/web-servers/nginx/location-options.nix @@ -9,6 +9,31 @@ with lib; { options = { + basicAuth = mkOption { + type = types.attrsOf types.str; + default = {}; + example = literalExample '' + { + user = "password"; + }; + ''; + description = '' + Basic Auth protection for a vhost. + + WARNING: This is implemented to store the password in plain text in the + nix store. + ''; + }; + + basicAuthFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Basic Auth password file for a vhost. + Can be created via: htpasswd -c <filename> <username> + ''; + }; + proxyPass = mkOption { type = types.nullOr types.str; default = null; From a4b86b2bf5bd85f1695a8b47bd07657758de1722 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 20 Oct 2020 16:05:41 +0000 Subject: [PATCH 3/4] nginx: test basic auth --- nixos/tests/all-tests.nix | 1 + nixos/tests/nginx-auth.nix | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 nixos/tests/nginx-auth.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 9ffeba27a7f..4e4d8b5e689 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -242,6 +242,7 @@ in nfs4 = handleTest ./nfs { version = 4; }; nghttpx = handleTest ./nghttpx.nix {}; nginx = handleTest ./nginx.nix {}; + nginx-auth = handleTest ./nginx-auth.nix {}; nginx-etag = handleTest ./nginx-etag.nix {}; nginx-pubhtml = handleTest ./nginx-pubhtml.nix {}; nginx-sandbox = handleTestOn ["x86_64-linux"] ./nginx-sandbox.nix {}; diff --git a/nixos/tests/nginx-auth.nix b/nixos/tests/nginx-auth.nix new file mode 100644 index 00000000000..c0d24a20ddb --- /dev/null +++ b/nixos/tests/nginx-auth.nix @@ -0,0 +1,47 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "nginx-auth"; + + nodes = { + webserver = { pkgs, lib, ... }: { + services.nginx = let + root = pkgs.runCommand "testdir" {} '' + mkdir "$out" + echo hello world > "$out/index.html" + ''; + in { + enable = true; + + virtualHosts.lockedroot = { + inherit root; + basicAuth.alice = "jane"; + }; + + virtualHosts.lockedsubdir = { + inherit root; + locations."/sublocation/" = { + alias = "${root}/"; + basicAuth.bob = "john"; + }; + }; + }; + }; + }; + + testScript = '' + webserver.wait_for_unit("nginx") + webserver.wait_for_open_port(80) + + webserver.fail("curl --fail --resolve lockedroot:80:127.0.0.1 http://lockedroot") + webserver.succeed( + "curl --fail --resolve lockedroot:80:127.0.0.1 http://alice:jane@lockedroot" + ) + + webserver.succeed("curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir") + webserver.fail( + "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://lockedsubdir/sublocation/index.html" + ) + webserver.succeed( + "curl --fail --resolve lockedsubdir:80:127.0.0.1 http://bob:john@lockedsubdir/sublocation/index.html" + ) + ''; +}) From 3361a037b9c29254b611de76dbc14bded60a3bd8 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Mon, 2 Nov 2020 08:15:28 -0500 Subject: [PATCH 4/4] nginx: add a warning that nginx's basic auth isn't very good. --- .../services/web-servers/nginx/location-options.nix | 7 +++++-- nixos/modules/services/web-servers/nginx/vhost-options.nix | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/nixos/modules/services/web-servers/nginx/location-options.nix b/nixos/modules/services/web-servers/nginx/location-options.nix index 793f29f09fb..f2fc0725572 100644 --- a/nixos/modules/services/web-servers/nginx/location-options.nix +++ b/nixos/modules/services/web-servers/nginx/location-options.nix @@ -21,7 +21,7 @@ with lib; Basic Auth protection for a vhost. WARNING: This is implemented to store the password in plain text in the - nix store. + Nix store. ''; }; @@ -30,7 +30,10 @@ with lib; default = null; description = '' Basic Auth password file for a vhost. - Can be created via: htpasswd -c <filename> <username> + Can be created via: htpasswd -c <filename> <username>. + + WARNING: The generate file contains the users' passwords in a + non-cryptographically-securely hashed way. ''; }; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index 455854e2a96..cf211ea9a71 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -198,7 +198,7 @@ with lib; Basic Auth protection for a vhost. WARNING: This is implemented to store the password in plain text in the - nix store. + Nix store. ''; }; @@ -207,7 +207,10 @@ with lib; default = null; description = '' Basic Auth password file for a vhost. - Can be created via: htpasswd -c <filename> <username> + Can be created via: htpasswd -c <filename> <username>. + + WARNING: The generate file contains the users' passwords in a + non-cryptographically-securely hashed way. ''; };