diff options
| author | Max Audron <audron@cocaine.farm> | 2023-10-05 11:44:40 +0200 |
|---|---|---|
| committer | Max Audron <audron@cocaine.farm> | 2023-10-05 11:44:40 +0200 |
| commit | 5e51bae86d94aac0ace303f309befa75e536d286 (patch) | |
| tree | d1a812c055f960c70cb60726786a94034ffd5b3a /modules/quassel | |
| parent | add and update servers (diff) | |
deploy teamspeak and quassel
Diffstat (limited to 'modules/quassel')
| -rw-r--r-- | modules/quassel/default.nix | 55 | ||||
| -rw-r--r-- | modules/quassel/quassel.nix | 487 |
2 files changed, 542 insertions, 0 deletions
diff --git a/modules/quassel/default.nix b/modules/quassel/default.nix new file mode 100644 index 0000000..e69d275 --- /dev/null +++ b/modules/quassel/default.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +let + quassel = pkgs.libsForQt5.callPackage ./package.nix { + tag = "-core"; + postgresql = pkgs.postgresql; + withLdap = true; + + client = false; + monolithic = false; + enableDaemon = true; + + withKDE = false; + }; +in +{ + disabledModules = + [ "services/networking/quassel.nix" ]; + imports = [ ./quassel.nix ]; + + services.quassel = { + enable = true; + configFromEnvironment = true; + # package = quassel; + settings = { + dataDir = "/var/lib/quassel"; + listen = [ "178.63.224.10" "2a01:4f8:231:56a::10" ]; + db = { + backend = "PostgreSQL"; + pgsql = { + database = "quassel"; + }; + }; + auth = { + # authenticator = "Ldap"; + ldap = { + hostname = "10.10.0.1"; + port = 389; + bindDN = "cn=quassel,ou=users,dc=quassel,dc=vapor,dc=systems"; + baseDN = "dc=quassel,dc=vapor,dc=systems"; + filter = "(objectClass=inetOrgPerson)"; + uidAttribute = "cn"; + }; + }; + }; + environmentFile = "/etc/secrets/quassel-ldap"; + }; + + secrets = { + quasselLdap = { + source = ../../secrets/authentik/quassel; + dest = "/etc/secrets/quassel-ldap"; + }; + }; +} diff --git a/modules/quassel/quassel.nix b/modules/quassel/quassel.nix new file mode 100644 index 0000000..6d259d0 --- /dev/null +++ b/modules/quassel/quassel.nix @@ -0,0 +1,487 @@ +{ config, lib, options, pkgs, ... }: + +with lib; + +let + cfg = config.services.quassel; + opt = options.services.quassel; + quassel = cfg.package; + user = if cfg.user != null then cfg.user else "quassel"; +in + +{ + options = { + services.quassel = { + enable = mkEnableOption ("the Quassel IRC client daemon"); + + package = mkOption { + type = types.package; + default = pkgs.quasselDaemon; + defaultText = literalExpression "pkgs.quasselDaemon"; + description = '' + The package of the quassel daemon. + ''; + }; + + user = mkOption { + default = null; + type = types.nullOr types.str; + description = '' + The existing user the Quassel daemon should run as. If left empty, a default "quassel" user will be created. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Path to an environment file loaded for the quassel service. + + This can be used to securely store tokens and secrets outside of the world-readable Nix store. + Since this file is read by systemd, it may have permission 0400 and be owned by root. + ''; + }; + + configFromEnvironment = mkOption { + default = false; + type = types.bool; + description = '' + Configure quassels authenticator and database settings using environment variables, + Instead of imperatively setting it up using the setup wizard during first connection to the quassel core. + ''; + }; + + settings = mkOption { + description = literalExpression '' + Configuration for quassel daemon. + ''; + type = types.submodule { + options = { + listen = mkOption { + type = types.listOf types.str; + default = [ "127.0.0.1" "::1" ]; + description = '' + The address(es) quasselcore will listen on. + ''; + }; + + port = mkOption { + default = 4242; + type = types.port; + description = '' + The port quasselcore will listen at. + ''; + }; + + dataDir = mkOption { + default = "/home/${user}/.config/quassel-irc.org"; + defaultText = literalExpression '' + "/home/''${config.${opt.user}}/.config/quassel-irc.org" + ''; + type = types.str; + description = '' + The directory holding configuration files, the SQlite database and the SSL Cert. + ''; + }; + + ident = mkOption { + description = literalExpression '' + Configuration for quassels internal ident daemon. + ''; + default = { }; + type = types.submodule { + options = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Enable internal ident daemon. + ''; + }; + + strict = mkOption { + type = types.bool; + default = false; + description = '' + Use users quasselcore username as ident reply. Ignores each user's configured ident setting. + ''; + }; + + listen = mkOption { + default = [ "127.0.0.1" "::1" ]; + type = types.listOf types.str; + description = '' + The address(es) quasselcore will listen on for ident requests. + ''; + }; + + port = mkOption { + default = 10113; + type = types.port; + description = '' + The port quasselcore will listen at for ident requests. + ''; + }; + }; + }; + }; + + oidentd = mkOption { + description = literalExpression '' + Configuration for quassels integration with oidentd. + ''; + default = { }; + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable oidentd integration. + ''; + }; + + confFile = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Set path to oidentd configuration file. + ''; + }; + }; + }; + }; + + ssl = mkOption { + default = { }; + type = types.submodule { + options = { + required = mkOption { + type = types.bool; + default = false; + description = '' + Require SSL for remote (non-loopback) client connections. + ''; + }; + + certFile = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Specify the path to the SSL certificate. + ''; + }; + + keyFile = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Specify the path to the SSL key. + ''; + }; + }; + }; + }; + + metrics = mkOption { + description = literalExpression '' + Export metrics in prometheus format + ''; + default = { }; + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable prometheus metrics API. + ''; + }; + + listen = mkOption { + default = [ "127.0.0.1" "::1" ]; + type = types.listOf types.str; + description = '' + The address(es) quasselcore will listen on for metrics requests. + ''; + }; + + port = mkOption { + default = 9558; + type = types.port; + description = '' + The port quasselcore will listen at for metrics requests. + ''; + }; + }; + }; + }; + + logLevel = mkOption { + type = types.enum [ "Debug" "Info" "Warning" "Error" ]; + default = "Info"; + description = '' + Supports one of Debug|Info|Warning|Error; + ''; + }; + + db = mkOption { + default = { }; + type = types.submodule { + options = { + backend = mkOption { + type = types.enum [ "SQLite" "PostgreSQL" ]; + default = "SQLite"; + description = literalExpression '' + Specify the database backend. + + In case SQLite is used, the database will be stored in ''${opt.settings.dataDir}/quassel-storage.sqlite + ''; + }; + + pgsql = mkOption { + description = '' + Configuration for PostgreSQL Connection if ''${opt.settings.db.type} is set to "PostgreSQL". + + TCP and UNIX Sockets are supported + ''; + default = null; + type = types.nullOr (types.submodule { + options = { + username = mkOption { + type = types.str; + default = user; + description = '' + Specifies the Postgres connection username. + ''; + }; + + password = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Specifies the Postgres connection user password. Warning: do not set confidential + information here because it is world-readable in the Nix store. + ''; + }; + + hostname = mkOption { + type = types.nullOr types.str; + default = "/var/run/postgresql/"; + description = '' + Specifies the Postgres connection hostname. + + Either an IP Address or hostname for a TCP Connection or the path to the directory + that contains a UNIX Socket. + ''; + }; + + port = mkOption { + default = 5432; + type = types.port; + description = '' + Specifies the Postgres connection port. + ''; + }; + + database = mkOption { + type = types.str; + default = "quassel"; + description = '' + Specifies the Postgres connection database name. + ''; + }; + }; + }); + }; + }; + }; + }; + + auth = mkOption { + default = { }; + type = types.submodule { + options = { + authenticator = mkOption { + type = types.enum [ "Database" "Ldap" ]; + default = "Database"; + description = '' + Specify the backend used to authenticate users to quassel. Either "Database" to + use quassel database or "Ldap" to use an external LDAP Server + ''; + }; + + ldap = mkOption { + default = null; + type = types.nullOr (types.submodule { + options = { + hostname = mkOption { + type = types.str; + description = '' + Specifies the LDAP authenticator connection hostname. + ''; + }; + + port = mkOption { + default = 389; + type = types.port; + description = '' + Specifies the LDAP authenticator connection port. + ''; + }; + + bindDN = mkOption { + type = types.str; + description = '' + Specifies the LDAP authenticator bind DN. + ''; + }; + + bindPassword = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Specifies the LDAP authenticator bind password. Warning: do not set + confidential information here because it is world-readable in the Nix store. + ''; + }; + + baseDN = mkOption { + type = types.str; + description = '' + Specifies the LDAP authenticator base DN. + ''; + }; + + filter = mkOption { + type = types.str; + description = '' + Specifies the LDAP authenticator filter. + ''; + example = "(objectClass=inetOrgPerson)"; + }; + + uidAttribute = mkOption { + default = "uid"; + type = types.str; + description = '' + Specifies the LDAP authenticator UID attribute. + ''; + example = "cn"; + }; + }; + }); + }; + }; + }; + }; + }; + }; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.settings.ssl.required -> cfg.settings.ssl.certFile != null; + message = "Quassel needs a certificate file in order to require SSL"; + } + { + assertion = cfg.settings.db.backend == "PostgreSQL" -> cfg.settings.db.pgsql != null; + message = "Quassel needs postgresql connection settings if database type is set to PostgreSQL"; + } + { + assertion = cfg.settings.auth.authenticator == "Ldap" -> cfg.settings.auth.ldap != null; + message = "Quassel needs ldap connection settings if authenticator type is set to Ldap"; + } + ]; + + users.users = optionalAttrs (cfg.user == null) { + quassel = { + name = "quassel"; + description = "Quassel IRC client daemon"; + group = "quassel"; + uid = config.ids.uids.quassel; + }; + }; + + users.groups = optionalAttrs (cfg.user == null) { + quassel = { + name = "quassel"; + gid = config.ids.gids.quassel; + }; + }; + + systemd.tmpfiles.rules = [ + "d '${cfg.settings.dataDir}' - ${user} - - -" + ]; + + systemd.services.quassel = + { + description = "Quassel IRC client daemon"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ] + ++ optional config.services.postgresql.enable "postgresql.service" + ++ optional config.services.mysql.enable "mysql.service"; + + serviceConfig = + { + ExecStart = (concatStringsSep " " ([ + "${quassel}/bin/quasselcore" + "--listen=${concatStringsSep "," cfg.settings.listen}" + "--port=${toString cfg.settings.port}" + "--configdir=${cfg.settings.dataDir}" + "--loglevel=${cfg.settings.logLevel}" + ] + ++ (optionals cfg.settings.ident.enable + [ + "--ident-daemon" + "--ident-listen=${concatStringsSep "," cfg.settings.ident.listen}" + "--ident-port=${toString cfg.settings.ident.port}" + ] ++ (optional cfg.settings.ident.strict "--strict-ident")) + ++ optionals cfg.settings.oidentd.enable [ + "--oidentd" + "--oidentd-conffile=${cfg.settings.ident.listen}" + ] + ++ optionals cfg.settings.metrics.enable [ + "--metrics-daemon" + "--metrics-listen=${concatStringsSep "," cfg.settings.metrics.listen}" + "--metrics-port=${toString cfg.settings.metrics.port}" + ] + ++ optional cfg.configFromEnvironment "--config-from-environment" + + # SSL + ++ optional cfg.settings.ssl.required "--require-ssl" + ++ optional (cfg.settings.ssl.certFile != null) "--ssl-cert=${cfg.settings.ssl.certFile}" + ++ optional (cfg.settings.ssl.keyFile != null) "--ssl-key=${cfg.settings.ssl.keyFile}" + )); + + EnvironmentFile = mkIf + (cfg.environmentFile != null) [ cfg.environmentFile ]; + Environment = mkIf cfg.configFromEnvironment ([ + "AUTH_AUTHENTICATOR=${cfg.settings.auth.authenticator}" + "DB_BACKEND=${cfg.settings.db.backend}" + ] ++ (optional (cfg.settings.db.backend == "PostgreSQL") [ + "DB_PGSQL_DATABASE=${cfg.settings.db.pgsql.database}" + "DB_PGSQL_HOSTNAME=${cfg.settings.db.pgsql.hostname}" + "DB_PGSQL_USERNAME=${cfg.settings.db.pgsql.username}" + "DB_PGSQL_PORT=${toString cfg.settings.db.pgsql.port}" + ] ++ optional (cfg.settings.db.pgsql.password != null) "DB_PGSQL_PASSWORD=${cfg.settings.db.pgsql.password}" + ) ++ (optional (cfg.settings.auth.authenticator == "Ldap") [ + "AUTH_LDAP_BASE_DN=${cfg.settings.auth.ldap.baseDN}" + "AUTH_LDAP_BIND_DN=${cfg.settings.auth.ldap.bindDN}" + "AUTH_LDAP_FILTER=${cfg.settings.auth.ldap.filter}" + "AUTH_LDAP_HOSTNAME=${cfg.settings.auth.ldap.hostname}" + "AUTH_LDAP_PORT=${toString cfg.settings.auth.ldap.port}" + "AUTH_LDAP_UID_ATTRIBUTE=${cfg.settings.auth.ldap.uidAttribute}" + ] /* ++ optional (cfg.settings.auth.ldap.bindPassword != null) "AUTH_LDAP_BIND_PASSWORD=${cfg.settings.auth.ldap.bindPassword}" */ + )); + User = user; + }; + }; + }; +} |
