Compare commits
No commits in common. "main" and "license-mit" have entirely different histories.
main
...
license-mi
17 changed files with 7 additions and 548 deletions
|
@ -46,12 +46,6 @@ let
|
||||||
fi
|
fi
|
||||||
'') (lib.attrValues gen.files)}
|
'') (lib.attrValues gen.files)}
|
||||||
|
|
||||||
# outputs
|
|
||||||
out=$(mktemp -d)
|
|
||||||
trap 'rm -rf $out' EXIT
|
|
||||||
export out
|
|
||||||
mkdir -p "$out"
|
|
||||||
|
|
||||||
if [ $all_files_missing = false ] && [ $all_files_present = false ] ; then
|
if [ $all_files_missing = false ] && [ $all_files_present = false ] ; then
|
||||||
echo "Inconsistent state for generator: ${gen.name}"
|
echo "Inconsistent state for generator: ${gen.name}"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -86,6 +80,12 @@ let
|
||||||
'') (lib.attrValues config.vars.generators.${input}.files)}
|
'') (lib.attrValues config.vars.generators.${input}.files)}
|
||||||
'') gen.dependencies}
|
'') gen.dependencies}
|
||||||
|
|
||||||
|
# outputs
|
||||||
|
out=$(mktemp -d)
|
||||||
|
trap 'rm -rf $out' EXIT
|
||||||
|
export out
|
||||||
|
mkdir -p "$out"
|
||||||
|
|
||||||
(
|
(
|
||||||
# prepare PATH
|
# prepare PATH
|
||||||
unset PATH
|
unset PATH
|
||||||
|
@ -112,15 +112,8 @@ let
|
||||||
mkdir -p "$(dirname "$OUT_FILE")"
|
mkdir -p "$(dirname "$OUT_FILE")"
|
||||||
mv "$out"/${file.name} "$OUT_FILE"
|
mv "$out"/${file.name} "$OUT_FILE"
|
||||||
'') (lib.attrValues gen.files)}
|
'') (lib.attrValues gen.files)}
|
||||||
fi
|
|
||||||
|
|
||||||
# move the files to the correct location
|
|
||||||
${lib.concatMapStringsSep "\n" (file: ''
|
|
||||||
OUT_FILE="$OUT_DIR"/${if file.secret then "secret" else "public"}/${file.generator}/${file.name}
|
|
||||||
chown ${file.owner}:${file.group} "''${OUT_FILE}"
|
|
||||||
chmod ${file.mode} "''${OUT_FILE}"
|
|
||||||
'') (lib.attrValues gen.files)}
|
|
||||||
rm -rf "$out"
|
rm -rf "$out"
|
||||||
|
fi
|
||||||
'') sortedGenerators}
|
'') sortedGenerators}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -145,13 +138,5 @@ in
|
||||||
generate-vars
|
generate-vars
|
||||||
];
|
];
|
||||||
system.build.generate-vars = generate-vars;
|
system.build.generate-vars = generate-vars;
|
||||||
|
|
||||||
systemd.services.generate-vars = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "default.target" ];
|
|
||||||
description = "generate needed secrets";
|
|
||||||
path = [ generate-vars ];
|
|
||||||
serviceConfig.ExecStart = "${generate-vars}/bin/generate-vars";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
in {
|
in {
|
||||||
nixosModules.default = { imports = [ ./options.nix ]; };
|
nixosModules.default = { imports = [ ./options.nix ]; };
|
||||||
nixosModules.backend-on-machine = { imports = [ ./backends/on-machine.nix ]; };
|
nixosModules.backend-on-machine = { imports = [ ./backends/on-machine.nix ]; };
|
||||||
nixosModules.generators = { imports = [ ./generators ]; };
|
|
||||||
# TODO fix tests
|
# TODO fix tests
|
||||||
checks = forAllSystems (system: let
|
checks = forAllSystems (system: let
|
||||||
tests = {
|
tests = {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./disk-id
|
|
||||||
./garage
|
|
||||||
./machine-id
|
|
||||||
./root-password
|
|
||||||
./sshd
|
|
||||||
./state-version
|
|
||||||
./user-password
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.vars.disk-id;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.vars.disk-id.enable = lib.mkEnableOption "Generates a uuid for use in disk device naming";
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
vars.generators.disk-id = {
|
|
||||||
files.diskId.secret = false;
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.bash
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
uuid=$(bash ${./uuid4.sh})
|
|
||||||
|
|
||||||
# Remove the hyphens from the UUID
|
|
||||||
uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-')
|
|
||||||
|
|
||||||
echo -n "$uuid_no_hyphens" > "$out/diskId"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
disko.devices.disk."main".name = "main-" + config.vars.generators.disk-id.files.diskId.value;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Read 16 bytes from /dev/urandom
|
|
||||||
uuid=$(dd if=/dev/urandom bs=1 count=16 2>/dev/null | od -An -tx1 | tr -d ' \n')
|
|
||||||
|
|
||||||
# Break the UUID into pieces and apply the required modifications
|
|
||||||
byte6=${uuid:12:2}
|
|
||||||
byte8=${uuid:16:2}
|
|
||||||
|
|
||||||
# Construct the correct version and variant
|
|
||||||
hex_byte6=$(printf "%x" $((0x$byte6 & 0x0F | 0x40)))
|
|
||||||
hex_byte8=$(printf "%x" $((0x$byte8 & 0x3F | 0x80)))
|
|
||||||
|
|
||||||
# Rebuild the UUID with the correct fields
|
|
||||||
uuid_v4="${uuid:0:12}${hex_byte6}${uuid:14:2}${hex_byte8}${uuid:18:14}"
|
|
||||||
|
|
||||||
# Format the UUID correctly 8-4-4-4-12
|
|
||||||
uuid_formatted="${uuid_v4:0:8}-${uuid_v4:8:4}-${uuid_v4:12:4}-${uuid_v4:16:4}-${uuid_v4:20:12}"
|
|
||||||
|
|
||||||
echo -n "$uuid_formatted"
|
|
|
@ -1,59 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.vars.garage;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.vars.garage.enable = lib.mkEnableOption ''
|
|
||||||
S3-compatible object store for small self-hosted geo-distributed deployments.
|
|
||||||
|
|
||||||
This module generates garage-specific keys automatically.
|
|
||||||
|
|
||||||
Options: [NixosModuleOptions](https://search.nixos.org/options?channel=unstable&size=50&sort=relevance&type=packages&query=garage)
|
|
||||||
Documentation: https://garagehq.deuxfleurs.fr/
|
|
||||||
'';
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
systemd.services.garage.serviceConfig = {
|
|
||||||
LoadCredential = [
|
|
||||||
"rpc_secret_path:${config.vars.generators.garage-shared.files.rpc_secret.path}"
|
|
||||||
"admin_token_path:${config.vars.generators.garage.files.admin_token.path}"
|
|
||||||
"metrics_token_path:${config.vars.generators.garage.files.metrics_token.path}"
|
|
||||||
];
|
|
||||||
Environment = [
|
|
||||||
"GARAGE_ALLOW_WORLD_READABLE_SECRETS=true"
|
|
||||||
"GARAGE_RPC_SECRET_FILE=%d/rpc_secret_path"
|
|
||||||
"GARAGE_ADMIN_TOKEN_FILE=%d/admin_token_path"
|
|
||||||
"GARAGE_METRICS_TOKEN_FILE=%d/metrics_token_path"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.generators.garage = {
|
|
||||||
files.admin_token = { };
|
|
||||||
files.metrics_token = { };
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.openssl
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
openssl rand -base64 -out "$out"/admin_token 32
|
|
||||||
openssl rand -base64 -out "$out"/metrics_token 32
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.generators.garage-shared = {
|
|
||||||
share = true;
|
|
||||||
files.rpc_secret = { };
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.openssl
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
openssl rand -hex -out "$out"/rpc_secret 32
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
var = config.vars.generators.machine-id.files.machineId or { };
|
|
||||||
cfg = config.vars.machine-id;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.vars.machine-id.enable = lib.mkEnableOption "Sets the /etc/machine-id and exposes it as a nix option";
|
|
||||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
|
||||||
(lib.mkIf ((var.value or null) != null) {
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = lib.stringLength var.value == 32;
|
|
||||||
message = "machineId must be exactly 32 characters long.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
boot.kernelParams = [
|
|
||||||
''systemd.machine_id=${var.value}''
|
|
||||||
];
|
|
||||||
environment.etc."machine-id" = {
|
|
||||||
text = var.value;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
{
|
|
||||||
vars.generators.machine-id = {
|
|
||||||
files.machineId.secret = false;
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.bash
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
uuid=$(bash ${./uuid4.sh})
|
|
||||||
|
|
||||||
# Remove the hyphens from the UUID
|
|
||||||
uuid_no_hyphens=$(echo -n "$uuid" | tr -d '-')
|
|
||||||
|
|
||||||
echo -n "$uuid_no_hyphens" > "$out/machineId"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Read 16 bytes from /dev/urandom
|
|
||||||
uuid=$(dd if=/dev/urandom bs=1 count=16 2>/dev/null | od -An -tx1 | tr -d ' \n')
|
|
||||||
|
|
||||||
# Break the UUID into pieces and apply the required modifications
|
|
||||||
byte6=${uuid:12:2}
|
|
||||||
byte8=${uuid:16:2}
|
|
||||||
|
|
||||||
# Construct the correct version and variant
|
|
||||||
hex_byte6=$(printf "%x" $((0x$byte6 & 0x0F | 0x40)))
|
|
||||||
hex_byte8=$(printf "%x" $((0x$byte8 & 0x3F | 0x80)))
|
|
||||||
|
|
||||||
# Rebuild the UUID with the correct fields
|
|
||||||
uuid_v4="${uuid:0:12}${hex_byte6}${uuid:14:2}${hex_byte8}${uuid:18:14}"
|
|
||||||
|
|
||||||
# Format the UUID correctly 8-4-4-4-12
|
|
||||||
uuid_formatted="${uuid_v4:0:8}-${uuid_v4:8:4}-${uuid_v4:12:4}-${uuid_v4:16:4}-${uuid_v4:20:12}"
|
|
||||||
|
|
||||||
echo -n "$uuid_formatted"
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
options.vars = {
|
|
||||||
unattended = lib.mkEnableOption "Whether to default to generating values unattended, rather than prompting for desired values.";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.vars.root-password;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../options.nix
|
|
||||||
];
|
|
||||||
options.vars.root-password = {
|
|
||||||
enable = lib.mkEnableOption "Automatically generates and configures a password for the root user.";
|
|
||||||
prompt = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = !config.vars.unattended;
|
|
||||||
example = true;
|
|
||||||
description = "Whether the user should be prompted.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
users.mutableUsers = false;
|
|
||||||
users.users.root.hashedPasswordFile =
|
|
||||||
config.vars.generators.root-password.files.password-hash.path;
|
|
||||||
|
|
||||||
vars.generators.root-password = {
|
|
||||||
files.password-hash = {
|
|
||||||
neededFor = "users";
|
|
||||||
};
|
|
||||||
files.password-hash.restartUnits = lib.optional (config.services.userborn.enable) "userborn.service";
|
|
||||||
files.password = {
|
|
||||||
deploy = false;
|
|
||||||
};
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.mkpasswd
|
|
||||||
pkgs.xkcdpass
|
|
||||||
];
|
|
||||||
prompts = lib.mkIf cfg.prompt {
|
|
||||||
password = {
|
|
||||||
type = "hidden";
|
|
||||||
persist = true;
|
|
||||||
description = "You can autogenerate a password, if you leave this prompt blank.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
script = ''
|
|
||||||
prompt_value=${if cfg.prompt then ''$(cat "$prompts"/password)'' else ""}
|
|
||||||
if [[ -n "''${prompt_value-}" ]]; then
|
|
||||||
echo "$prompt_value" | tr -d "\n" > "$out"/password
|
|
||||||
else
|
|
||||||
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > "$out"/password
|
|
||||||
fi
|
|
||||||
mkpasswd -s -m sha-512 < "$out"/password | tr -d "\n" > "$out"/password-hash
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./shared.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./client.nix
|
|
||||||
./server.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
stringSet = list: builtins.attrNames (builtins.groupBy lib.id list);
|
|
||||||
|
|
||||||
domains = stringSet config.vars.sshd.certificate.searchDomains;
|
|
||||||
|
|
||||||
cfg = config.vars.sshd;
|
|
||||||
|
|
||||||
name = config.networking.hostName;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [ ../shared.nix ];
|
|
||||||
options = {
|
|
||||||
vars.sshd = {
|
|
||||||
enable = lib.mkEnableOption "Set up the opensshd service, generating a host key for the machine.";
|
|
||||||
hostKeys.rsa.enable = lib.mkEnableOption "Generate RSA host key";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings.PasswordAuthentication = false;
|
|
||||||
|
|
||||||
settings.HostCertificate = lib.mkIf (
|
|
||||||
cfg.certificate.searchDomains != [ ]
|
|
||||||
) config.vars.generators.openssh-cert.files."ssh.id_ed25519-cert.pub".path;
|
|
||||||
|
|
||||||
hostKeys =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
path = config.vars.generators.openssh.files."ssh.id_ed25519".path;
|
|
||||||
type = "ed25519";
|
|
||||||
}
|
|
||||||
]
|
|
||||||
++ lib.optional cfg.hostKeys.rsa.enable {
|
|
||||||
path = config.vars.generators.openssh-rsa.files."ssh.id_rsa".path;
|
|
||||||
type = "rsa";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.generators.openssh = {
|
|
||||||
files."ssh.id_ed25519" = { };
|
|
||||||
files."ssh.id_ed25519.pub".secret = false;
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.openssh
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
ssh-keygen -t ed25519 -N "" -f "$out"/ssh.id_ed25519
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.ssh.knownHosts.sshd-self-ed25519 = {
|
|
||||||
hostNames = [
|
|
||||||
"localhost"
|
|
||||||
config.networking.hostName
|
|
||||||
] ++ (lib.optional (config.networking.domain != null) config.networking.fqdn);
|
|
||||||
publicKey = config.vars.generators.openssh.files."ssh.id_ed25519.pub".value;
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.generators.openssh-rsa = lib.mkIf config.vars.sshd.hostKeys.rsa.enable {
|
|
||||||
files."ssh.id_rsa" = { };
|
|
||||||
files."ssh.id_rsa.pub".secret = false;
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.openssh
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
ssh-keygen -t rsa -b 4096 -N "" -f "$out"/ssh.id_rsa
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
vars.generators.openssh-cert = lib.mkIf (cfg.certificate.searchDomains != [ ]) {
|
|
||||||
files."ssh.id_ed25519-cert.pub".secret = false;
|
|
||||||
dependencies = [
|
|
||||||
"openssh"
|
|
||||||
"openssh-ca"
|
|
||||||
];
|
|
||||||
validation = {
|
|
||||||
inherit name;
|
|
||||||
domains = lib.genAttrs config.vars.sshd.certificate.searchDomains lib.id;
|
|
||||||
};
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.openssh
|
|
||||||
pkgs.jq
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
ssh-keygen \
|
|
||||||
-s $in/openssh-ca/id_ed25519 \
|
|
||||||
-I ${name} \
|
|
||||||
-h \
|
|
||||||
-n ${lib.concatMapStringsSep "," (d: "${name}.${d}") domains} \
|
|
||||||
$in/openssh/ssh.id_ed25519.pub
|
|
||||||
mv $in/openssh/ssh.id_ed25519-cert.pub "$out"/ssh.id_ed25519-cert.pub
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.vars.sshd.certificate;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.vars.sshd.certificate = {
|
|
||||||
enable = lib.mkEnableOption "Add machines to the known hosts, enabling secure remote access to them over ssh.";
|
|
||||||
searchDomains = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
default = [ ];
|
|
||||||
example = [ "mydomain.com" ];
|
|
||||||
description = "List of domains to include in the certificate. This option will prepend the machine name in front of each domain before adding it to the certificate.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
vars.generators.openssh-ca =
|
|
||||||
lib.mkIf (config.vars.sshd.certificate.searchDomains != [ ])
|
|
||||||
{
|
|
||||||
share = true;
|
|
||||||
files.id_ed25519.deploy = false;
|
|
||||||
files."id_ed25519.pub" = {
|
|
||||||
deploy = false;
|
|
||||||
secret = false;
|
|
||||||
};
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.openssh
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
ssh-keygen -t ed25519 -N "" -f "$out"/id_ed25519
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.ssh.knownHosts.ssh-ca = lib.mkIf (config.vars.sshd.certificate.searchDomains != [ ]) {
|
|
||||||
certAuthority = true;
|
|
||||||
extraHostNames = builtins.map (domain: "*.${domain}") config.vars.sshd.certificate.searchDomains;
|
|
||||||
publicKey = config.vars.generators.openssh-ca.files."id_ed25519.pub".value;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
var = config.vars.generators.state-version.files.version or { };
|
|
||||||
cfg = config.vars.state-version;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.vars.state-version.enable = lib.mkEnableOption "Automatically generate the state version of the nixos installation.";
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
system.stateVersion = lib.mkDefault (lib.removeSuffix "\n" var.value);
|
|
||||||
|
|
||||||
vars.generators.state-version = {
|
|
||||||
files.version = {
|
|
||||||
secret = false;
|
|
||||||
value = lib.mkDefault config.system.nixos.release;
|
|
||||||
};
|
|
||||||
runtimeInputs = [ ];
|
|
||||||
script = ''
|
|
||||||
echo -n ${config.system.stateVersion} > "$out"/version
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
cfg = config.vars.user-password;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
../options.nix
|
|
||||||
];
|
|
||||||
options.vars.user-password = {
|
|
||||||
enable = lib.mkEnableOption ''
|
|
||||||
Automatically generates and configures a password for a user.
|
|
||||||
|
|
||||||
This will set `mutableUsers` to `false`, meaning you can not manage user passwords through `passwd` anymore.
|
|
||||||
'';
|
|
||||||
users = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf (lib.submodule {
|
|
||||||
options = {
|
|
||||||
prompt = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = !config.vars.unattended;
|
|
||||||
example = true;
|
|
||||||
description = "Whether the user should be prompted.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
description = "The users for which to generate passwords.";
|
|
||||||
example = "{ alice = { }; }";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
users.mutableUsers = false;
|
|
||||||
users.users = lib.mapAttrs (userName: _: {
|
|
||||||
hashedPasswordFile = config.vars.generators."user-password-${userName}".files.user-password-hash.path;
|
|
||||||
isNormalUser = lib.mkDefault true;
|
|
||||||
}) cfg.users;
|
|
||||||
|
|
||||||
vars.generators = lib.mapAttrs (userName: user: {
|
|
||||||
"user-password-${userName}" = {
|
|
||||||
files.user-password-hash.neededFor = "users";
|
|
||||||
files.user-password-hash.restartUnits = lib.optional (config.services.userborn.enable) "userborn.service";
|
|
||||||
|
|
||||||
prompts = lib.mkIf user.prompt {
|
|
||||||
"user-password-${userName}" = {
|
|
||||||
type = "hidden";
|
|
||||||
persist = true;
|
|
||||||
description = "You can autogenerate a password, if you leave this prompt blank.";
|
|
||||||
files.user-password.deploy = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.xkcdpass
|
|
||||||
pkgs.mkpasswd
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
prompt_value=${if user.prompt then ''$(cat "$prompts"/user-password)'' else ""}
|
|
||||||
if [[ -n "''${prompt_value-}" ]]; then
|
|
||||||
echo "$prompt_value" | tr -d "\n" > "$out"/user-password
|
|
||||||
else
|
|
||||||
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > "$out"/user-password
|
|
||||||
fi
|
|
||||||
mkpasswd -s -m sha-512 < "$out"/user-password | tr -d "\n" > "$out"/user-password-hash
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}) cfg.users;
|
|
||||||
};
|
|
||||||
}
|
|
15
options.nix
15
options.nix
|
@ -82,21 +82,6 @@
|
||||||
default = generator.config.name;
|
default = generator.config.name;
|
||||||
defaultText = "Name of the generator";
|
defaultText = "Name of the generator";
|
||||||
};
|
};
|
||||||
owner = lib.mkOption {
|
|
||||||
description = "The user name or id that will own the file.";
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "root";
|
|
||||||
};
|
|
||||||
group = lib.mkOption {
|
|
||||||
description = "The group name or id that will own the file.";
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "root";
|
|
||||||
};
|
|
||||||
mode = lib.mkOption {
|
|
||||||
description = "The unix file mode of the file. Must be a 4-digit octal number.";
|
|
||||||
type = lib.types.strMatching "^[0-7]{4}$";
|
|
||||||
default = if file.config.group == "root" then "0400" else "0440";
|
|
||||||
};
|
|
||||||
deploy = lib.mkOption {
|
deploy = lib.mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Whether the file should be deployed to the target machine.
|
Whether the file should be deployed to the target machine.
|
||||||
|
|
Loading…
Add table
Reference in a new issue