vault: run as an unpivileged user

Volth 4c428b4a cad450e6

Changed files
+99 -172
nixos
modules
misc
services
security
pkgs
tools
security
vault
+2
nixos/modules/misc/ids.nix
···
btsync = 113;
minecraft = 114;
#monetdb = 115; # unused (not packaged), removed 2016-09-19
+
vault = 115;
rippled = 116;
murmur = 117;
foundationdb = 118;
···
btsync = 113;
#minecraft = 114; # unused
#monetdb = 115; # unused (not packaged), removed 2016-09-19
+
vault = 115;
#ripped = 116; # unused
#murmur = 117; # unused
foundationdb = 118;
+95 -170
nixos/modules/services/security/vault.nix
···
-
{ config, lib, pkgs, utils, ... }:
+
{ config, lib, pkgs, ... }:
with lib;
let
-
-
inherit (pkgs) vault;
+
cfg = config.services.vault;
-
cfg = config.services.vault;
-
configFile = pkgs.writeText "vault.hcl" ''
listener "tcp" {
-
address = "${cfg.listener.address}"
-
-
${optionalString (cfg.listener.cluster_address != null)''
-
cluster_address = "${cfg.listener.cluster_address}"
-
''}
-
-
${optionalString (cfg.listener.tls_cert_file != null)''
-
tls_cert_file = "${cfg.listener.tls_cert_file}"
-
''}
-
-
${optionalString (cfg.listener.tls_key_file != null)''
-
tls_key_file = "${cfg.listener.tls_key_file}"
-
''}
-
-
${if cfg.listener.tls_disable then "tls_disable = \"1\"" else "" }
-
-
tls_min_version = "${cfg.listener.tls_min_version}"
-
-
${optionalString (cfg.listener.tls_cipher_suites != null)''
-
tls_cipher_suites = \"${cfg.listener.tls_cipher_suites}\"
-
''}
-
-
tls_prefer_server_cipher_suites = "${boolToString cfg.listener.tls_prefer_server_cipher_suites}"
-
-
tls_require_and_verify_client_cert = "${boolToString cfg.listener.tls_require_and_verify_client_cert}"
-
+
address = "${cfg.address}"
+
tls_cert_file = "${cfg.tlsCertFile}"
+
tls_key_file = "${cfg.tlsKeyFile}"
+
${cfg.listenerExtraConfig}
}
-
-
storage "${cfg.storage.backend}" {
-
${cfg.storage.extraConfig}
+
storage "${cfg.storageBackend}" {
+
${cfg.storageConfig}
}
-
-
${if cfg.telemetry.extraConfig != "" then "
-
telemetry {
-
${if cfg.telemetry.disable_hostname then "disable_hostname = \"true\"" else ""}
-
${cfg.telemetry.extraConfig}
-
}" else ""}
-
+
${optionalString (cfg.telemetryConfig != "") ''
+
telemetry {
+
${cfg.telemetryConfig}
+
}
+
''}
'';
-
in
{
options = {
services.vault = {
-
enable = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Enables the vault daemon.
-
'';
+
enable = mkEnableOption "Vault daemon";
+
+
address = mkOption {
+
type = types.str;
+
default = "127.0.0.1:8200";
+
description = "The name of the ip interface to listen to";
};
-
listener = {
+
tlsCertFile = mkOption {
+
type = types.str;
+
default = "/etc/vault/cert.pem";
+
example = "/path/to/your/cert.pem";
+
description = "TLS certificate file. A self-signed certificate will be generated if file not exists";
+
};
-
address = mkOption {
-
type = types.str;
-
default = "127.0.0.1:8200";
-
description = ''
-
The name of the ip interface to listen to.
-
'';
-
};
+
tlsKeyFile = mkOption {
+
type = types.str;
+
default = "/etc/vault/key.pem";
+
example = "/path/to/your/key.pem";
+
description = "TLS private key file. A self-signed certificate will be generated if file not exists";
+
};
-
cluster_address = mkOption {
-
type = types.nullOr types.str;
-
default = null;
-
description = ''
-
The name of the address to bind to for cluster server-to-server requests.
-
'';
-
};
-
-
tls_cert_file = mkOption {
-
type = types.str;
-
default = "";
-
description = ''
-
The name of the crt file for the ssl certificate.
-
'';
-
};
-
-
tls_key_file = mkOption {
-
type = types.str;
-
default = "";
-
description = ''
-
The name of the key file for the ssl certificate.
-
'';
-
};
+
listenerExtraConfig = mkOption {
+
type = types.lines;
+
default = ''
+
tls_min_version = "tls12"
+
'';
+
description = "extra configuration";
+
};
-
tls_disable = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Specifies if TLS will be disabled. Vault assumes TLS by default, so you must explicitly disable TLS to opt-in to insecure communication.
-
'';
-
};
-
-
tls_min_version = mkOption {
-
type = types.enum [ "tls10" "tls11" "tls12" ];
-
default = "tls12";
-
description = ''
-
The minimum supported version of TLS. Accepted values are "tls10", "tls11" or "tls12".
-
'';
-
};
-
-
tls_cipher_suites = mkOption {
-
type = types.nullOr types.str;
-
default = null;
-
description = ''
-
The list of supported ciphersuites as a comma-separated-list.
-
'';
-
};
-
-
tls_prefer_server_cipher_suites = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Specifies to prefer the server's ciphersuite over the client ciphersuites.
-
'';
-
};
-
-
tls_require_and_verify_client_cert = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Turns on client authentication for this listener.
-
'';
-
};
-
+
storageBackend = mkOption {
+
type = types.enum ["inmem" "consul" "zookeeper" "file" "s3" "azure" "dynamodb" "etcd" "mssql" "mysql" "postgresql" "swift" "gcs"];
+
default = "inmem";
+
description = "The name of the type of storage backend";
};
-
storage = {
-
-
backend = mkOption {
-
type = types.str;
-
default = "inMemory";
-
description = ''
-
The name of the type of storage backend.
-
'';
-
};
-
-
extraConfig = mkOption {
-
type = types.lines;
-
default = "";
-
description = ''
-
Configuration for storage
-
'';
-
};
-
+
storageConfig = mkOption {
+
type = types.lines;
+
description = "Storage configuration";
+
default = "";
};
-
-
telemetry = {
-
-
disable_hostname = mkOption {
-
type = types.bool;
-
default = false;
-
description = ''
-
Specifies if gauge values should be prefixed with the local hostname.
-
'';
-
};
-
-
extraConfig = mkOption {
-
type = types.lines;
-
default = "";
-
description = ''
-
configuration for telemetry
-
'';
-
};
-
+
telemetryConfig = mkOption {
+
type = types.lines;
+
default = "";
+
description = "Telemetry configuration";
};
-
};
-
};
config = mkIf cfg.enable {
-
systemd.services.vault =
-
{ description = "Vault server daemon";
+
users.extraUsers.vault = {
+
name = "vault";
+
group = "vault";
+
uid = config.ids.uids.vault;
+
description = "Vault daemon user";
+
};
+
users.extraGroups.vault.gid = config.ids.gids.vault;
+
+
systemd.services.vault = {
+
description = "Vault server daemon";
wantedBy = ["multi-user.target"];
+
after = [ "network.target" ];
-
preStart =
-
''
-
mkdir -m 0755 -p /var/lib/vault
-
'';
+
preStart = ''
+
mkdir -m 0755 -p /var/lib/vault
+
chown -R vault:vault /var/lib/vault
-
serviceConfig =
-
{ ExecStart =
-
"${pkgs.vault}/bin/vault server -config ${configFile}";
-
KillMode = "process";
-
};
-
};
+
# generate a self-signed certificate, you will have to set environment variable "VAULT_SKIP_VERIFY=1" in the client
+
if [ ! -s ${cfg.tlsCertFile} -o ! -s ${cfg.tlsKeyFile} ]; then
+
mkdir -p $(dirname ${cfg.tlsCertFile}) || true
+
mkdir -p $(dirname ${cfg.tlsKeyFile }) || true
+
${pkgs.openssl.bin}/bin/openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 99999 \
+
-subj /C=US/ST=NY/L=NYC/O=vault/CN=${cfg.address} \
+
-keyout ${cfg.tlsKeyFile} -out ${cfg.tlsCertFile}
+
+
chown root:vault ${cfg.tlsKeyFile} ${cfg.tlsCertFile}
+
chmod 440 ${cfg.tlsKeyFile} ${cfg.tlsCertFile}
+
fi
+
'';
+
+
serviceConfig = {
+
User = "vault";
+
Group = "vault";
+
PermissionsStartOnly = true;
+
ExecStart = "${pkgs.vault}/bin/vault server -config ${configFile}";
+
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;
+
};
+
};
};
}
+2 -2
pkgs/tools/security/vault/default.nix
···
};
in buildGoPackage rec {
name = "vault-${version}";
-
version = "0.7.2";
+
version = "0.7.3";
goPackagePath = "github.com/hashicorp/vault";
···
owner = "hashicorp";
repo = "vault";
rev = "v${version}";
-
sha256 = "1kclpyb9a9y5zjvrlbxnkac4fl3lwqsr98v4yydf9ihl5v7wy4f5";
+
sha256 = "15wj1pfgzwzjfrqy7b5bx4y9f0hbpqlfif58l5xamwm88229qk4m";
};
buildFlagsArray = ''