From 1a64deeb894dc95e2645a75771732c6cc53a79ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Wed, 4 Oct 2023 01:35:06 +0200 Subject: Squash changes containing private information There were a lot of changes since the previous commit, but a lot of them contained personnal information about users. All thos changes got stashed into a single commit (history is kept in a different place) and private information was moved in a separate private repository --- systems/eldiron/databases/openldap/default.nix | 304 +++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 systems/eldiron/databases/openldap/default.nix (limited to 'systems/eldiron/databases/openldap') diff --git a/systems/eldiron/databases/openldap/default.nix b/systems/eldiron/databases/openldap/default.nix new file mode 100644 index 0000000..7cd15da --- /dev/null +++ b/systems/eldiron/databases/openldap/default.nix @@ -0,0 +1,304 @@ +{ lib, pkgs, config, openldap, ... }: +let + cfg = config.myServices.databases.openldap; +in +{ + options.myServices.databases = { + openldap = { + enable = lib.mkOption { + default = false; + example = true; + description = "Whether to enable ldap"; + type = lib.types.bool; + }; + baseDn = lib.mkOption { + type = lib.types.str; + description = '' + Base DN for LDAP + ''; + }; + rootDn = lib.mkOption { + type = lib.types.str; + description = '' + Root DN + ''; + }; + rootPw = lib.mkOption { + type = lib.types.str; + description = '' + Root (Hashed) password + ''; + }; + accessFile = lib.mkOption { + type = lib.types.path; + description = '' + The file path that defines the access + ''; + }; + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/openldap/mdb"; + description = '' + The directory where Openldap stores its data. + ''; + }; + socketsDir = lib.mkOption { + type = lib.types.path; + default = "/run/openldap"; + description = '' + The directory where Openldap puts sockets and pid files. + ''; + }; + # Output variables + pids = lib.mkOption { + type = lib.types.attrsOf lib.types.path; + default = { + pid = "${cfg.socketsDir}/slapd.pid"; + args = "${cfg.socketsDir}/slapd.args"; + }; + readOnly = true; + description = '' + Slapd pid files + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + myServices.dns.zones."immae.eu".subdomains.ldap = + with config.myServices.dns.helpers; ips servers.eldiron.ips.main; + + nixpkgs.overlays = [ + (self: super: { + openldap_libressl_cyrus = (self.openldap.override { + openssl = self.libressl; + cyrus_sasl = self.cyrus_sasl.overrideAttrs (old: { + configureFlags = old.configureFlags ++ [ "--with-configdir=/etc/sasl2" ]; + }); + }).overrideAttrs (old: { + configureFlags = old.configureFlags ++ [ "--with-cyrus-sasl" "--enable-spasswd" ]; + }); + }) + ]; + + secrets.keys = { + "ldap/password" = { + permissions = "0400"; + user = "openldap"; + group = "openldap"; + text = "${cfg.rootPw}"; + }; + "ldap/access" = { + permissions = "0400"; + user = "openldap"; + group = "openldap"; + text = builtins.readFile cfg.accessFile; + }; + "ldap" = { + permissions = "0500"; + user = "openldap"; + group = "openldap"; + isDir = true; + }; + }; + users.users.openldap.extraGroups = [ "keys" ]; + networking.firewall.allowedTCPPorts = [ 636 389 ]; + + security.acme.certs."ldap" = { + group = "openldap"; + domain = "ldap.immae.eu"; + postRun = '' + systemctl restart openldap.service + ''; + }; + + services.filesWatcher.openldap = { + restart = true; + paths = [ config.secrets.fullPaths."ldap" ]; + }; + + services.openldap = { + enable = true; + urlList = [ "ldap://" "ldaps://" ]; + package = pkgs.openldap_libressl_cyrus; + settings = { + attrs = { + olcPidFile = cfg.pids.pid; + olcArgsFile = cfg.pids.args; + olcLogLevel = "none"; + olcTLSCertificateFile = "${config.security.acme.certs.ldap.directory}/cert.pem"; + olcTLSCertificateKeyFile = "${config.security.acme.certs.ldap.directory}/key.pem"; + olcTLSCACertificateFile = "${config.security.acme.certs.ldap.directory}/fullchain.pem"; + olcTLSCACertificatePath = "${pkgs.cacert.unbundled}/etc/ssl/certs/"; + # This makes openldap crash + # olcTLSCipherSuite = "DEFAULT"; + #olcSaslHost = "kerberos.immae.eu"; + # Map sasl "dn" to ldap dn + #olcAuthzRegexp = ''{0}"uid=([^,]*)(,cn=IMMAE.EU)?,cn=(gssapi|gss-spnego),cn=auth" "uid=$1,ou=users,dc=immae,dc=eu"''; + }; + children = { + "cn=module{0}" = { + attrs = { + cn = "module{0}"; + objectClass = [ "olcModuleList" ]; + olcModuleLoad = [ "{0}back_mdb" "{1}memberof" "{2}syncprov" ]; + }; + }; + "cn=schema".includes = map (schema: + "${config.services.openldap.package}/etc/schema/${schema}.ldif" + ) [ "core" "cosine" "inetorgperson" "nis" ] ++ [ + "${openldap.immae-ldif}" + ]; + "olcDatabase={0}config" = { + attrs = { + objectClass = "olcDatabaseConfig"; + olcDatabase = "{0}config"; + olcAccess = ["{0}to * by * none"]; + }; + }; + "olcDatabase={1}mdb" = { + attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + olcDatabase = "{1}mdb"; + olcDbIndex = [ + "objectClass eq" + "uid pres,eq" + "mail pres,eq,sub" + "cn pres,eq,sub" + "sn pres,eq,sub" + "dc eq" + "member eq" + "memberOf eq" + ]; + olcAccess = let + join = builtins.replaceStrings ["\n"] [" "]; + in [ + # First matching "to" + "by" wins + #### Replication needs full access + (join ''{0}to * + by dn.base="uid=ldap_replication,cn=ldap,ou=services,dc=immae,dc=eu" read + by * break + '') + #### Prevent modification of SASL passwords + (join ''{1}to attrs=userPassword val.regex="^.SASL..+" + by self read + by anonymous auth + by * none + '') + #### Oneself needs access to users password + (join ''{2}to attrs=userPassword,shadowLastChange + by self write + by anonymous auth + by * none + '') + #### Should be write, but disabled during migration to psql + (join ''{3}to attrs=immaeSshKey + by self read + by * break + '') + + #### Anyone can auth, and I can see myself + (join ''{4}to * + by self read + by anonymous auth + by * break + '') + + #### Specific access for phpldapadmin + (join ''{5}to filter="(uid=*)" attrs=entry,uid + by dn.base="cn=phpldapadmin,ou=services,dc=immae,dc=eu" read + by * break + '') + + #### Hosts + # The attributes are available to every host + (join ''{6}to dn.one="ou=hosts,dc=immae,dc=eu" + by dn.subtree="ou=hosts,dc=immae,dc=eu" read + by dn.base="dc=immae,dc=eu" search + by * break + '') + #### /Hosts + + #### Local services + # this/-* & user : all your ancestors have access to you + # this/memberOf/-* & user : all those whom you belong to (in a group), + # and their ancestors, have access to you + # user/immaeAccessWriteDn*/member & this : you have write access to the + # members of your immaeAccessDn + # attributes + # user/immaeAccessDn*/member & this : you have access to the members + # of your immaeAccessDn attributes + # user/immaeAccessReadSubtree* & this/-* : you have access to the + # childrens of your immaeAccessReadSubtree + # attributes + # this/memberOf/-* & user/immaeAccessReadSubtree*: you have access to + # the members of the childrens of your + # immaeAccessReadSubtree attributes + # http://www.openldap.org/faq/data/cache/1133.html + (join ''{7}to dn.subtree="dc=immae,dc=eu" + by dn.subtree="ou=external_services,dc=immae,dc=eu" break + by set.exact="this/-* & user" read + by set.exact="this/memberOf/-* & user" read + by set.exact="user/immaeAccessWriteDn*/member & this" write + by set.exact="user/immaeAccessDn*/member & this" read + by set.exact="user/immaeAccessReadSubtree* & this/-*" read + by set.exact="this/memberOf/-* & user/immaeAccessReadSubtree*" read + by users search + by * break + '') + #### /Local services + + #### External services + # http://www.openldap.org/faq/data/cache/429.html + # FIXME: Find a way to whitelist? + (join ''{8}to attrs=immaeSshKey + by dn.subtree="ou=external_services,dc=immae,dc=eu" none + '') + (join ''{9}to dn.subtree="dc=immae,dc=eu" + by set.exact="this/-* & user" read + by set.exact="this/memberOf/-* & user" read + by set.exact="user/immaeAccessDn*/member & this/-*" read + by users search + by * none + '') + #### /External services + ]; + olcDbDirectory = cfg.dataDir; + olcRootDN = cfg.rootDn; + olcRootPW.path = config.secrets.fullPaths."ldap/password"; + olcSuffix = cfg.baseDn; + }; + children = { + "olcOverlay={0}memberof" = { + attrs = { + objectClass = [ "olcOverlayConfig" "olcMemberOf" ]; + olcOverlay = "{0}memberof"; + }; + }; + "olcOverlay={1}syncprov" = { + attrs = { + objectClass = [ "olcOverlayConfig" "olcSyncProvConfig" ]; + olcOverlay = "{1}syncprov"; + olcSpCheckpoint = "100 10"; + }; + }; + }; + }; + }; + }; + }; + myServices.monitoring.fromMasterActivatedPlugins = [ "tcp" ]; + myServices.monitoring.fromMasterObjects.service = [ + { + service_description = "ldap SSL is up to date"; + host_name = config.hostEnv.fqdn; + use = "external-service"; + check_command = ["check_tcp_ssl" "636"]; + + servicegroups = "webstatus-ssl"; + _webstatus_name = "LDAP"; + _webstatus_url = "ldap.immae.eu"; + } + ]; + }; +} -- cgit v1.2.3