meow
This commit is contained in:
parent
93a675c06a
commit
9ca7a8d8f6
20 changed files with 631 additions and 194 deletions
51
secrets/deploy-secrets.py
Normal file
51
secrets/deploy-secrets.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
import json
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("flake")
|
||||
parser.add_argument("-f", "--force", action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
NIX_OUTPUT_JSON_PATH = subprocess.run(["nix", "build", f"{args.flake}.config.xyno.secret-output", "--no-link")
|
||||
HOSTNAME = subprocess.run(["nix", "eval", f"{args.flake}.config.networking.hostName", "--raw"])
|
||||
|
||||
nix_output_json
|
||||
|
||||
with open(NIX_OUTPUT_JSON_PATH, "r") as f:
|
||||
nix_output_json = json.load(f)
|
||||
|
||||
def run_ssh(command):
|
||||
return subprocess.run("ssh", HOSTNAME, command)
|
||||
|
||||
def check_tpm():
|
||||
return run_ssh("systemd-analyze has-tpm2").returncode == 0
|
||||
|
||||
def push_secret(secret_name, secret_content):
|
||||
|
||||
if !args.force && secret_name in run_ssh("systemd-creds list"):
|
||||
print(f"[INFO] secret {secret_name} exists on target, skipping")
|
||||
print(f"[INFO] run with --force to skip")
|
||||
return
|
||||
|
||||
command
|
||||
if secret_content["random"] != null:
|
||||
command = f"openssl rand -hex {secret_content["random"]} | systemd-creds encrypt - {secret_name}"
|
||||
else if secret_content["ageFile"] != null:
|
||||
secret_output = subprocess.run(["rage", "-d", secret_content["ageFile"]])
|
||||
command = f"echo '{secret_output}' | systemd-creds encrypt - {secret_name}"
|
||||
else if secret_content["command"] != null:
|
||||
secret_output = subprocess.run(["sh", "-c", secret_content["command"]])
|
||||
command = f"echo '{secret_output}' | systemd-creds encrypt - {secret_name}"
|
||||
else:
|
||||
print(f"[ERROR] no secret content set for {secret_name}: {secret_content}")
|
||||
return
|
||||
run_ssh(command)
|
||||
|
||||
|
||||
|
||||
for secret_name, secret_content in nix_output_json:
|
||||
push_secret(secret_name,secret_content)
|
||||
56
secrets/nixos-module.nix
Normal file
56
secrets/nixos-module.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.xyno.secrets;
|
||||
json = builtins.toJSON cfg;
|
||||
|
||||
in
|
||||
{
|
||||
options.xyno.secret-output = lib.mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
options.xyno.secrets = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
random = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
have the secret be a random hex string with n bytes
|
||||
'';
|
||||
};
|
||||
ageFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
have the secret be a age encrypted file
|
||||
'';
|
||||
};
|
||||
command = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
have the secret be the output of a command (impure grrrrr)
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
config = {
|
||||
systemd.tpm2.enable = true;
|
||||
boot.initrd.systemd.tpm2.enable = true;
|
||||
# TODO: ensure secrets are loaded in activation script
|
||||
|
||||
xyno.secret-output = pkgs.writeFile "xyno-secret.json" json;
|
||||
environment.systemPackages = [
|
||||
pkgs.openssl # needed for random secrets
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue