at master 6.9 kB view raw
1{ 2 config, 3 options, 4 lib, 5 pkgs, 6 ... 7}: 8let 9 cfg = config.services.cfssl; 10in 11{ 12 options.services.cfssl = { 13 enable = lib.mkEnableOption "the CFSSL CA api-server"; 14 15 dataDir = lib.mkOption { 16 default = "/var/lib/cfssl"; 17 type = lib.types.path; 18 description = '' 19 The work directory for CFSSL. 20 21 ::: {.note} 22 If left as the default value this directory will automatically be 23 created before the CFSSL server starts, otherwise you are 24 responsible for ensuring the directory exists with appropriate 25 ownership and permissions. 26 ::: 27 ''; 28 }; 29 30 address = lib.mkOption { 31 default = "127.0.0.1"; 32 type = lib.types.str; 33 description = "Address to bind."; 34 }; 35 36 port = lib.mkOption { 37 default = 8888; 38 type = lib.types.port; 39 description = "Port to bind."; 40 }; 41 42 ca = lib.mkOption { 43 defaultText = lib.literalExpression ''"''${cfg.dataDir}/ca.pem"''; 44 type = lib.types.str; 45 description = "CA used to sign the new certificate -- accepts '[file:]fname' or 'env:varname'."; 46 }; 47 48 caKey = lib.mkOption { 49 defaultText = lib.literalExpression ''"file:''${cfg.dataDir}/ca-key.pem"''; 50 type = lib.types.str; 51 description = "CA private key -- accepts '[file:]fname' or 'env:varname'."; 52 }; 53 54 caBundle = lib.mkOption { 55 default = null; 56 type = lib.types.nullOr lib.types.path; 57 description = "Path to root certificate store."; 58 }; 59 60 intBundle = lib.mkOption { 61 default = null; 62 type = lib.types.nullOr lib.types.path; 63 description = "Path to intermediate certificate store."; 64 }; 65 66 intDir = lib.mkOption { 67 default = null; 68 type = lib.types.nullOr lib.types.path; 69 description = "Intermediates directory."; 70 }; 71 72 metadata = lib.mkOption { 73 default = null; 74 type = lib.types.nullOr lib.types.path; 75 description = '' 76 Metadata file for root certificate presence. 77 The content of the file is a json dictionary (k,v): each key k is 78 a SHA-1 digest of a root certificate while value v is a list of key 79 store filenames. 80 ''; 81 }; 82 83 remote = lib.mkOption { 84 default = null; 85 type = lib.types.nullOr lib.types.str; 86 description = "Remote CFSSL server."; 87 }; 88 89 configFile = lib.mkOption { 90 default = null; 91 type = lib.types.nullOr lib.types.str; 92 description = "Path to configuration file. Do not put this in nix-store as it might contain secrets."; 93 }; 94 95 responder = lib.mkOption { 96 default = null; 97 type = lib.types.nullOr lib.types.path; 98 description = "Certificate for OCSP responder."; 99 }; 100 101 responderKey = lib.mkOption { 102 default = null; 103 type = lib.types.nullOr lib.types.str; 104 description = "Private key for OCSP responder certificate. Do not put this in nix-store."; 105 }; 106 107 tlsKey = lib.mkOption { 108 default = null; 109 type = lib.types.nullOr lib.types.str; 110 description = "Other endpoint's CA private key. Do not put this in nix-store."; 111 }; 112 113 tlsCert = lib.mkOption { 114 default = null; 115 type = lib.types.nullOr lib.types.path; 116 description = "Other endpoint's CA to set up TLS protocol."; 117 }; 118 119 mutualTlsCa = lib.mkOption { 120 default = null; 121 type = lib.types.nullOr lib.types.path; 122 description = "Mutual TLS - require clients be signed by this CA."; 123 }; 124 125 mutualTlsCn = lib.mkOption { 126 default = null; 127 type = lib.types.nullOr lib.types.str; 128 description = "Mutual TLS - regex for whitelist of allowed client CNs."; 129 }; 130 131 tlsRemoteCa = lib.mkOption { 132 default = null; 133 type = lib.types.nullOr lib.types.path; 134 description = "CAs to trust for remote TLS requests."; 135 }; 136 137 mutualTlsClientCert = lib.mkOption { 138 default = null; 139 type = lib.types.nullOr lib.types.path; 140 description = "Mutual TLS - client certificate to call remote instance requiring client certs."; 141 }; 142 143 mutualTlsClientKey = lib.mkOption { 144 default = null; 145 type = lib.types.nullOr lib.types.path; 146 description = "Mutual TLS - client key to call remote instance requiring client certs. Do not put this in nix-store."; 147 }; 148 149 dbConfig = lib.mkOption { 150 default = null; 151 type = lib.types.nullOr lib.types.path; 152 description = "Certificate db configuration file. Path must be writeable."; 153 }; 154 155 logLevel = lib.mkOption { 156 default = 1; 157 type = lib.types.ints.between 0 5; 158 description = "Log level (0 = DEBUG, 5 = FATAL)."; 159 }; 160 161 disable = lib.mkOption { 162 default = null; 163 type = lib.types.nullOr lib.types.commas; 164 description = "Endpoints to disable (comma-separated list)"; 165 }; 166 }; 167 168 config = lib.mkIf cfg.enable { 169 users.groups.cfssl = { 170 gid = config.ids.gids.cfssl; 171 }; 172 173 users.users.cfssl = { 174 description = "cfssl user"; 175 home = cfg.dataDir; 176 group = "cfssl"; 177 uid = config.ids.uids.cfssl; 178 }; 179 180 systemd.services.cfssl = { 181 description = "CFSSL CA API server"; 182 wantedBy = [ "multi-user.target" ]; 183 after = [ "network.target" ]; 184 185 serviceConfig = lib.mkMerge [ 186 { 187 WorkingDirectory = cfg.dataDir; 188 Restart = "always"; 189 User = "cfssl"; 190 Group = "cfssl"; 191 192 ExecStart = 193 with cfg; 194 let 195 opt = n: v: lib.optionalString (v != null) ''-${n}="${v}"''; 196 in 197 lib.concatStringsSep " \\\n" [ 198 "${pkgs.cfssl}/bin/cfssl serve" 199 (opt "address" address) 200 (opt "port" (toString port)) 201 (opt "ca" ca) 202 (opt "ca-key" caKey) 203 (opt "ca-bundle" caBundle) 204 (opt "int-bundle" intBundle) 205 (opt "int-dir" intDir) 206 (opt "metadata" metadata) 207 (opt "remote" remote) 208 (opt "config" configFile) 209 (opt "responder" responder) 210 (opt "responder-key" responderKey) 211 (opt "tls-key" tlsKey) 212 (opt "tls-cert" tlsCert) 213 (opt "mutual-tls-ca" mutualTlsCa) 214 (opt "mutual-tls-cn" mutualTlsCn) 215 (opt "mutual-tls-client-key" mutualTlsClientKey) 216 (opt "mutual-tls-client-cert" mutualTlsClientCert) 217 (opt "tls-remote-ca" tlsRemoteCa) 218 (opt "db-config" dbConfig) 219 (opt "loglevel" (toString logLevel)) 220 (opt "disable" disable) 221 ]; 222 } 223 (lib.mkIf (cfg.dataDir == options.services.cfssl.dataDir.default) { 224 StateDirectory = baseNameOf cfg.dataDir; 225 StateDirectoryMode = 700; 226 }) 227 ]; 228 }; 229 230 services.cfssl = { 231 ca = lib.mkDefault "${cfg.dataDir}/ca.pem"; 232 caKey = lib.mkDefault "${cfg.dataDir}/ca-key.pem"; 233 }; 234 }; 235}