1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.murmur; 7 configFile = pkgs.writeText "murmurd.ini" '' 8 database=/var/lib/murmur/murmur.sqlite 9 dbDriver=QSQLITE 10 11 autobanAttempts=${toString cfg.autobanAttempts} 12 autobanTimeframe=${toString cfg.autobanTimeframe} 13 autobanTime=${toString cfg.autobanTime} 14 15 logfile=/var/log/murmur/murmurd.log 16 pidfile=${cfg.pidfile} 17 18 welcome="${cfg.welcome}" 19 port=${toString cfg.port} 20 21 ${if cfg.hostName == "" then "" else "host="+cfg.hostName} 22 ${if cfg.password == "" then "" else "serverpassword="+cfg.password} 23 24 bandwidth=${toString cfg.bandwidth} 25 users=${toString cfg.users} 26 27 textmessagelength=${toString cfg.textMsgLength} 28 imagemessagelength=${toString cfg.imgMsgLength} 29 allowhtml=${if cfg.allowHtml then "true" else "false"} 30 logdays=${toString cfg.logDays} 31 bonjour=${if cfg.bonjour then "true" else "false"} 32 sendversion=${if cfg.sendVersion then "true" else "false"} 33 34 ${if cfg.registerName == "" then "" else "registerName="+cfg.registerName} 35 ${if cfg.registerPassword == "" then "" else "registerPassword="+cfg.registerPassword} 36 ${if cfg.registerUrl == "" then "" else "registerUrl="+cfg.registerUrl} 37 ${if cfg.registerHostname == "" then "" else "registerHostname="+cfg.registerHostname} 38 39 certrequired=${if cfg.clientCertRequired then "true" else "false"} 40 ${if cfg.sslCert == "" then "" else "sslCert="+cfg.sslCert} 41 ${if cfg.sslKey == "" then "" else "sslKey="+cfg.sslKey} 42 ${if cfg.sslCa == "" then "" else "sslCA="+cfg.sslCa} 43 44 ${cfg.extraConfig} 45 ''; 46in 47{ 48 options = { 49 services.murmur = { 50 enable = mkOption { 51 type = types.bool; 52 default = false; 53 description = "If enabled, start the Murmur Service."; 54 }; 55 56 autobanAttempts = mkOption { 57 type = types.int; 58 default = 10; 59 description = '' 60 Number of attempts a client is allowed to make in 61 <literal>autobanTimeframe</literal> seconds, before being 62 banned for <literal>autobanTime</literal>. 63 ''; 64 }; 65 66 autobanTimeframe = mkOption { 67 type = types.int; 68 default = 120; 69 description = '' 70 Timeframe in which a client can connect without being banned 71 for repeated attempts (in seconds). 72 ''; 73 }; 74 75 autobanTime = mkOption { 76 type = types.int; 77 default = 300; 78 description = "The amount of time an IP ban lasts (in seconds)."; 79 }; 80 81 pidfile = mkOption { 82 type = types.path; 83 default = "/tmp/murmurd.pid"; 84 description = "Path to PID file for Murmur daemon."; 85 }; 86 87 welcome = mkOption { 88 type = types.str; 89 default = ""; 90 description = "Welcome message for connected clients."; 91 }; 92 93 port = mkOption { 94 type = types.int; 95 default = 64738; 96 description = "Ports to bind to (UDP and TCP)."; 97 }; 98 99 hostName = mkOption { 100 type = types.str; 101 default = ""; 102 description = "Host to bind to. Defaults binding on all addresses."; 103 }; 104 105 password = mkOption { 106 type = types.str; 107 default = ""; 108 description = "Required password to join server, if specified."; 109 }; 110 111 bandwidth = mkOption { 112 type = types.int; 113 default = 72000; 114 description = '' 115 Maximum bandwidth (in bits per second) that clients may send 116 speech at. 117 ''; 118 }; 119 120 users = mkOption { 121 type = types.int; 122 default = 100; 123 description = "Maximum number of concurrent clients allowed."; 124 }; 125 126 textMsgLength = mkOption { 127 type = types.int; 128 default = 5000; 129 description = "Max length of text messages. Set 0 for no limit."; 130 }; 131 132 imgMsgLength = mkOption { 133 type = types.int; 134 default = 131072; 135 description = "Max length of image messages. Set 0 for no limit."; 136 }; 137 138 allowHtml = mkOption { 139 type = types.bool; 140 default = true; 141 description = '' 142 Allow HTML in client messages, comments, and channel 143 descriptions. 144 ''; 145 }; 146 147 logDays = mkOption { 148 type = types.int; 149 default = 31; 150 description = '' 151 How long to store RPC logs for in the database. Set 0 to 152 keep logs forever, or -1 to disable DB logging. 153 ''; 154 }; 155 156 bonjour = mkOption { 157 type = types.bool; 158 default = false; 159 description = '' 160 Enable Bonjour auto-discovery, which allows clients over 161 your LAN to automatically discover Murmur servers. 162 ''; 163 }; 164 165 sendVersion = mkOption { 166 type = types.bool; 167 default = true; 168 description = "Send Murmur version in UDP response."; 169 }; 170 171 registerName = mkOption { 172 type = types.str; 173 default = ""; 174 description = '' 175 Public server registration name, and also the name of the 176 Root channel. Even if you don't publicly register your 177 server, you probably still want to set this. 178 ''; 179 }; 180 181 registerPassword = mkOption { 182 type = types.str; 183 default = ""; 184 description = '' 185 Public server registry password, used authenticate your 186 server to the registry to prevent impersonation; required for 187 subsequent registry updates. 188 ''; 189 }; 190 191 registerUrl = mkOption { 192 type = types.str; 193 default = ""; 194 description = "URL website for your server."; 195 }; 196 197 registerHostname = mkOption { 198 type = types.str; 199 default = ""; 200 description = '' 201 DNS hostname where your server can be reached. This is only 202 needed if you want your server to be accessed by its 203 hostname and not IP - but the name *must* resolve on the 204 internet properly. 205 ''; 206 }; 207 208 clientCertRequired = mkOption { 209 type = types.bool; 210 default = false; 211 description = "Require clients to authenticate via certificates."; 212 }; 213 214 sslCert = mkOption { 215 type = types.str; 216 default = ""; 217 description = "Path to your SSL certificate."; 218 }; 219 220 sslKey = mkOption { 221 type = types.str; 222 default = ""; 223 description = "Path to your SSL key."; 224 }; 225 226 sslCa = mkOption { 227 type = types.str; 228 default = ""; 229 description = "Path to your SSL CA certificate."; 230 }; 231 232 extraConfig = mkOption { 233 type = types.str; 234 default = ""; 235 description = "Extra configuration to put into mumur.ini."; 236 }; 237 }; 238 }; 239 240 config = mkIf cfg.enable { 241 users.extraUsers.murmur = { 242 description = "Murmur Service user"; 243 home = "/var/lib/murmur"; 244 createHome = true; 245 uid = config.ids.uids.murmur; 246 }; 247 248 systemd.services.murmur = { 249 description = "Murmur Chat Service"; 250 wantedBy = [ "multi-user.target" ]; 251 after = [ "network.target "]; 252 253 serviceConfig = { 254 Type = "forking"; 255 PIDFile = cfg.pidfile; 256 Restart = "always"; 257 User = "murmur"; 258 ExecStart = "${pkgs.murmur}/bin/murmurd -ini ${configFile}"; 259 PermissionsStartOnly = true; 260 }; 261 262 preStart = '' 263 mkdir -p /var/log/murmur 264 chown -R murmur /var/log/murmur 265 ''; 266 }; 267 }; 268}