at master 4.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.step-ca; 9 settingsFormat = (pkgs.formats.json { }); 10in 11{ 12 meta.maintainers = [ ]; 13 14 options = { 15 services.step-ca = { 16 enable = lib.mkEnableOption "the smallstep certificate authority server"; 17 openFirewall = lib.mkEnableOption "opening the certificate authority server port"; 18 package = lib.mkPackageOption pkgs "step-ca" { }; 19 address = lib.mkOption { 20 type = lib.types.str; 21 example = "127.0.0.1"; 22 description = '' 23 The address (without port) the certificate authority should listen at. 24 This combined with {option}`services.step-ca.port` overrides {option}`services.step-ca.settings.address`. 25 ''; 26 }; 27 port = lib.mkOption { 28 type = lib.types.port; 29 example = 8443; 30 description = '' 31 The port the certificate authority should listen on. 32 This combined with {option}`services.step-ca.address` overrides {option}`services.step-ca.settings.address`. 33 ''; 34 }; 35 settings = lib.mkOption { 36 type = with lib.types; attrsOf anything; 37 description = '' 38 Settings that go into {file}`ca.json`. See 39 [the step-ca manual](https://smallstep.com/docs/step-ca/configuration) 40 for more information. The easiest way to 41 configure this module would be to run `step ca init` 42 to generate {file}`ca.json` and then import it using 43 `builtins.fromJSON`. 44 [This article](https://smallstep.com/docs/step-cli/basic-crypto-operations#run-an-offline-x509-certificate-authority) 45 may also be useful if you want to customize certain aspects of 46 certificate generation for your CA. 47 You need to change the database storage path to {file}`/var/lib/step-ca/db`. 48 49 ::: {.warning} 50 The {option}`services.step-ca.settings.address` option 51 will be ignored and overwritten by 52 {option}`services.step-ca.address` and 53 {option}`services.step-ca.port`. 54 ::: 55 ''; 56 }; 57 intermediatePasswordFile = lib.mkOption { 58 type = lib.types.pathWith { 59 inStore = false; 60 absolute = true; 61 }; 62 example = "/run/keys/smallstep-password"; 63 description = '' 64 Path to the file containing the password for the intermediate 65 certificate private key. 66 67 ::: {.warning} 68 Make sure to use a quoted absolute path instead of a path literal 69 to prevent it from being copied to the globally readable Nix 70 store. 71 ::: 72 ''; 73 }; 74 }; 75 }; 76 77 config = lib.mkIf config.services.step-ca.enable ( 78 let 79 configFile = settingsFormat.generate "ca.json" ( 80 cfg.settings 81 // { 82 address = cfg.address + ":" + toString cfg.port; 83 } 84 ); 85 in 86 { 87 systemd.packages = [ cfg.package ]; 88 89 # configuration file indirection is needed to support reloading 90 environment.etc."smallstep/ca.json".source = configFile; 91 92 systemd.services."step-ca" = { 93 wantedBy = [ "multi-user.target" ]; 94 restartTriggers = [ configFile ]; 95 unitConfig = { 96 ConditionFileNotEmpty = ""; # override upstream 97 }; 98 serviceConfig = { 99 User = "step-ca"; 100 Group = "step-ca"; 101 UMask = "0077"; 102 Environment = "HOME=%S/step-ca"; 103 WorkingDirectory = ""; # override upstream 104 ReadWritePaths = ""; # override upstream 105 106 # LocalCredential handles file permission problems arising from the use of DynamicUser. 107 LoadCredential = "intermediate_password:${cfg.intermediatePasswordFile}"; 108 109 ExecStart = [ 110 "" # override upstream 111 "${cfg.package}/bin/step-ca /etc/smallstep/ca.json --password-file \${CREDENTIALS_DIRECTORY}/intermediate_password" 112 ]; 113 114 # ProtectProc = "invisible"; # not supported by upstream yet 115 # ProcSubset = "pid"; # not supported by upstream yet 116 # PrivateUsers = true; # doesn't work with privileged ports therefore not supported by upstream 117 118 DynamicUser = true; 119 StateDirectory = "step-ca"; 120 }; 121 }; 122 123 users.users.step-ca = { 124 home = "/var/lib/step-ca"; 125 group = "step-ca"; 126 isSystemUser = true; 127 }; 128 129 users.groups.step-ca = { }; 130 131 networking.firewall = lib.mkIf cfg.openFirewall { 132 allowedTCPPorts = [ cfg.port ]; 133 }; 134 } 135 ); 136}