at 18.09-beta 6.1 kB view raw
1{ config, lib, pkgs, ...}: 2 3with lib; 4 5let 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 passwordConf = optionalString cfg.checkPasswords '' 16 password_file ${cfg.dataDir}/passwd 17 ''; 18 19 mosquittoConf = pkgs.writeText "mosquitto.conf" '' 20 pid_file /run/mosquitto/pid 21 acl_file ${aclFile} 22 persistence true 23 allow_anonymous ${boolToString cfg.allowAnonymous} 24 bind_address ${cfg.host} 25 port ${toString cfg.port} 26 ${passwordConf} 27 ${listenerConf} 28 ${cfg.extraConf} 29 ''; 30 31 userAcl = (concatStringsSep "\n\n" (mapAttrsToList (n: c: 32 "user ${n}\n" + (concatStringsSep "\n" c.acl)) cfg.users 33 )); 34 35 aclFile = pkgs.writeText "mosquitto.acl" '' 36 ${cfg.aclExtraConf} 37 ${userAcl} 38 ''; 39 40in 41 42{ 43 44 ###### Interface 45 46 options = { 47 services.mosquitto = { 48 enable = mkEnableOption "Enable the MQTT Mosquitto broker."; 49 50 host = mkOption { 51 default = "127.0.0.1"; 52 example = "0.0.0.0"; 53 type = types.string; 54 description = '' 55 Host to listen on without SSL. 56 ''; 57 }; 58 59 port = mkOption { 60 default = 1883; 61 example = 1883; 62 type = types.int; 63 description = '' 64 Port on which to listen without SSL. 65 ''; 66 }; 67 68 ssl = { 69 enable = mkEnableOption "Enable SSL listener."; 70 71 cafile = mkOption { 72 type = types.nullOr types.path; 73 default = null; 74 description = "Path to PEM encoded CA certificates."; 75 }; 76 77 certfile = mkOption { 78 type = types.nullOr types.path; 79 default = null; 80 description = "Path to PEM encoded server certificate."; 81 }; 82 83 keyfile = mkOption { 84 type = types.nullOr types.path; 85 default = null; 86 description = "Path to PEM encoded server key."; 87 }; 88 89 host = mkOption { 90 default = "0.0.0.0"; 91 example = "localhost"; 92 type = types.string; 93 description = '' 94 Host to listen on with SSL. 95 ''; 96 }; 97 98 port = mkOption { 99 default = 8883; 100 example = 8883; 101 type = types.int; 102 description = '' 103 Port on which to listen with SSL. 104 ''; 105 }; 106 }; 107 108 dataDir = mkOption { 109 default = "/var/lib/mosquitto"; 110 type = types.path; 111 description = '' 112 The data directory. 113 ''; 114 }; 115 116 users = mkOption { 117 type = types.attrsOf (types.submodule { 118 options = { 119 password = mkOption { 120 type = with types; uniq (nullOr str); 121 default = null; 122 description = '' 123 Specifies the (clear text) password for the MQTT User. 124 ''; 125 }; 126 127 hashedPassword = mkOption { 128 type = with types; uniq (nullOr str); 129 default = null; 130 description = '' 131 Specifies the hashed password for the MQTT User. 132 <option>hashedPassword</option> overrides <option>password</option>. 133 To generate hashed password install <literal>mosquitto</literal> 134 package and use <literal>mosquitto_passwd</literal>. 135 ''; 136 }; 137 138 acl = mkOption { 139 type = types.listOf types.string; 140 example = [ "topic read A/B" "topic A/#" ]; 141 description = '' 142 Control client access to topics on the broker. 143 ''; 144 }; 145 }; 146 }); 147 example = { john = { password = "123456"; acl = [ "topic readwrite john/#" ]; }; }; 148 description = '' 149 A set of users and their passwords and ACLs. 150 ''; 151 }; 152 153 allowAnonymous = mkOption { 154 default = false; 155 type = types.bool; 156 description = '' 157 Allow clients to connect without authentication. 158 ''; 159 }; 160 161 checkPasswords = mkOption { 162 default = false; 163 example = true; 164 type = types.bool; 165 description = '' 166 Refuse connection when clients provide incorrect passwords. 167 ''; 168 }; 169 170 extraConf = mkOption { 171 default = ""; 172 type = types.lines; 173 description = '' 174 Extra config to append to `mosquitto.conf` file. 175 ''; 176 }; 177 178 aclExtraConf = mkOption { 179 default = ""; 180 type = types.lines; 181 description = '' 182 Extra config to prepend to the ACL file. 183 ''; 184 }; 185 186 }; 187 }; 188 189 190 ###### Implementation 191 192 config = mkIf cfg.enable { 193 194 systemd.services.mosquitto = { 195 description = "Mosquitto MQTT Broker Daemon"; 196 wantedBy = [ "multi-user.target" ]; 197 after = [ "network.target" ]; 198 serviceConfig = { 199 Type = "forking"; 200 User = "mosquitto"; 201 Group = "mosquitto"; 202 RuntimeDirectory = "mosquitto"; 203 WorkingDirectory = cfg.dataDir; 204 Restart = "on-failure"; 205 ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf} -d"; 206 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 207 PIDFile = "/run/mosquitto/pid"; 208 }; 209 preStart = '' 210 rm -f ${cfg.dataDir}/passwd 211 touch ${cfg.dataDir}/passwd 212 '' + concatStringsSep "\n" ( 213 mapAttrsToList (n: c: 214 if c.hashedPassword != null then 215 "echo '${n}:${c.hashedPassword}' >> ${cfg.dataDir}/passwd" 216 else optionalString (c.password != null) 217 "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}" 218 ) cfg.users); 219 }; 220 221 users.users.mosquitto = { 222 description = "Mosquitto MQTT Broker Daemon owner"; 223 group = "mosquitto"; 224 uid = config.ids.uids.mosquitto; 225 home = cfg.dataDir; 226 createHome = true; 227 }; 228 229 users.groups.mosquitto.gid = config.ids.gids.mosquitto; 230 231 }; 232}