diff --git a/hosts/buskerud/configuration.nix b/hosts/buskerud/configuration.nix index 14eec65..990e063 100644 --- a/hosts/buskerud/configuration.nix +++ b/hosts/buskerud/configuration.nix @@ -4,6 +4,8 @@ ./hardware-configuration.nix ../../base.nix ../../misc/metrics-exporters.nix + + ./containers/salsa/configuration.nix ]; # buskerud does not support efi? diff --git a/hosts/buskerud/containers/salsa/NOTES.md b/hosts/buskerud/containers/salsa/NOTES.md new file mode 100644 index 0000000..e5840ee --- /dev/null +++ b/hosts/buskerud/containers/salsa/NOTES.md @@ -0,0 +1,27 @@ +# Misc docs + +### Old stuff about storing kerberos state inside LDAP - might not be relevant + +- https://wiki.debian.org/LDAP/OpenLDAPSetup#OpenLDAP_as_a_Backend +- https://ubuntu.com/server/docs/service-kerberos-with-openldap-backend +- https://forums.freebsd.org/threads/heimdal-and-openldap-integration-some-questions.58422/ +- http://osr507doc.sco.com/cgi-bin/info2html?(heimdal.info.gz)Using%2520LDAP%2520to%2520store%2520the%2520database&lang=en +- https://bbs.archlinux.org/viewtopic.php?id=54236 +- https://openldap-software.0penldap.narkive.com/Ml6seAGL/ldap-backend-for-heimdal-kerberos + +### Heimdal setup + +- http://chschneider.eu/linux/server/heimdal.shtml +- https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/kerberos/heimdal.nix +- https://itk.samfundet.no/dok/Kerberos (possibly a bit dated) + +### OpenLDAP setup with new olc stuff + +- https://www.openldap.org/doc/admin26/ +- https://www.openldap.org/doc/admin26/sasl.html#GSSAPI +- https://www.zytrax.com/books/ldap/ + +### SASLAUTHD + +- https://linux.die.net/man/8/saslauthd +- https://www.cyrusimap.org/sasl/index.html diff --git a/hosts/buskerud/containers/salsa/configuration.nix b/hosts/buskerud/containers/salsa/configuration.nix new file mode 100644 index 0000000..4f82876 --- /dev/null +++ b/hosts/buskerud/containers/salsa/configuration.nix @@ -0,0 +1,41 @@ +{ config, pkgs, lib, inputs, values, ... }: +{ + containers.salsa = { + autoStart = true; + interfaces = [ "enp6s0f1" ]; + bindMounts = { + "/data" = { hostPath = "/data/salsa"; isReadOnly = false; }; + }; + + config = { config, pkgs, ... }: let + inherit values inputs; + in { + imports = [ + inputs.sops-nix.nixosModules.sops + ../../../../base.nix + + ./services/heimdal + ./services/openldap.nix + ./services/saslauthd.nix + ]; + + _module.args = { + inherit values inputs; + }; + + sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + sops.age.keyFile = "/var/lib/sops-nix/key.txt"; + sops.age.generateKey = true; + + # systemd.network.networks."30-enp6s0f1" = values.defaultNetworkConfig // { + # matchConfig.Name = "enp6s0f1"; + # address = with values.hosts.jokum; [ (ipv4 + "/25") (ipv6 + "/64") ] + # ++ (with values.services.turn; [ (ipv4 + "/25") (ipv6 + "/64") ]); + # }; + + networking.useHostResolvConf = lib.mkForce false; + + system.stateVersion = "23.11"; + }; + }; +} diff --git a/hosts/buskerud/containers/salsa/services/heimdal/default.nix b/hosts/buskerud/containers/salsa/services/heimdal/default.nix new file mode 100644 index 0000000..73b944d --- /dev/null +++ b/hosts/buskerud/containers/salsa/services/heimdal/default.nix @@ -0,0 +1,72 @@ +{ pkgs, ... }: +let + # NOTE: This has a small edit that moves an include header to $dev/include. + # It is required in order to build smbk5pwd, because of some nested includes. + # We should open an issue upstream (heimdal, not nixpkgs), but this patch + # will do for now. + package = pkgs.callPackage ./package.nix { }; + + realm = "PVV.NTNU.NO" +in +{ + security.krb5 = { + enable = true; + kerberos = package; + + settings = { + logging.kdc = "CONSOLE"; + realms.${realm} = { + admin_server = "localhost"; + kdc = [ "localhost" ]; + }; + + kadmin.default_keys = lib.concatStringsSep " " [ + "aes256-cts-hmac-sha1-96:pw-salt" + "aes128-cts-hmac-sha1-96:pw-salt" + ]; + + libdefaults.default_etypes = lib.concatStringsSep " " [ + "aes256-cts-hmac-sha1-96" + "aes128-cts-hmac-sha1-96" + ]; + + libdefaults = { + default_realm = realm; + }; + + domain_realm = { + "pvv.ntnu.no" = realm; + ".pvv.ntnu.no" = realm; + }; + }; + }; + + services.kerberos_server = { + enable = true; + settings = { + realms.${realm} = { + dbname = "/var/heimdal/heimdal"; + mkey = "/var/heimdal/mkey"; + }; + kadmin.default_keys = lib.concatStringsSep " " [ + "aes256-cts-hmac-sha1-96:pw-salt" + "aes128-cts-hmac-sha1-96:pw-salt" + ]; + + libdefaults.default_etypes = lib.concatStringsSep " " [ + "aes256-cts-hmac-sha1-96" + "aes128-cts-hmac-sha1-96" + ]; + + password_quality.min_length = 8; + }; + }; + + # NOTE: These changes are part of nixpkgs-unstable, but not 23.11. + # The package override needs these changes. + systemd.services = { + kdc.serviceConfig.ExecStart = lib.mkForce "${config.security.krb5.kerberos}/libexec/kadmind --config-file=/etc/heimdal-kdc/kdc.conf"; + kpasswdd.serviceConfig.ExecStart = lib.mkForce "${config.security.krb5.kerberos}/libexec/kpasswdd"; + kadmind.serviceConfig.ExecStart = lib.mkForce "${config.security.krb5.kerberos}/libexec/kdc --config-file=/etc/heimdal-kdc/kdc.conf"; + }; +} diff --git a/hosts/buskerud/containers/salsa/services/heimdal/package.nix b/hosts/buskerud/containers/salsa/services/heimdal/package.nix new file mode 100644 index 0000000..af8fe33 --- /dev/null +++ b/hosts/buskerud/containers/salsa/services/heimdal/package.nix @@ -0,0 +1,180 @@ +{ lib +, stdenv +, fetchFromGitHub +, autoreconfHook +, pkg-config +, python3 +, perl +, bison +, flex +, texinfo +, perlPackages + +, openldap +, libcap_ng +, sqlite +, openssl +, db +, libedit +, pam +, krb5 +, libmicrohttpd +, cjson + +, CoreFoundation +, Security +, SystemConfiguration + +, curl +, jdk +, unzip +, which + +, nixosTests + +, withCJSON ? true +, withCapNG ? stdenv.isLinux +# libmicrohttpd should theoretically work for darwin as well, but something is broken. +# It affects tests check-bx509d and check-httpkadmind. +, withMicroHTTPD ? stdenv.isLinux +, withOpenLDAP ? true +, withOpenLDAPAsHDBModule ? false +, withOpenSSL ? true +, withSQLite3 ? true +}: + +assert lib.assertMsg (withOpenLDAPAsHDBModule -> withOpenLDAP) '' + OpenLDAP needs to be enabled in order to build the OpenLDAP HDB Module. +''; + +stdenv.mkDerivation { + pname = "heimdal"; + version = "7.8.0-unstable-2023-11-29"; + + src = fetchFromGitHub { + owner = "heimdal"; + repo = "heimdal"; + rev = "3253c49544eacb33d5ad2f6f919b0696e5aab794"; + hash = "sha256-uljzQBzXrZCZjcIWfioqHN8YsbUUNy14Vo+A3vZIXzM="; + }; + + outputs = [ "out" "dev" "man" "info" ]; + + nativeBuildInputs = [ + autoreconfHook + pkg-config + python3 + perl + bison + flex + texinfo + ] + ++ (with perlPackages; [ JSON ]); + + buildInputs = [ db libedit pam ] + ++ lib.optionals (stdenv.isDarwin) [ CoreFoundation Security SystemConfiguration ] + ++ lib.optionals (withCJSON) [ cjson ] + ++ lib.optionals (withCapNG) [ libcap_ng ] + ++ lib.optionals (withMicroHTTPD) [ libmicrohttpd ] + ++ lib.optionals (withOpenLDAP) [ openldap ] + ++ lib.optionals (withOpenSSL) [ openssl ] + ++ lib.optionals (withSQLite3) [ sqlite ]; + + doCheck = true; + nativeCheckInputs = [ + curl + jdk + unzip + which + ]; + + configureFlags = [ + "--with-libedit-include=${libedit.dev}/include" + "--with-libedit-lib=${libedit}/lib" + "--with-berkeley-db-include=${db.dev}/include" + "--with-berkeley-db" + + "--without-x" + "--disable-afs-string-to-key" + ] ++ lib.optionals (withCapNG) [ + "--with-capng" + ] ++ lib.optionals (withCJSON) [ + "--with-cjson=${cjson}" + ] ++ lib.optionals (withOpenLDAP) [ + "--with-openldap=${openldap.dev}" + ] ++ lib.optionals (withOpenLDAPAsHDBModule) [ + "--enable-hdb-openldap-module" + ] ++ lib.optionals (withSQLite3) [ + "--with-sqlite3=${sqlite.dev}" + ]; + + # (check-ldap) slapd resides within ${openldap}/libexec, + # which is not part of $PATH by default. + # (check-ldap) prepending ${openldap}/bin to the path to avoid + # using the default installation of openldap on unsandboxed darwin systems, + # which does not support the new mdb backend at the moment (2024-01-13). + # (check-ldap) the bdb backend got deprecated in favour of mdb in openldap 2.5.0, + # but the heimdal tests still seem to expect bdb as the openldap backend. + # This might be fixed upstream in a future update. + patchPhase = '' + runHook prePatch + + substituteInPlace tests/ldap/slapd-init.in \ + --replace 'SCHEMA_PATHS="' 'SCHEMA_PATHS="${openldap}/etc/schema ' + substituteInPlace tests/ldap/check-ldap.in \ + --replace 'PATH=' 'PATH=${openldap}/libexec:${openldap}/bin:' + substituteInPlace tests/ldap/slapd.conf \ + --replace 'database bdb' 'database mdb' + + runHook postPatch + ''; + + # (test_cc) heimdal uses librokens implementation of `secure_getenv` on darwin, + # which expects either USER or LOGNAME to be set. + preCheck = lib.optionalString (stdenv.isDarwin) '' + export USER=nix-builder + ''; + + # We need to build hcrypt for applications like samba + postBuild = '' + (cd include/hcrypto; make -j $NIX_BUILD_CORES) + (cd lib/hcrypto; make -j $NIX_BUILD_CORES) + ''; + + postInstall = '' + # Install hcrypto + (cd include/hcrypto; make -j $NIX_BUILD_CORES install) + (cd lib/hcrypto; make -j $NIX_BUILD_CORES install) + + mkdir -p $dev/bin + mv $out/bin/krb5-config $dev/bin/ + + # asn1 compilers, move them to $dev + mv $out/libexec/heimdal/* $dev/bin + rmdir $out/libexec/heimdal + + cp include/heim_threads.h $dev/include + + # compile_et is needed for cross-compiling this package and samba + mv lib/com_err/.libs/compile_et $dev/bin + ''; + + # Issues with hydra + # In file included from hxtool.c:34:0: + # hx_locl.h:67:25: fatal error: pkcs10_asn1.h: No such file or directory + #enableParallelBuilding = true; + + passthru = { + implementation = "heimdal"; + tests.nixos = nixosTests.kerberos.heimdal; + }; + + meta = with lib; { + homepage = "https://www.heimdal.software"; + changelog = "https://github.com/heimdal/heimdal/releases"; + description = "An implementation of Kerberos 5 (and some more stuff)"; + license = licenses.bsd3; + platforms = platforms.unix; + maintainers = with maintainers; [ h7x4 ]; + }; +} diff --git a/hosts/buskerud/containers/salsa/services/openldap.nix b/hosts/buskerud/containers/salsa/services/openldap.nix new file mode 100644 index 0000000..c01092e --- /dev/null +++ b/hosts/buskerud/containers/salsa/services/openldap.nix @@ -0,0 +1,115 @@ +{ config, pkgs, lib, ... }: +{ + services.openldap = let + dn = "dc=kerberos,dc=pvv,dc=ntnu,dc=no"; + cfg = config.services.openldap; + in { + enable = true; + + # NOTE: this is a custom build of openldap with support for + # perl and kerberos. + package = pkgs.openldap.overrideAttrs (prev: { + # https://github.com/openldap/openldap/blob/master/configure + configureFlags = prev.configureFlags ++ [ + # Connect to slapd via UNIX socket + "--enable-local" + # Cyrus SASL + "--enable-spasswd" + # Reverse hostname lookups + "--enable-rlookups" + # perl + "--enable-perl" + ]; + + buildInputs = prev.buildInputs ++ (with pkgs; [ + perl + config.security.krb5.kerberos + ]); + + extraContribModules = prev.extraContribModules ++ [ + # https://git.openldap.org/openldap/openldap/-/tree/master/contrib/slapd-modules + "smbk5pwd" + ]; + }); + + settings = { + attrs = { + olcLogLevel = [ "stats" "config" "args" ]; + + # olcAuthzRegexp = '' + # gidNumber=.*\\\+uidNumber=0,cn=peercred,cn=external,cn=auth + # "uid=heimdal,${dn2}" + # ''; + + # olcSaslSecProps = "minssf=0"; + }; + + children = { + "cn=schema".includes = let + # NOTE: needed for smbk5pwd.so module + # schemaToLdif = name: path: pkgs.runCommandNoCC name { + # buildInputs = with pkgs; [ schema2ldif ]; + # } '' + # schema2ldif "${path}" > $out + # ''; + + # hdb-ldif = schemaToLdif "hdb.ldif" "${pkgs.heimdal.src}/lib/hdb/hdb.schema"; + # samba-ldif = schemaToLdif "samba.ldif" "${pkgs.heimdal.src}/tests/ldap/samba.schema"; + in [ + "${cfg.package}/etc/schema/core.ldif" + "${cfg.package}/etc/schema/cosine.ldif" + "${cfg.package}/etc/schema/nis.ldif" + "${cfg.package}/etc/schema/inetorgperson.ldif" + # "${hdb-ldif}" + # "${samba-ldif}" + ]; + + # NOTE: installation of smbk5pwd.so module + # https://git.openldap.org/openldap/openldap/-/tree/master/contrib/slapd-modules/smbk5pwd + # "cn=module{0}".attrs = { + # objectClass = [ "olcModuleList" ]; + # olcModuleLoad = [ "${cfg.package}/lib/modules/smbk5pwd.so" ]; + # }; + + # NOTE: activation of smbk5pwd.so module for {1}mdb + # "olcOverlay={0}smbk5pwd,olcDatabase={1}mdb".attrs = { + # objectClass = [ "olcOverlayConfig" "olcSmbK5PwdConfig" ]; + # olcOverlay = "{0}smbk5pwd"; + # olcSmbK5PwdEnable = [ "krb5" "samba" ]; + # olcSmbK5PwdMustChange = toString (60 * 60 * 24 * 30); + # }; + + "olcDatabase={1}mdb".attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + + olcDatabase = "{1}mdb"; + + olcSuffix = dn; + + # TODO: PW is supposed to be a secret, but it's probably fine for testing + olcRootDN = "cn=admin,${dn}"; + olcRootPW.path = pkgs.writeText "olcRootPW" "pass"; + + olcDbDirectory = "/var/lib/openldap/test-db"; + olcDbIndex = "objectClass eq"; + + olcAccess = [ + ''{0}to attrs=userPassword,shadowLastChange + by dn.exact=cn=admin,${dn} write + by self write + by anonymous auth + by * none'' + + ''{1}to dn.base="" + by * read'' + + /* allow read on anything else */ + # ''{2}to * + # by cn=admin,${dn} write by dn.exact=gidNumber=0+uidNumber=0+cn=peercred,cn=external write + # by * read'' + ]; + }; + }; + }; + }; +} diff --git a/hosts/buskerud/containers/salsa/services/saslauthd.nix b/hosts/buskerud/containers/salsa/services/saslauthd.nix new file mode 100644 index 0000000..19174f2 --- /dev/null +++ b/hosts/buskerud/containers/salsa/services/saslauthd.nix @@ -0,0 +1,14 @@ +{ ... }: +{ + # TODO: This is seemingly required for openldap to authenticate + # against kerberos, but I have no idea how to configure it as + # such. Does it need a keytab? There's a binary "testsaslauthd" + # that follows with `pkgs.cyrus_sasl` that might be useful. + services.saslauthd = { + enable = true; + mechanism = "kerberos5"; + # config = '' + + # ''; + }; +}