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