diff --git a/config/portunus_seeds.json b/config/portunus_seeds.json index 5b213fd..b73bf07 100644 --- a/config/portunus_seeds.json +++ b/config/portunus_seeds.json @@ -26,6 +26,15 @@ "portunus": { "is_admin": false }, "ldap": { "can_read": false } } + }, + { + "name": "search", + "long_name": "LDAP search group", + "members": ["search"], + "permissions": { + "portunus": { "is_admin": false }, + "ldap": { "can_read": true } + } } ], "users": [ @@ -34,6 +43,12 @@ "given_name": "admin", "family_name": "admin", "password": { "from_command": ["/usr/bin/env", "cat", "/run/secrets/portunus_admin"] } + }, + { + "login_name": "search", + "given_name": "search", + "family_name": "search", + "password": { "from_command": ["/usr/bin/env", "cat", "/run/secrets/portunus_search"] } } ] } diff --git a/flake.lock b/flake.lock index 714027c..84b48fd 100644 --- a/flake.lock +++ b/flake.lock @@ -71,11 +71,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1670146390, - "narHash": "sha256-XrEoDpuloRHHbUkbPnhF2bQ0uwHllXq3NHxtuVe/QK4=", + "lastModified": 1673740915, + "narHash": "sha256-MMH8zONfqahgHly3K8/A++X34800rajA/XgZ2DzNL/M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "86370507cb20c905800527539fc049a2bf09c667", + "rev": "7c65528c3f8462b902e09d1ccca23bb9034665c2", "type": "github" }, "original": { @@ -87,11 +87,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1671215800, - "narHash": "sha256-2W54K41A7MefEaWzgL/TsaWlhKRK/RhWUybyOW4i0K8=", + "lastModified": 1673800717, + "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", "owner": "nixos", "repo": "nixpkgs", - "rev": "9d692a724e74d2a49f7c985132972f991d144254", + "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", "type": "github" }, "original": { @@ -116,11 +116,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1670149631, - "narHash": "sha256-rwmtlxx45PvOeZNP51wql/cWjY3rqzIR3Oj2Y+V7jM0=", + "lastModified": 1673752321, + "narHash": "sha256-EFfXY1ZHJq4FNaNQA9x0djtu/jiOhBbT0Xi+BT06cJw=", "owner": "Mic92", "repo": "sops-nix", - "rev": "da98a111623101c64474a14983d83dad8f09f93d", + "rev": "e18eefd2b133a58309475298052c341c08470717", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index fee070a..335440c 100755 --- a/flake.nix +++ b/flake.nix @@ -66,6 +66,7 @@ ./modules/wiki.nix ./modules/stream.nix ./modules/nextcloud.nix + ./modules/matrix.nix { fsr.enable_office_bloat = false; fsr.domain = "staging.ifsr.de"; diff --git a/modules/ldap.nix b/modules/ldap.nix index 20a8cc8..a1965a6 100644 --- a/modules/ldap.nix +++ b/modules/ldap.nix @@ -29,9 +29,15 @@ in members = [ "${ldapUser}" ]; }; - sops.secrets."portunus_admin" = { - owner = "${portunusUser}"; - group = "${portunusGroup}"; + sops.secrets = { + "portunus_admin" = { + owner = "${portunusUser}"; + group = "${portunusGroup}"; + }; + "portunus_search" = { + owner = "${portunusUser}"; + group = "${portunusGroup}"; + }; }; services.portunus = { @@ -40,10 +46,16 @@ in group = "${portunusGroup}"; domain = "${domain}"; port = 8081; + ldap = { user = "${ldapUser}"; group = "${ldapGroup}"; + suffix = "dc=ifsr,dc=de"; + searchUserName = "search"; + + # disables port 389, use 636 with tls + # `portunus.domain` resolves to localhost tls = true; }; @@ -60,9 +72,4 @@ in }; }; }; - - networking.firewall.allowedTCPPorts = [ - 80 # http - 443 # https - ]; } diff --git a/modules/matrix.nix b/modules/matrix.nix new file mode 100644 index 0000000..82cfa0f --- /dev/null +++ b/modules/matrix.nix @@ -0,0 +1,141 @@ +{ config, pkgs, lib, ... }: +let + domainServer = "matrix.${config.fsr.domain}"; + domainClient = "chat.${config.fsr.domain}"; + + clientConfig = { + "m.homeserver" = { + base_url = "https://${domainServer}:443"; + server_name = domainServer; + }; + }; + serverConfig = { + "m.server" = "${domainServer}:443"; + }; + + mkWellKnown = data: '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON data}'; + ''; + + # build ldap3 plugin from git because it's very outdated in nixpkgs + matrix-synapse-ldap3 = pkgs.python3.pkgs.callPackage ../pkgs/matrix-synapse-ldap3.nix { }; + # matrix-synapse-ldap3 = config.services.matrix-synapse.package.plugins.matrix-synapse-ldap3; +in +{ + sops.secrets.matrix_ldap_search = { + key = "portunus_search"; + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + }; + + services = { + postgresql = { + enable = true; + ensureUsers = [{ + name = "matrix-synapse"; + }]; + }; + + nginx = { + recommendedProxySettings = true; + virtualHosts = { + # synapse + "${domainServer}" = { + enableACME = true; + forceSSL = true; + + # homeserver discovery + locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; + locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; + + # 404 on / + locations."/".extraConfig = "return 404;"; + + # proxy to synapse + locations."/_matrix".proxyPass = "http://[::1]:8008"; + locations."/_synapse/client".proxyPass = "http://[::1]:8008"; + }; + + # element + "${domainClient}" = { + enableACME = true; + forceSSL = true; + + root = pkgs.element-web.override { + conf = { + default_server_config = clientConfig; + disable_3pid_login = true; + }; + }; + }; + }; + }; + + matrix-synapse = { + enable = true; + + plugins = [ matrix-synapse-ldap3 ]; + + settings = { + server_name = domainServer; + + listeners = [{ + port = 8008; + bind_addresses = [ "::1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [{ + names = [ "client" "federation" ]; + compress = false; + }]; + }]; + }; + + extraConfigFiles = [ + (pkgs.writeTextFile { + name = "matrix-synapse-extra-config.yml"; + text = let portunus = config.services.portunus; in '' + modules: + - module: ldap_auth_provider.LdapAuthProviderModule + config: + enabled: true + # have to use fqdn here for tls (still connects to localhost) + uri: ldaps://${portunus.domain}:636 + base: ou=users,${portunus.ldap.suffix} + # taken from kaki config + attributes: + uid: uid + mail: uid + name: cn + bind_dn: uid=search,ou=users,${portunus.ldap.suffix} + bind_password_file: ${config.sops.secrets.matrix_ldap_search.path} + ''; + }) + ]; + }; + }; + + systemd.services.matrix-synapse.after = [ "matrix-synapse-pgsetup.service" ]; + + systemd.services.matrix-synapse-pgsetup = { + description = "Prepare Synapse postgres database"; + wantedBy = [ "multi-user.target" ]; + after = [ "networking.target" "postgresql.service" ]; + serviceConfig.Type = "oneshot"; + + path = [ pkgs.sudo config.services.postgresql.package ]; + + # create database for synapse. will silently fail if it already exists + script = '' + sudo -u ${config.services.postgresql.superUser} psql <