Merge pull request #15620 from Cornu/mosquitto

mosquitto service: init

+222
+2
nixos/modules/misc/ids.nix
··· 267 graylog = 243; 268 sniproxy = 244; 269 nzbget = 245; 270 271 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 272 ··· 504 emby = 242; 505 sniproxy = 244; 506 nzbget = 245; 507 508 # When adding a gid, make sure it doesn't match an existing 509 # uid. Users and groups with the same name should have equal
··· 267 graylog = 243; 268 sniproxy = 244; 269 nzbget = 245; 270 + mosquitto = 246; 271 272 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 273 ··· 505 emby = 242; 506 sniproxy = 244; 507 nzbget = 245; 508 + mosquitto = 246; 509 510 # When adding a gid, make sure it doesn't match an existing 511 # uid. Users and groups with the same name should have equal
+1
nixos/modules/module-list.nix
··· 347 ./services/networking/mjpg-streamer.nix 348 ./services/networking/minidlna.nix 349 ./services/networking/miniupnpd.nix 350 ./services/networking/mstpd.nix 351 ./services/networking/murmur.nix 352 ./services/networking/namecoind.nix
··· 347 ./services/networking/mjpg-streamer.nix 348 ./services/networking/minidlna.nix 349 ./services/networking/miniupnpd.nix 350 + ./services/networking/mosquitto.nix 351 ./services/networking/mstpd.nix 352 ./services/networking/murmur.nix 353 ./services/networking/namecoind.nix
+219
nixos/modules/services/networking/mosquitto.nix
···
··· 1 + { config, lib, pkgs, ...}: 2 + 3 + with lib; 4 + 5 + let 6 + cfg = config.services.mosquitto; 7 + 8 + listenerConf = optionalString cfg.ssl.enable '' 9 + listener ${toString cfg.ssl.port} ${cfg.ssl.host} 10 + cafile ${cfg.ssl.cafile} 11 + certfile ${cfg.ssl.certfile} 12 + keyfile ${cfg.ssl.keyfile} 13 + ''; 14 + 15 + mosquittoConf = pkgs.writeText "mosquitto.conf" '' 16 + pid_file /run/mosquitto/pid 17 + acl_file ${aclFile} 18 + persistence true 19 + allow_anonymous ${if cfg.allowAnonymous then "true" else "false"} 20 + bind_address ${cfg.host} 21 + port ${toString cfg.port} 22 + ${listenerConf} 23 + ${cfg.extraConf} 24 + ''; 25 + 26 + userAcl = (concatStringsSep "\n\n" (mapAttrsToList (n: c: 27 + "user ${n}\n" + (concatStringsSep "\n" c.acl)) cfg.users 28 + )); 29 + 30 + aclFile = pkgs.writeText "mosquitto.acl" '' 31 + ${cfg.aclExtraConf} 32 + ${userAcl} 33 + ''; 34 + 35 + in 36 + 37 + { 38 + 39 + ###### Interface 40 + 41 + options = { 42 + services.mosquitto = { 43 + enable = mkEnableOption "Enable the MQTT Mosquitto broker."; 44 + 45 + host = mkOption { 46 + default = "127.0.0.1"; 47 + example = "0.0.0.0"; 48 + type = types.string; 49 + description = '' 50 + Host to listen on without SSL. 51 + ''; 52 + }; 53 + 54 + port = mkOption { 55 + default = 1883; 56 + example = 1883; 57 + type = types.int; 58 + description = '' 59 + Port on which to listen without SSL. 60 + ''; 61 + }; 62 + 63 + ssl = { 64 + enable = mkEnableOption "Enable SSL listener."; 65 + 66 + cafile = mkOption { 67 + type = types.nullOr types.path; 68 + default = null; 69 + description = "Path to PEM encoded CA certificates."; 70 + }; 71 + 72 + certfile = mkOption { 73 + type = types.nullOr types.path; 74 + default = null; 75 + description = "Path to PEM encoded server certificate."; 76 + }; 77 + 78 + keyfile = mkOption { 79 + type = types.nullOr types.path; 80 + default = null; 81 + description = "Path to PEM encoded server key."; 82 + }; 83 + 84 + host = mkOption { 85 + default = "0.0.0.0"; 86 + example = "localhost"; 87 + type = types.string; 88 + description = '' 89 + Host to listen on with SSL. 90 + ''; 91 + }; 92 + 93 + port = mkOption { 94 + default = 8883; 95 + example = 8883; 96 + type = types.int; 97 + description = '' 98 + Port on which to listen with SSL. 99 + ''; 100 + }; 101 + }; 102 + 103 + dataDir = mkOption { 104 + default = "/var/lib/mosquitto"; 105 + type = types.path; 106 + description = '' 107 + The data directory. 108 + ''; 109 + }; 110 + 111 + users = mkOption { 112 + type = types.attrsOf (types.submodule { 113 + options = { 114 + password = mkOption { 115 + type = with types; uniq (nullOr str); 116 + default = null; 117 + description = '' 118 + Specifies the (clear text) password for the MQTT User. 119 + ''; 120 + }; 121 + 122 + hashedPassword = mkOption { 123 + type = with types; uniq (nullOr str); 124 + default = null; 125 + description = '' 126 + Specifies the hashed password for the MQTT User. 127 + <option>hashedPassword</option> overrides <option>password</option>. 128 + To generate hashed password install <literal>mkpasswd</literal> 129 + package and run <literal>mkpasswd -m sha-512</literal>. 130 + ''; 131 + }; 132 + 133 + acl = mkOption { 134 + type = types.listOf types.string; 135 + example = [ "topic read A/B" "topic A/#" ]; 136 + description = '' 137 + Control client access to topics on the broker. 138 + ''; 139 + }; 140 + }; 141 + }); 142 + example = { john = { password = "123456"; acl = [ "topic readwrite john/#" ]; }; }; 143 + description = '' 144 + A set of users and their passwords and ACLs. 145 + ''; 146 + }; 147 + 148 + allowAnonymous = mkOption { 149 + default = false; 150 + example = true; 151 + type = types.bool; 152 + description = '' 153 + Allow clients to connect without authentication. 154 + ''; 155 + }; 156 + 157 + extraConf = mkOption { 158 + default = ""; 159 + type = types.lines; 160 + description = '' 161 + Extra config to append to `mosquitto.conf` file. 162 + ''; 163 + }; 164 + 165 + aclExtraConf = mkOption { 166 + default = ""; 167 + type = types.lines; 168 + description = '' 169 + Extra config to prepend to the ACL file. 170 + ''; 171 + }; 172 + 173 + }; 174 + }; 175 + 176 + 177 + ###### Implementation 178 + 179 + config = mkIf cfg.enable { 180 + 181 + systemd.services.mosquitto = { 182 + description = "Mosquitto MQTT Broker Daemon"; 183 + wantedBy = [ "multi-user.target" ]; 184 + after = [ "network.target" ]; 185 + serviceConfig = { 186 + Type = "forking"; 187 + User = "mosquitto"; 188 + Group = "mosquitto"; 189 + RuntimeDirectory = "mosquitto"; 190 + WorkingDirectory = cfg.dataDir; 191 + Restart = "on-failure"; 192 + ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf} -d"; 193 + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 194 + PIDFile = "/run/mosquitto/pid"; 195 + }; 196 + preStart = '' 197 + rm -f ${cfg.dataDir}/passwd 198 + touch ${cfg.dataDir}/passwd 199 + '' + concatStringsSep "\n" ( 200 + mapAttrsToList (n: c: 201 + if c.hashedPassword != null then 202 + "echo '${n}:${c.hashedPassword}' > ${cfg.dataDir}/passwd" 203 + else optionalString (c.password != null) 204 + "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}" 205 + ) cfg.users); 206 + }; 207 + 208 + users.extraUsers.mosquitto = { 209 + description = "Mosquitto MQTT Broker Daemon owner"; 210 + group = "mosquitto"; 211 + uid = config.ids.uids.mosquitto; 212 + home = cfg.dataDir; 213 + createHome = true; 214 + }; 215 + 216 + users.extraGroups.mosquitto.gid = config.ids.gids.mosquitto; 217 + 218 + }; 219 + }