Compare commits
No commits in common. "eab20b43392c47856164bea7edf498646178cc86" and "5462fa43fa92baf046c3635f2ba63aa57d892701" have entirely different histories.
eab20b4339
...
5462fa43fa
|
@ -12,11 +12,9 @@
|
||||||
disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
./gaming
|
./gaming
|
||||||
./geoffrey.nix
|
./geoffrey.nix
|
||||||
./password
|
|
||||||
./printing
|
./printing
|
||||||
./remote-builds
|
./remote-builds
|
||||||
./style
|
./style
|
||||||
./syncthing
|
|
||||||
./wireless
|
./wireless
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,163 +0,0 @@
|
||||||
{ pkgs, lib, config, ... }:
|
|
||||||
let
|
|
||||||
pass_subdir = "";
|
|
||||||
readPassword = password: "pass show '${pass_subdir}/${password.path}'" + (
|
|
||||||
if password.selector == null
|
|
||||||
then " | head -n1"
|
|
||||||
else
|
|
||||||
(if password.selector == "@"
|
|
||||||
then ""
|
|
||||||
else " | tail -n +2 | yq -r '.${password.selector}'")
|
|
||||||
);
|
|
||||||
readPasswordFile = password: (readPassword password) + (lib.strings.optionalString (password.transform != null) "| ${password.transform}");
|
|
||||||
passwords = builtins.attrValues config.vivarium.passwords;
|
|
||||||
passwordFiles = builtins.attrValues config.vivarium.passwordFiles;
|
|
||||||
generatePassword = password: ''
|
|
||||||
if [ ! -f "$PASSWORD_STORE_DIR/${password.path}.gpg" ]
|
|
||||||
then
|
|
||||||
${password.generator} | pass insert -m "${password.path}"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
ensurePassword = password:
|
|
||||||
(lib.optionalString (password.generator != null) (generatePassword password)) + ''
|
|
||||||
${readPassword password} > /dev/null
|
|
||||||
'';
|
|
||||||
pipeSubstitute = k: v: " | K='${k}' V=\"$(${v})\" awk '{ gsub (ENVIRON[\"K\"], ENVIRON[\"V\"]); print }'";
|
|
||||||
renderPasswordFile = passwordFile: "echo ${lib.strings.escapeShellArg passwordFile.text} ${lib.strings.concatStrings (map
|
|
||||||
(password: pipeSubstitute password.variable (readPasswordFile password))
|
|
||||||
(lib.attrsets.attrValues passwordFile.passwords))}";
|
|
||||||
installPasswordFile = passwordFile: ''
|
|
||||||
sudo mkdir -p "${builtins.dirOf passwordFile.path}"
|
|
||||||
${renderPasswordFile passwordFile} | sudo tee ${passwordFile.path} > /dev/null
|
|
||||||
'';
|
|
||||||
fixPermissionsPasswordFile = passwordFile: ''
|
|
||||||
sudo chown ${passwordFile.owner}:${passwordFile.group} ${passwordFile.path}
|
|
||||||
sudo chmod ${passwordFile.mode} ${passwordFile.path}
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = {
|
|
||||||
system.extraSystemBuilderCmds = ''
|
|
||||||
ln -s ${pkgs.writeShellApplication {
|
|
||||||
name = "generate-passwords";
|
|
||||||
text = ''
|
|
||||||
test -d "$PASSWORD_STORE_DIR"
|
|
||||||
'' + lib.strings.concatLines (builtins.map ensurePassword passwords);
|
|
||||||
}}/bin/generate-passwords $out/bin/generate-passwords
|
|
||||||
ln -s ${pkgs.writeShellApplication {
|
|
||||||
name = "install-passwords";
|
|
||||||
text = lib.strings.concatStrings (builtins.map installPasswordFile passwordFiles);
|
|
||||||
}}/bin/install-passwords $out/bin/install-passwords
|
|
||||||
ln -s ${pkgs.writeShellApplication {
|
|
||||||
name = "fix-permissions-passwords";
|
|
||||||
text = lib.strings.concatStrings (builtins.map fixPermissionsPasswordFile passwordFiles);
|
|
||||||
}}/bin/fix-permissions-passwords $out/bin/fix-permissions-passwords
|
|
||||||
'';
|
|
||||||
vivarium.passwords =
|
|
||||||
let
|
|
||||||
passwordTypes = lib.lists.flatten (map (f: builtins.attrValues f.passwords) passwordFiles);
|
|
||||||
password = passwordType: {
|
|
||||||
${passwordType.path} = {
|
|
||||||
inherit (passwordType) selector generator;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
passwords = map password passwordTypes;
|
|
||||||
in
|
|
||||||
lib.attrsets.mergeAttrsList passwords;
|
|
||||||
};
|
|
||||||
options = {
|
|
||||||
# Using vivarium because that's where it's from, and we don't want it in home manager's frogeye
|
|
||||||
# TODO Make this cleaner, merge the two, somehow
|
|
||||||
vivarium =
|
|
||||||
let
|
|
||||||
defaultvar = "@PASSWORD@";
|
|
||||||
passwordTypeCommon = {
|
|
||||||
selector = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = "If unset, selects the first line. If '@', select everything. If any other value, will parse the password metadata as YML and use selector (yq).";
|
|
||||||
};
|
|
||||||
generator = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = "${lib.getExe pkgs.pwgen} -s 32";
|
|
||||||
description = "Command to generate the password. Won't work when selector is set to read metadata.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
hostConfig = config;
|
|
||||||
passwordTypeFile = { name, config, ... }: {
|
|
||||||
options = passwordTypeCommon // {
|
|
||||||
variable = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = name;
|
|
||||||
description = "String in the template that will be substituted by the actual password";
|
|
||||||
};
|
|
||||||
transform = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Shell command to transform the password with before substitution";
|
|
||||||
};
|
|
||||||
path = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
description = "Path to the password store entry";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
passwords = lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
|
||||||
options = passwordTypeCommon // {
|
|
||||||
path = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = name;
|
|
||||||
description = "Path to the password store entry";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
passwordFiles =
|
|
||||||
lib.mkOption {
|
|
||||||
default = { };
|
|
||||||
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: {
|
|
||||||
options = {
|
|
||||||
path = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = name;
|
|
||||||
description = "Where to place the file.";
|
|
||||||
};
|
|
||||||
mode = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "0400";
|
|
||||||
description = "Unix permission";
|
|
||||||
};
|
|
||||||
owner = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "root";
|
|
||||||
description = "Owner of the secret file";
|
|
||||||
};
|
|
||||||
group = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "root";
|
|
||||||
description = "Group of the secret file";
|
|
||||||
};
|
|
||||||
text = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = defaultvar;
|
|
||||||
description = "Content of the template used to make the file. Exclusive with `template`.";
|
|
||||||
};
|
|
||||||
passwords = lib.mkOption {
|
|
||||||
default = lib.optionalAttrs (config.password != null) { ${defaultvar} = config.password; };
|
|
||||||
type = lib.types.attrsOf (lib.types.submodule passwordTypeFile);
|
|
||||||
description = "Paths to passwords that will substitute the variables in the template. Exclusive with `password`";
|
|
||||||
};
|
|
||||||
password = lib.mkOption {
|
|
||||||
type = lib.types.submodule ({ ... }@args: passwordTypeFile (args // { name = defaultvar; }));
|
|
||||||
description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -39,14 +39,7 @@ then
|
||||||
fi
|
fi
|
||||||
if [ "$verb" = "test" ] || [ "$verb" = "switch" ] || [ "$confirm" = "y" ]
|
if [ "$verb" = "test" ] || [ "$verb" = "switch" ] || [ "$confirm" = "y" ]
|
||||||
then
|
then
|
||||||
# Generate passwords first. If there's a missing one that cannot be generated, we'll know before anything is written
|
|
||||||
"$toplevel/bin/generate-passwords"
|
|
||||||
# Install the passwords to their respective directories
|
|
||||||
"$toplevel/bin/install-passwords"
|
|
||||||
sudo nixos-rebuild --flake "$self#$HOSTNAME" test "${specialisationArgs[@]}" "$@"
|
sudo nixos-rebuild --flake "$self#$HOSTNAME" test "${specialisationArgs[@]}" "$@"
|
||||||
# Fix passwords permission. After install, so it can use new users
|
|
||||||
"$toplevel/bin/fix-permissions-passwords"
|
|
||||||
# TODO Install passwords with correct permissions during activation
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set as boot
|
# Set as boot
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
{ pkgs, lib, config, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.services.syncthing;
|
|
||||||
service = "syncthing";
|
|
||||||
secretsDir = "/etc/secrets/${service}";
|
|
||||||
password = {
|
|
||||||
path = "syncthing/${config.networking.hostName}";
|
|
||||||
selector = "@";
|
|
||||||
generator = ''(t="$(mktemp -d)" && ${lib.getExe pkgs.syncthing} generate --home="$t" &> /dev/null && cat "$t"/{cert,key}.pem && rm -rf "$t")'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.${service} = {
|
|
||||||
guiAddress = "127.0.0.1:8385"; # DEBUG
|
|
||||||
|
|
||||||
openDefaultPorts = true;
|
|
||||||
configDir = "/var/lib/${service}";
|
|
||||||
databaseDir = "/var/cache/${service}";
|
|
||||||
dataDir = cfg.databaseDir; # Don't really care
|
|
||||||
|
|
||||||
key = "${secretsDir}/key.pem";
|
|
||||||
cert = "${secretsDir}/cert.pem";
|
|
||||||
};
|
|
||||||
systemd.services.${service} = {
|
|
||||||
serviceConfig.ExecStartPre = [
|
|
||||||
"+${pkgs.writeShellScript "syncthing-create-folders" ''
|
|
||||||
install -Dm700 -o ${cfg.user} -g ${cfg.group} -d ${cfg.configDir}
|
|
||||||
install -Dm700 -o ${cfg.user} -g ${cfg.group} -d ${cfg.databaseDir}
|
|
||||||
''}"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
vivarium.passwordFiles = {
|
|
||||||
${cfg.key}.password = password // {
|
|
||||||
transform = "${lib.getExe pkgs.openssl} pkey";
|
|
||||||
};
|
|
||||||
${cfg.cert}.password = password // {
|
|
||||||
transform = "${lib.getExe pkgs.openssl} x509";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in a new issue