diff options
author | Anderson Torres <torres.anderson.85@protonmail.com> | 2022-11-18 14:46:03 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-18 14:46:03 -0300 |
commit | fc8a4f72910595b287fdde96b66f75fec760715f (patch) | |
tree | 4c560b30ecdd572c867337f73fee82a16a6db93f /nixos | |
parent | 5dcab938e0c5219937cc22bf7b3555babfb3e457 (diff) | |
parent | ee758abefeb001e2044ae59415b500cc36d2f2b1 (diff) |
Merge pull request #201521 from hmenke/alps
nixos/alps: add hardening, extensible options, test
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/services/web-apps/alps.nix | 52 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/alps.nix | 104 |
3 files changed, 148 insertions, 9 deletions
diff --git a/nixos/modules/services/web-apps/alps.nix b/nixos/modules/services/web-apps/alps.nix index b73cb82925d9b..4681739af4ab0 100644 --- a/nixos/modules/services/web-apps/alps.nix +++ b/nixos/modules/services/web-apps/alps.nix @@ -70,6 +70,23 @@ in { ''; }; }; + + package = mkOption { + internal = true; + type = types.package; + default = pkgs.alps; + }; + + args = mkOption { + internal = true; + type = types.listOf types.str; + default = [ + "-addr" "${cfg.bindIP}:${toString cfg.port}" + "-theme" "${cfg.theme}" + "imaps://${cfg.imaps.host}:${toString cfg.imaps.port}" + "smpts://${cfg.smtps.host}:${toString cfg.smtps.port}" + ]; + }; }; config = mkIf cfg.enable { @@ -80,16 +97,33 @@ in { after = [ "network.target" "network-online.target" ]; serviceConfig = { - ExecStart = '' - ${pkgs.alps}/bin/alps \ - -addr ${cfg.bindIP}:${toString cfg.port} \ - -theme ${cfg.theme} \ - imaps://${cfg.imaps.host}:${toString cfg.imaps.port} \ - smpts://${cfg.smtps.host}:${toString cfg.smtps.port} - ''; - StateDirectory = "alps"; - WorkingDirectory = "/var/lib/alps"; + ExecStart = "${cfg.package}/bin/alps ${escapeShellArgs cfg.args}"; DynamicUser = true; + ## This is desirable but would restrict bindIP to 127.0.0.1 + #IPAddressAllow = "localhost"; + #IPAddressDeny = "any"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateIPC = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service @resources" "~@privileged @obsolete" ]; }; }; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index bd0fe18c4f8c2..b238c43849512 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -74,6 +74,7 @@ in { agda = handleTest ./agda.nix {}; airsonic = handleTest ./airsonic.nix {}; allTerminfo = handleTest ./all-terminfo.nix {}; + alps = handleTest ./alps.nix {}; amazon-init-shell = handleTest ./amazon-init-shell.nix {}; apfs = handleTest ./apfs.nix {}; apparmor = handleTest ./apparmor.nix {}; diff --git a/nixos/tests/alps.nix b/nixos/tests/alps.nix new file mode 100644 index 0000000000000..8d7814117df1e --- /dev/null +++ b/nixos/tests/alps.nix @@ -0,0 +1,104 @@ +let + certs = import ./common/acme/server/snakeoil-certs.nix; + domain = certs.domain; +in +import ./make-test-python.nix ({ pkgs, ... }: { + name = "alps"; + + nodes = { + server = { + imports = [ ./common/user-account.nix ]; + security.pki.certificateFiles = [ + certs.ca.cert + ]; + networking.extraHosts = '' + 127.0.0.1 ${domain} + ''; + networking.firewall.allowedTCPPorts = [ 25 465 993 ]; + services.postfix = { + enable = true; + enableSubmission = true; + enableSubmissions = true; + tlsTrustedAuthorities = "${certs.ca.cert}"; + sslCert = "${certs.${domain}.cert}"; + sslKey = "${certs.${domain}.key}"; + }; + services.dovecot2 = { + enable = true; + enableImap = true; + sslCACert = "${certs.ca.cert}"; + sslServerCert = "${certs.${domain}.cert}"; + sslServerKey = "${certs.${domain}.key}"; + }; + }; + + client = { nodes, config, ... }: { + security.pki.certificateFiles = [ + certs.ca.cert + ]; + networking.extraHosts = '' + ${nodes.server.config.networking.primaryIPAddress} ${domain} + ''; + services.alps = { + enable = true; + theme = "alps"; + imaps = { + host = domain; + port = 993; + }; + smtps = { + host = domain; + port = 465; + }; + }; + environment.systemPackages = [ + (pkgs.writers.writePython3Bin "test-alps-login" { } '' + from urllib.request import build_opener, HTTPCookieProcessor, Request + from urllib.parse import urlencode, urljoin + from http.cookiejar import CookieJar + + baseurl = "http://localhost:${toString config.services.alps.port}" + username = "alice" + password = "${nodes.server.config.users.users.alice.password}" + cookiejar = CookieJar() + cookieprocessor = HTTPCookieProcessor(cookiejar) + opener = build_opener(cookieprocessor) + + data = urlencode({"username": username, "password": password}).encode() + req = Request(urljoin(baseurl, "login"), data=data, method="POST") + with opener.open(req) as ret: + # Check that the alps_session cookie is set + print(cookiejar) + assert any(cookie.name == "alps_session" for cookie in cookiejar) + + req = Request(baseurl) + with opener.open(req) as ret: + # Check that the alps_session cookie is still there... + print(cookiejar) + assert any(cookie.name == "alps_session" for cookie in cookiejar) + # ...and that we have not been redirected back to the login page + print(ret.url) + assert ret.url == urljoin(baseurl, "mailbox/INBOX") + + req = Request(urljoin(baseurl, "logout")) + with opener.open(req) as ret: + # Check that the alps_session cookie is now gone + print(cookiejar) + assert all(cookie.name != "alps_session" for cookie in cookiejar) + '') + ]; + }; + }; + + testScript = '' + server.start() + server.wait_for_unit("postfix.service") + server.wait_for_unit("dovecot2.service") + server.wait_for_open_port(465) + server.wait_for_open_port(993) + + client.start() + client.wait_for_unit("alps.service") + client.succeed("test-alps-login") + ''; +}) |