1 { config, lib, pkgs, ... }:
6 cfg = config.services.soju;
7 stateDir = "/var/lib/soju";
8 runtimeDir = "/run/soju";
10 ++ optional cfg.adminSocket.enable "unix+admin://${runtimeDir}/admin";
11 listenCfg = concatMapStringsSep "\n" (l: "listen ${l}") listen;
12 tlsCfg = optionalString (cfg.tlsCertificate != null)
13 "tls ${cfg.tlsCertificate} ${cfg.tlsCertificateKey}";
14 logCfg = optionalString cfg.enableMessageLogging
15 "log fs ${stateDir}/logs";
17 configFile = pkgs.writeText "soju.conf" ''
19 hostname ${cfg.hostName}
21 db sqlite3 ${stateDir}/soju.db
23 http-origin ${concatStringsSep " " cfg.httpOrigins}
24 accept-proxy-ip ${concatStringsSep " " cfg.acceptProxyIP}
29 sojuctl = pkgs.writeShellScriptBin "sojuctl" ''
30 exec ${cfg.package}/bin/sojuctl --config ${configFile} "$@"
36 options.services.soju = {
37 enable = mkEnableOption "soju";
39 package = mkPackageOption pkgs "soju" { };
42 type = types.listOf types.str;
43 default = [ ":6697" ];
45 Where soju should listen for incoming connections. See the
53 default = config.networking.hostName;
54 defaultText = literalExpression "config.networking.hostName";
55 description = "Server hostname.";
58 tlsCertificate = mkOption {
59 type = types.nullOr types.path;
61 example = "/var/host.cert";
62 description = "Path to server TLS certificate.";
65 tlsCertificateKey = mkOption {
66 type = types.nullOr types.path;
68 example = "/var/host.key";
69 description = "Path to server TLS certificate key.";
72 enableMessageLogging = mkOption {
75 description = "Whether to enable message logging.";
78 adminSocket.enable = mkOption {
82 Listen for admin connections from sojuctl at /run/soju/admin.
86 httpOrigins = mkOption {
87 type = types.listOf types.str;
90 List of allowed HTTP origins for WebSocket listeners. The parameters are
91 interpreted as shell patterns, see
96 acceptProxyIP = mkOption {
97 type = types.listOf types.str;
100 Allow the specified IPs to act as a proxy. Proxys have the ability to
101 overwrite the remote and local connection addresses (via the X-Forwarded-\*
102 HTTP header fields). The special name "localhost" accepts the loopback
103 addresses 127.0.0.0/8 and ::1/128. By default, all IPs are rejected.
107 extraConfig = mkOption {
110 description = "Lines added verbatim to the configuration file.";
114 ###### implementation
116 config = mkIf cfg.enable {
119 assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null);
121 services.soju.tlsCertificate and services.soju.tlsCertificateKey
122 must both be specified to enable TLS.
127 environment.systemPackages = [ sojuctl ];
129 systemd.services.soju = {
130 description = "soju IRC bouncer";
131 wantedBy = [ "multi-user.target" ];
132 wants = [ "network-online.target" ];
133 after = [ "network-online.target" ];
137 ExecStart = "${cfg.package}/bin/soju -config ${configFile}";
138 StateDirectory = "soju";
139 RuntimeDirectory = "soju";
144 meta.maintainers = with maintainers; [ malte-v ];