at 23.11-pre 3.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.soju; 7 stateDir = "/var/lib/soju"; 8 listenCfg = concatMapStringsSep "\n" (l: "listen ${l}") cfg.listen; 9 tlsCfg = optionalString (cfg.tlsCertificate != null) 10 "tls ${cfg.tlsCertificate} ${cfg.tlsCertificateKey}"; 11 logCfg = optionalString cfg.enableMessageLogging 12 "log fs ${stateDir}/logs"; 13 14 configFile = pkgs.writeText "soju.conf" '' 15 ${listenCfg} 16 hostname ${cfg.hostName} 17 ${tlsCfg} 18 db sqlite3 ${stateDir}/soju.db 19 ${logCfg} 20 http-origin ${concatStringsSep " " cfg.httpOrigins} 21 accept-proxy-ip ${concatStringsSep " " cfg.acceptProxyIP} 22 23 ${cfg.extraConfig} 24 ''; 25in 26{ 27 ###### interface 28 29 options.services.soju = { 30 enable = mkEnableOption (lib.mdDoc "soju"); 31 32 listen = mkOption { 33 type = types.listOf types.str; 34 default = [ ":6697" ]; 35 description = lib.mdDoc '' 36 Where soju should listen for incoming connections. See the 37 `listen` directive in 38 {manpage}`soju(1)`. 39 ''; 40 }; 41 42 hostName = mkOption { 43 type = types.str; 44 default = config.networking.hostName; 45 defaultText = literalExpression "config.networking.hostName"; 46 description = lib.mdDoc "Server hostname."; 47 }; 48 49 tlsCertificate = mkOption { 50 type = types.nullOr types.path; 51 default = null; 52 example = "/var/host.cert"; 53 description = lib.mdDoc "Path to server TLS certificate."; 54 }; 55 56 tlsCertificateKey = mkOption { 57 type = types.nullOr types.path; 58 default = null; 59 example = "/var/host.key"; 60 description = lib.mdDoc "Path to server TLS certificate key."; 61 }; 62 63 enableMessageLogging = mkOption { 64 type = types.bool; 65 default = true; 66 description = lib.mdDoc "Whether to enable message logging."; 67 }; 68 69 httpOrigins = mkOption { 70 type = types.listOf types.str; 71 default = []; 72 description = lib.mdDoc '' 73 List of allowed HTTP origins for WebSocket listeners. The parameters are 74 interpreted as shell patterns, see 75 {manpage}`glob(7)`. 76 ''; 77 }; 78 79 acceptProxyIP = mkOption { 80 type = types.listOf types.str; 81 default = []; 82 description = lib.mdDoc '' 83 Allow the specified IPs to act as a proxy. Proxys have the ability to 84 overwrite the remote and local connection addresses (via the X-Forwarded-\* 85 HTTP header fields). The special name "localhost" accepts the loopback 86 addresses 127.0.0.0/8 and ::1/128. By default, all IPs are rejected. 87 ''; 88 }; 89 90 extraConfig = mkOption { 91 type = types.lines; 92 default = ""; 93 description = lib.mdDoc "Lines added verbatim to the configuration file."; 94 }; 95 }; 96 97 ###### implementation 98 99 config = mkIf cfg.enable { 100 assertions = [ 101 { 102 assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null); 103 message = '' 104 services.soju.tlsCertificate and services.soju.tlsCertificateKey 105 must both be specified to enable TLS. 106 ''; 107 } 108 ]; 109 110 systemd.services.soju = { 111 description = "soju IRC bouncer"; 112 wantedBy = [ "multi-user.target" ]; 113 after = [ "network-online.target" ]; 114 serviceConfig = { 115 DynamicUser = true; 116 Restart = "always"; 117 ExecStart = "${pkgs.soju}/bin/soju -config ${configFile}"; 118 StateDirectory = "soju"; 119 }; 120 }; 121 }; 122 123 meta.maintainers = with maintainers; [ malte-v ]; 124}