nixpkgs/nixos/modules/services/security/vault.nix

157 lines
4.7 KiB
Nix
Raw Normal View History

2017-06-27 16:54:25 +02:00
{ config, lib, pkgs, ... }:
2017-06-07 22:31:40 +02:00
with lib;
2017-06-07 22:31:40 +02:00
let
cfg = config.services.vault;
2017-06-27 16:54:25 +02:00
2017-06-07 22:31:40 +02:00
configFile = pkgs.writeText "vault.hcl" ''
listener "tcp" {
2017-06-27 16:54:25 +02:00
address = "${cfg.address}"
${if (cfg.tlsCertFile == null || cfg.tlsKeyFile == null) then ''
tls_disable = "true"
'' else ''
tls_cert_file = "${cfg.tlsCertFile}"
tls_key_file = "${cfg.tlsKeyFile}"
''}
2017-06-27 16:54:25 +02:00
${cfg.listenerExtraConfig}
2017-06-07 22:31:40 +02:00
}
2017-06-27 16:54:25 +02:00
storage "${cfg.storageBackend}" {
${optionalString (cfg.storagePath != null) ''path = "${cfg.storagePath}"''}
${optionalString (cfg.storageConfig != null) cfg.storageConfig}
2017-06-07 22:31:40 +02:00
}
2017-06-27 16:54:25 +02:00
${optionalString (cfg.telemetryConfig != "") ''
telemetry {
${cfg.telemetryConfig}
}
''}
${cfg.extraConfig}
2017-06-07 22:31:40 +02:00
'';
in
2017-06-07 22:31:40 +02:00
{
options = {
services.vault = {
2017-06-27 16:54:25 +02:00
enable = mkEnableOption "Vault daemon";
2017-06-07 22:31:40 +02:00
package = mkOption {
type = types.package;
default = pkgs.vault;
defaultText = "pkgs.vault";
description = "This option specifies the vault package to use.";
};
2017-06-27 16:54:25 +02:00
address = mkOption {
type = types.str;
default = "127.0.0.1:8200";
description = "The name of the ip interface to listen to";
2017-06-07 22:31:40 +02:00
};
2017-06-27 16:54:25 +02:00
tlsCertFile = mkOption {
type = types.nullOr types.str;
default = null;
2017-06-27 16:54:25 +02:00
example = "/path/to/your/cert.pem";
description = "TLS certificate file. TLS will be disabled unless this option is set";
2017-06-07 22:31:40 +02:00
};
2017-06-27 16:54:25 +02:00
tlsKeyFile = mkOption {
type = types.nullOr types.str;
default = null;
2017-06-27 16:54:25 +02:00
example = "/path/to/your/key.pem";
description = "TLS private key file. TLS will be disabled unless this option is set";
2017-06-27 16:54:25 +02:00
};
2017-06-07 22:31:40 +02:00
2017-06-27 16:54:25 +02:00
listenerExtraConfig = mkOption {
type = types.lines;
default = ''
tls_min_version = "tls12"
'';
description = "Extra text appended to the listener section.";
2017-06-27 16:54:25 +02:00
};
2017-06-07 22:31:40 +02:00
2017-06-27 16:54:25 +02:00
storageBackend = mkOption {
type = types.enum [ "inmem" "file" "consul" "zookeeper" "s3" "azure" "dynamodb" "etcd" "mssql" "mysql" "postgresql" "swift" "gcs" "raft" ];
2017-06-27 16:54:25 +02:00
default = "inmem";
description = "The name of the type of storage backend";
};
2017-06-07 22:31:40 +02:00
storagePath = mkOption {
type = types.nullOr types.path;
default = if cfg.storageBackend == "file" then "/var/lib/vault" else null;
description = "Data directory for file backend";
};
2017-06-27 16:54:25 +02:00
storageConfig = mkOption {
type = types.nullOr types.lines;
default = null;
2017-06-27 16:54:25 +02:00
description = "Storage configuration";
2017-06-07 22:31:40 +02:00
};
2017-06-27 16:54:25 +02:00
telemetryConfig = mkOption {
type = types.lines;
default = "";
description = "Telemetry configuration";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra text appended to <filename>vault.hcl</filename>.";
};
2017-06-07 22:31:40 +02:00
};
};
config = mkIf cfg.enable {
assertions = [
{ assertion = cfg.storageBackend == "inmem" -> (cfg.storagePath == null && cfg.storageConfig == null);
message = ''The "inmem" storage expects no services.vault.storagePath nor services.vault.storageConfig'';
}
{ assertion = (cfg.storageBackend == "file" -> (cfg.storagePath != null && cfg.storageConfig == null)) && (cfg.storagePath != null -> cfg.storageBackend == "file");
message = ''You must set services.vault.storagePath only when using the "file" backend'';
}
];
2017-06-07 22:31:40 +02:00
users.users.vault = {
2017-06-27 16:54:25 +02:00
name = "vault";
group = "vault";
uid = config.ids.uids.vault;
description = "Vault daemon user";
};
users.groups.vault.gid = config.ids.gids.vault;
2017-06-07 22:31:40 +02:00
systemd.tmpfiles.rules = optional (cfg.storagePath != null) [
"d '${cfg.storagePath}' 0700 vault vault - -"
];
2017-06-27 16:54:25 +02:00
systemd.services.vault = {
description = "Vault server daemon";
2017-06-07 22:31:40 +02:00
2017-06-27 16:54:25 +02:00
wantedBy = ["multi-user.target"];
after = [ "network.target" ]
++ optional (config.services.consul.enable && cfg.storageBackend == "consul") "consul.service";
2017-06-27 16:54:25 +02:00
restartIfChanged = false; # do not restart on "nixos-rebuild switch". It would seal the storage and disrupt the clients.
2017-06-27 16:54:25 +02:00
serviceConfig = {
User = "vault";
Group = "vault";
ExecStart = "${cfg.package}/bin/vault server -config ${configFile}";
2017-06-27 16:54:25 +02:00
PrivateDevices = true;
PrivateTmp = true;
ProtectSystem = "full";
ProtectHome = "read-only";
AmbientCapabilities = "cap_ipc_lock";
NoNewPrivileges = true;
KillSignal = "SIGINT";
TimeoutStopSec = "30s";
Restart = "on-failure";
StartLimitInterval = "60s";
StartLimitBurst = 3;
};
unitConfig.RequiresMountsFor = optional (cfg.storagePath != null) cfg.storagePath;
2017-06-27 16:54:25 +02:00
};
2017-06-07 22:31:40 +02:00
};
}