aboutsummaryrefslogtreecommitdiff
path: root/modules/services/soju
diff options
context:
space:
mode:
Diffstat (limited to 'modules/services/soju')
-rw-r--r--modules/services/soju/_soju-module.nix132
-rw-r--r--modules/services/soju/default.nix48
2 files changed, 180 insertions, 0 deletions
diff --git a/modules/services/soju/_soju-module.nix b/modules/services/soju/_soju-module.nix
new file mode 100644
index 0000000..d14082c
--- /dev/null
+++ b/modules/services/soju/_soju-module.nix
@@ -0,0 +1,132 @@
+# Not an overlay, module replacement
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.soju;
+ stateDir = "/var/lib/soju";
+ listenCfg = concatMapStringsSep "\n" (l: "listen ${l}") cfg.listen;
+ tlsCfg = optionalString (cfg.tlsCertificate != null)
+ "tls ${cfg.tlsCertificate} ${cfg.tlsCertificateKey}";
+ logCfg = optionalString cfg.enableMessageLogging
+ "log fs ${stateDir}/logs";
+
+ configFile = pkgs.writeText "soju.conf" ''
+ ${listenCfg}
+ hostname ${cfg.hostName}
+ ${tlsCfg}
+ db sqlite3 ${stateDir}/soju.db
+ ${logCfg}
+ http-origin ${concatStringsSep " " cfg.httpOrigins}
+ accept-proxy-ip ${concatStringsSep " " cfg.acceptProxyIP}
+
+ ${cfg.extraConfig}
+ '';
+in
+{
+ ###### interface
+
+ options.services.soju = {
+ enable = mkEnableOption (lib.mdDoc "soju");
+
+ listen = mkOption {
+ type = types.listOf types.str;
+ default = [ ":6697" ];
+ description = lib.mdDoc ''
+ Where soju should listen for incoming connections. See the
+ `listen` directive in
+ {manpage}`soju(1)`.
+ '';
+ };
+
+ hostName = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ defaultText = literalExpression "config.networking.hostName";
+ description = lib.mdDoc "Server hostname.";
+ };
+
+ tlsCertificate = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/var/host.cert";
+ description = lib.mdDoc "Path to server TLS certificate.";
+ };
+
+ tlsCertificateKey = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/var/host.key";
+ description = lib.mdDoc "Path to server TLS certificate key.";
+ };
+
+ enableMessageLogging = mkOption {
+ type = types.bool;
+ default = true;
+ description = lib.mdDoc "Whether to enable message logging.";
+ };
+
+ httpOrigins = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = lib.mdDoc ''
+ List of allowed HTTP origins for WebSocket listeners. The parameters are
+ interpreted as shell patterns, see
+ {manpage}`glob(7)`.
+ '';
+ };
+
+ acceptProxyIP = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = lib.mdDoc ''
+ Allow the specified IPs to act as a proxy. Proxys have the ability to
+ overwrite the remote and local connection addresses (via the X-Forwarded-\*
+ HTTP header fields). The special name "localhost" accepts the loopback
+ addresses 127.0.0.0/8 and ::1/128. By default, all IPs are rejected.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = lib.mdDoc "Lines added verbatim to the configuration file.";
+ };
+
+ extraGroups = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = lib.mdDoc "Extra groups for the dynamic user.";
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null);
+ message = ''
+ services.soju.tlsCertificate and services.soju.tlsCertificateKey
+ must both be specified to enable TLS.
+ '';
+ }
+ ];
+
+ systemd.services.soju = {
+ description = "soju IRC bouncer";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-online.target" ];
+ serviceConfig = {
+ DynamicUser = true;
+ SupplementaryGroups = cfg.extraGroups;
+ Restart = "always";
+ ExecStart = "${pkgs.soju}/bin/soju -config ${configFile}";
+ StateDirectory = "soju";
+ };
+ };
+ };
+
+ meta.maintainers = with maintainers; [ malvo ];
+}
diff --git a/modules/services/soju/default.nix b/modules/services/soju/default.nix
new file mode 100644
index 0000000..557222e
--- /dev/null
+++ b/modules/services/soju/default.nix
@@ -0,0 +1,48 @@
+{ config, lib, ... }:
+
+with lib;
+let
+ cfg = config.modules.services.soju;
+in
+{
+ disabledModules = [
+ "services/networking/soju.nix"
+ ];
+
+ imports = [
+ ./_soju-module.nix
+ ];
+
+ options.modules.services.soju = {
+ enable = mkEnableOption "soju bouncer";
+
+ hostName = mkOption { type = types.str; default = config.networking.hostName; };
+ port = mkOption { type = types.port; default = 6697; };
+ tls = {
+ enable = mkEnableOption "enable TLS encryption";
+ acmeHost = mkOption { type = types.str; };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.soju = {
+ enable = true;
+ extraGroups = [ "acme" ];
+ hostName = cfg.hostName;
+ listen = [ ":${toString cfg.port}" ];
+ } // optionalAttrs cfg.tls.enable {
+ tlsCertificate = "${config.security.acme.certs.${cfg.tls.acmeHost}.directory}/cert.pem";
+ tlsCertificateKey = "${config.security.acme.certs.${cfg.tls.acmeHost}.directory}/key.pem";
+ };
+
+ systemd.services.soju = {
+ after = [ "acme-finished-${cfg.tls.acmeHost}.target" ];
+ };
+
+ networking.firewall.allowedTCPPorts = [ cfg.port ];
+
+ modules.persistence.directories = [
+ "/var/lib/private/soju"
+ ];
+ };
+}