at 17.09-beta 5.8 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 mosquittoConf = pkgs.writeText "mosquitto.conf" '' 16 pid_file /run/mosquitto/pid 17 acl_file ${aclFile} 18 persistence true 19 allow_anonymous ${boolToString cfg.allowAnonymous} 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 35in 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>mosquitto</literal> 129 package and use <literal>mosquitto_passwd</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 type = types.bool; 151 description = '' 152 Allow clients to connect without authentication. 153 ''; 154 }; 155 156 extraConf = mkOption { 157 default = ""; 158 type = types.lines; 159 description = '' 160 Extra config to append to `mosquitto.conf` file. 161 ''; 162 }; 163 164 aclExtraConf = mkOption { 165 default = ""; 166 type = types.lines; 167 description = '' 168 Extra config to prepend to the ACL file. 169 ''; 170 }; 171 172 }; 173 }; 174 175 176 ###### Implementation 177 178 config = mkIf cfg.enable { 179 180 systemd.services.mosquitto = { 181 description = "Mosquitto MQTT Broker Daemon"; 182 wantedBy = [ "multi-user.target" ]; 183 after = [ "network.target" ]; 184 serviceConfig = { 185 Type = "forking"; 186 User = "mosquitto"; 187 Group = "mosquitto"; 188 RuntimeDirectory = "mosquitto"; 189 WorkingDirectory = cfg.dataDir; 190 Restart = "on-failure"; 191 ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf} -d"; 192 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 193 PIDFile = "/run/mosquitto/pid"; 194 }; 195 preStart = '' 196 rm -f ${cfg.dataDir}/passwd 197 touch ${cfg.dataDir}/passwd 198 '' + concatStringsSep "\n" ( 199 mapAttrsToList (n: c: 200 if c.hashedPassword != null then 201 "echo '${n}:${c.hashedPassword}' > ${cfg.dataDir}/passwd" 202 else optionalString (c.password != null) 203 "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}" 204 ) cfg.users); 205 }; 206 207 users.extraUsers.mosquitto = { 208 description = "Mosquitto MQTT Broker Daemon owner"; 209 group = "mosquitto"; 210 uid = config.ids.uids.mosquitto; 211 home = cfg.dataDir; 212 createHome = true; 213 }; 214 215 users.extraGroups.mosquitto.gid = config.ids.gids.mosquitto; 216 217 }; 218}