at 18.03-beta 7.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.prosody; 8 9 sslOpts = { ... }: { 10 11 options = { 12 13 key = mkOption { 14 type = types.path; 15 description = "Path to the key file."; 16 }; 17 18 cert = mkOption { 19 type = types.path; 20 description = "Path to the certificate file."; 21 }; 22 23 extraOptions = mkOption { 24 type = types.attrs; 25 default = {}; 26 description = "Extra SSL configuration options."; 27 }; 28 29 }; 30 }; 31 32 moduleOpts = { 33 34 roster = mkOption { 35 type = types.bool; 36 default = true; 37 description = "Allow users to have a roster"; 38 }; 39 40 saslauth = mkOption { 41 type = types.bool; 42 default = true; 43 description = "Authentication for clients and servers. Recommended if you want to log in."; 44 }; 45 46 tls = mkOption { 47 type = types.bool; 48 default = true; 49 description = "Add support for secure TLS on c2s/s2s connections"; 50 }; 51 52 dialback = mkOption { 53 type = types.bool; 54 default = true; 55 description = "s2s dialback support"; 56 }; 57 58 disco = mkOption { 59 type = types.bool; 60 default = true; 61 description = "Service discovery"; 62 }; 63 64 legacyauth = mkOption { 65 type = types.bool; 66 default = true; 67 description = "Legacy authentication. Only used by some old clients and bots"; 68 }; 69 70 version = mkOption { 71 type = types.bool; 72 default = true; 73 description = "Replies to server version requests"; 74 }; 75 76 uptime = mkOption { 77 type = types.bool; 78 default = true; 79 description = "Report how long server has been running"; 80 }; 81 82 time = mkOption { 83 type = types.bool; 84 default = true; 85 description = "Let others know the time here on this server"; 86 }; 87 88 ping = mkOption { 89 type = types.bool; 90 default = true; 91 description = "Replies to XMPP pings with pongs"; 92 }; 93 94 console = mkOption { 95 type = types.bool; 96 default = false; 97 description = "telnet to port 5582"; 98 }; 99 100 bosh = mkOption { 101 type = types.bool; 102 default = false; 103 description = "Enable BOSH clients, aka 'Jabber over HTTP'"; 104 }; 105 106 httpserver = mkOption { 107 type = types.bool; 108 default = false; 109 description = "Serve static files from a directory over HTTP"; 110 }; 111 112 websocket = mkOption { 113 type = types.bool; 114 default = false; 115 description = "Enable WebSocket support"; 116 }; 117 118 }; 119 120 toLua = x: 121 if builtins.isString x then ''"${x}"'' 122 else if builtins.isBool x then toString x 123 else if builtins.isInt x then toString x 124 else throw "Invalid Lua value"; 125 126 createSSLOptsStr = o: '' 127 ssl = { 128 key = "${o.key}"; 129 certificate = "${o.cert}"; 130 ${concatStringsSep "\n" (mapAttrsToList (name: value: "${name} = ${toLua value};") o.extraOptions)} 131 }; 132 ''; 133 134 vHostOpts = { ... }: { 135 136 options = { 137 138 # TODO: require attribute 139 domain = mkOption { 140 type = types.str; 141 description = "Domain name"; 142 }; 143 144 enabled = mkOption { 145 type = types.bool; 146 default = false; 147 description = "Whether to enable the virtual host"; 148 }; 149 150 ssl = mkOption { 151 type = types.nullOr (types.submodule sslOpts); 152 default = null; 153 description = "Paths to SSL files"; 154 }; 155 156 extraConfig = mkOption { 157 type = types.lines; 158 default = ""; 159 description = "Additional virtual host specific configuration"; 160 }; 161 162 }; 163 164 }; 165 166in 167 168{ 169 170 ###### interface 171 172 options = { 173 174 services.prosody = { 175 176 enable = mkOption { 177 type = types.bool; 178 default = false; 179 description = "Whether to enable the prosody server"; 180 }; 181 182 package = mkOption { 183 type = types.package; 184 description = "Prosody package to use"; 185 default = pkgs.prosody; 186 defaultText = "pkgs.prosody"; 187 example = literalExample '' 188 pkgs.prosody.override { 189 withExtraLibs = [ pkgs.luaPackages.lpty ]; 190 withCommunityModules = [ "auth_external" ]; 191 }; 192 ''; 193 }; 194 195 allowRegistration = mkOption { 196 type = types.bool; 197 default = false; 198 description = "Allow account creation"; 199 }; 200 201 modules = moduleOpts; 202 203 extraModules = mkOption { 204 type = types.listOf types.str; 205 default = []; 206 description = "Enable custom modules"; 207 }; 208 209 virtualHosts = mkOption { 210 211 description = "Define the virtual hosts"; 212 213 type = with types; loaOf (submodule vHostOpts); 214 215 example = { 216 myhost = { 217 domain = "my-xmpp-example-host.org"; 218 enabled = true; 219 }; 220 }; 221 222 default = { 223 localhost = { 224 domain = "localhost"; 225 enabled = true; 226 }; 227 }; 228 229 }; 230 231 ssl = mkOption { 232 type = types.nullOr (types.submodule sslOpts); 233 default = null; 234 description = "Paths to SSL files"; 235 }; 236 237 admins = mkOption { 238 type = types.listOf types.str; 239 default = []; 240 example = [ "admin1@example.com" "admin2@example.com" ]; 241 description = "List of administrators of the current host"; 242 }; 243 244 extraConfig = mkOption { 245 type = types.lines; 246 default = ""; 247 description = "Additional prosody configuration"; 248 }; 249 250 }; 251 }; 252 253 254 ###### implementation 255 256 config = mkIf cfg.enable { 257 258 environment.systemPackages = [ pkgs.prosody ]; 259 260 environment.etc."prosody/prosody.cfg.lua".text = '' 261 262 pidfile = "/var/lib/prosody/prosody.pid" 263 264 265 log = "*syslog" 266 267 data_path = "/var/lib/prosody" 268 269 allow_registration = ${boolToString cfg.allowRegistration}; 270 271 ${ optionalString cfg.modules.console "console_enabled = true;" } 272 273 ${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) } 274 275 admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } }; 276 277 modules_enabled = { 278 279 ${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList 280 (name: val: optionalString val ''"${name}";'') 281 cfg.modules) } 282 283 ${ optionalString cfg.allowRegistration "\"register\"\;" } 284 285 ${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)} 286 287 "posix"; 288 }; 289 290 ${ cfg.extraConfig } 291 292 ${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: '' 293 VirtualHost "${v.domain}" 294 enabled = ${boolToString v.enabled}; 295 ${ optionalString (v.ssl != null) (createSSLOptsStr v.ssl) } 296 ${ v.extraConfig } 297 '') cfg.virtualHosts) } 298 ''; 299 300 users.extraUsers.prosody = { 301 uid = config.ids.uids.prosody; 302 description = "Prosody user"; 303 createHome = true; 304 group = "prosody"; 305 home = "/var/lib/prosody"; 306 }; 307 308 users.extraGroups.prosody = { 309 gid = config.ids.gids.prosody; 310 }; 311 312 systemd.services.prosody = { 313 description = "Prosody XMPP server"; 314 after = [ "network-online.target" ]; 315 wants = [ "network-online.target" ]; 316 wantedBy = [ "multi-user.target" ]; 317 restartTriggers = [ config.environment.etc."prosody/prosody.cfg.lua".source ]; 318 serviceConfig = { 319 User = "prosody"; 320 Type = "forking"; 321 PIDFile = "/var/lib/prosody/prosody.pid"; 322 ExecStart = "${cfg.package}/bin/prosodyctl start"; 323 }; 324 }; 325 326 }; 327 328}