Overhaul secrets management
This commit is contained in:
parent
826e196891
commit
7b2da0349c
|
@ -20,12 +20,12 @@
|
|||
./locales.nix
|
||||
./media-proxy.nix
|
||||
./network-manager.nix
|
||||
./nginx.nix
|
||||
./office.nix
|
||||
./prometheus/node_exporter.nix
|
||||
./pubkeys.nix
|
||||
./pulseaudio.nix
|
||||
./restic.nix
|
||||
./secrets.nix
|
||||
./ssd.nix
|
||||
./ssh.nix
|
||||
./tools.nix
|
||||
|
|
|
@ -2,41 +2,48 @@
|
|||
let
|
||||
port = 8888;
|
||||
services = {
|
||||
"media" = <secrets/media-proxy-auth>;
|
||||
"scan" = <secrets/media-proxy-auth>;
|
||||
"torrent" = <secrets/torrent-proxy-auth>;
|
||||
"media" = config.krops.secrets.media-proxy-auth.path;
|
||||
"scan" = config.krops.secrets.media-proxy-auth.path;
|
||||
"torrent" = config.krops.secrets.torrent-proxy-auth.path;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.sbruder.media-proxy.enable = lib.mkEnableOption "media proxy";
|
||||
|
||||
config.services.nginx = lib.mkIf config.sbruder.media-proxy.enable {
|
||||
enable = true;
|
||||
secrets = builtins.attrValues services;
|
||||
virtualHosts.media-proxy = {
|
||||
serverName = "localhost";
|
||||
listen = [
|
||||
{ inherit port; addr = "127.0.0.1"; }
|
||||
{ inherit port; addr = "[::1]"; }
|
||||
];
|
||||
locations = {
|
||||
"/".extraConfig = ''
|
||||
rewrite ^/__assets/(.*)$ /media/__assets/$1;
|
||||
'';
|
||||
} // lib.mapAttrs'
|
||||
(name: secret: {
|
||||
name = "/${name}/";
|
||||
value = {
|
||||
proxyPass = "https://${name}.sbruder.de/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
include /run/nginx/secrets/${lib.last (lib.splitString "/" (toString secret))};
|
||||
charset utf-8;
|
||||
'';
|
||||
};
|
||||
})
|
||||
services;
|
||||
config = lib.mkIf config.sbruder.media-proxy.enable {
|
||||
krops.secrets = {
|
||||
torrent-proxy-auth.group = "nginx";
|
||||
media-proxy-auth.group = "nginx";
|
||||
};
|
||||
users.users.nginx.extraGroups = [ "keys" ];
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts.media-proxy = {
|
||||
serverName = "localhost";
|
||||
listen = [
|
||||
{ inherit port; addr = "127.0.0.1"; }
|
||||
{ inherit port; addr = "[::1]"; }
|
||||
];
|
||||
locations = {
|
||||
"/".extraConfig = ''
|
||||
rewrite ^/__assets/(.*)$ /media/__assets/$1;
|
||||
'';
|
||||
} // lib.mapAttrs'
|
||||
(name: secret: {
|
||||
name = "/${name}/";
|
||||
value = {
|
||||
proxyPass = "https://${name}.sbruder.de/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
include ${secret};
|
||||
charset utf-8;
|
||||
'';
|
||||
};
|
||||
})
|
||||
services;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.services.nginx;
|
||||
in
|
||||
{
|
||||
options.services.nginx.secrets = lib.mkOption {
|
||||
type = with lib.types; listOf (either str path);
|
||||
default = [ ];
|
||||
description = "Secrets to be copied to `/run/nginx/secrets/`";
|
||||
};
|
||||
|
||||
config.systemd = lib.mkIf (lib.length cfg.secrets != 0) {
|
||||
services = {
|
||||
nginx-secrets = {
|
||||
description = "Secrets for nginx";
|
||||
wantedBy = [ "nginx.service" ];
|
||||
partOf = [ "nginx.service" ];
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
script = ''
|
||||
rm -rf /run/nginx/secrets
|
||||
install -o ${cfg.user} -g ${cfg.group} -m 700 -d /run/nginx/secrets
|
||||
'' + lib.concatStrings (map
|
||||
(secret: ''
|
||||
install -o ${cfg.user} -g ${cfg.group} -m 600 ${toString secret} /run/nginx/secrets
|
||||
'')
|
||||
cfg.secrets);
|
||||
};
|
||||
nginx.after = [ "nginx-secrets.service" ];
|
||||
};
|
||||
paths.nginx-secrets = {
|
||||
wantedBy = [ "nginx-secrets.service" ];
|
||||
partOf = [ "nginx-secrets.service" ];
|
||||
pathConfig = {
|
||||
PathModified = "/var/src/secrets";
|
||||
Unit = "nginx-secrets.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -68,10 +68,15 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
krops.secrets = {
|
||||
restic-password = { };
|
||||
restic-s3 = { };
|
||||
};
|
||||
|
||||
services.restic.backups."${name}" = {
|
||||
inherit repository;
|
||||
passwordFile = toString <secrets/restic-password>;
|
||||
s3CredentialsFile = toString <secrets/restic-s3>;
|
||||
passwordFile = config.krops.secrets.restic-password.path;
|
||||
s3CredentialsFile = config.krops.secrets.restic-s3.path;
|
||||
paths = [
|
||||
"/home"
|
||||
"/srv"
|
||||
|
|
66
modules/secrets.nix
Normal file
66
modules/secrets.nix
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Adapted from https://github.com/Mic92/dotfiles/blob/23f163cae52545d44a7e379dc204010b013d679a/nixos/vms/modules/secrets.nix
|
||||
#
|
||||
# All of the users wanting to access any key under /run/keys have to be a
|
||||
# member of the keys group (or be root). This is a hard coded limitation of
|
||||
# NixOS and I haven’t found a way to allow everyone to access /run/keys/ (not a
|
||||
# security problem since the keys themselves are given the right permissions).
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
secret = lib.types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = config._module.args.name;
|
||||
};
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/run/keys/${config.name}";
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0440";
|
||||
};
|
||||
owner = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
};
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
};
|
||||
source = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = toString <secrets> + "/${config.name}";
|
||||
};
|
||||
};
|
||||
});
|
||||
in
|
||||
{
|
||||
options.krops.secrets = lib.mkOption {
|
||||
type = lib.types.attrsOf secret;
|
||||
default = { };
|
||||
};
|
||||
config = lib.mkIf (config.krops.secrets != { }) {
|
||||
system.activationScripts.setup-secrets =
|
||||
let
|
||||
script = ''
|
||||
echo "setting up secrets…"
|
||||
'' + lib.concatMapStringsSep
|
||||
"\n"
|
||||
(secret: ''
|
||||
${pkgs.coreutils}/bin/install \
|
||||
-D \
|
||||
--compare \
|
||||
--verbose \
|
||||
--mode=${lib.escapeShellArg secret.mode} \
|
||||
--owner=${lib.escapeShellArg secret.owner} \
|
||||
--group=${lib.escapeShellArg secret.group} \
|
||||
${lib.escapeShellArg secret.source} \
|
||||
${lib.escapeShellArg secret.path} \
|
||||
|| echo "failed to copy ${secret.source} to ${secret.path}"
|
||||
'')
|
||||
(lib.attrValues config.krops.secrets);
|
||||
in
|
||||
lib.stringAfter [ "users" "groups" ] "source ${pkgs.writeText "setup-secrets.sh" script}";
|
||||
};
|
||||
}
|
|
@ -11,24 +11,23 @@ in
|
|||
description = "IP(v4) address of the host";
|
||||
example = "10.80.0.1";
|
||||
};
|
||||
privateKeyFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Private key file";
|
||||
default = toString <secrets/wg-home-private-key>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config.networking.wireguard.interfaces.wg-home = lib.mkIf cfg.enable {
|
||||
privateKeyFile = cfg.privateKeyFile;
|
||||
ips = [ "${cfg.address}/24" ];
|
||||
peers = [
|
||||
{
|
||||
allowedIPs = [ "10.80.0.0/24" ];
|
||||
publicKey = "UyZRAVTIc/RMs/J+591wrA8lHU0e8dwDJJwcpRb3xQA=";
|
||||
endpoint = "87.140.16.73:51820"; # IPv6 is tunneled so legacy is preferred
|
||||
persistentKeepalive = 25;
|
||||
}
|
||||
];
|
||||
config = lib.mkIf cfg.enable {
|
||||
krops.secrets.wg-home-private-key = { };
|
||||
|
||||
networking.wireguard.interfaces.wg-home = {
|
||||
privateKeyFile = config.krops.secrets.wg-home-private-key.path;
|
||||
ips = [ "${cfg.address}/24" ];
|
||||
peers = [
|
||||
{
|
||||
allowedIPs = [ "10.80.0.0/24" ];
|
||||
publicKey = "UyZRAVTIc/RMs/J+591wrA8lHU0e8dwDJJwcpRb3xQA=";
|
||||
endpoint = "87.140.16.73:51820"; # IPv6 is tunneled so legacy is preferred
|
||||
persistentKeepalive = 25;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue