functional HELL

This commit is contained in:
Jakub Kropáček 2025-01-07 20:05:09 +01:00
parent 6b54f0bc42
commit 8afcfba1d9
6 changed files with 62 additions and 21 deletions

View file

@ -2,6 +2,9 @@
{ {
kropcloud = { kropcloud = {
networking.enable = false; networking.enable = false;
admin.password = "changeme"; admin = {
password = "changeme";
sudoRequirePassword = false;
};
}; };
} }

View file

@ -19,12 +19,19 @@ in
default = null; default = null;
description = "Password for the admin user. Should be used only for initial setup."; description = "Password for the admin user. Should be used only for initial setup.";
}; };
sudoRequirePassword = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Require password for sudo. Should be used only for initial setup.";
};
}; };
config = { config = {
age.secrets.mypassword.file = ../../secrets/mypassword.age; age.secrets.mypassword.file = ../../secrets/mypassword.age;
security.sudo.wheelNeedsPassword = cfg.sudoRequirePassword;
# Define the admin user # Define the admin user
users = { users = {
mutableUsers = false; mutableUsers = false;

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import json import json
import ipaddress import socket
import time import time
from subprocess import check_output from subprocess import check_output
@ -16,10 +16,10 @@ def _get_available_machines() -> list:
def _validate_ip(ip: str) -> bool: def _validate_ip(ip: str) -> bool:
try: try:
ipaddress.ip_address(ip) socket.inet_aton(ip)
return True
except ValueError:
return False return False
except socket.error:
return True
def _check_ssh_connection(ip: str) -> bool: def _check_ssh_connection(ip: str) -> bool:
@ -29,6 +29,8 @@ def _check_ssh_connection(ip: str) -> bool:
except Exception: except Exception:
return False return False
def add_key_to_secrets(key: str):
def bootstrap_machine(ip: str): def bootstrap_machine(ip: str):
check_output( check_output(
@ -50,7 +52,22 @@ def get_ssh_key(ip: str) -> str:
""" """
This function uses machines ssh-keyscan to get the ssh key and then get the ed25519 key This function uses machines ssh-keyscan to get the ssh key and then get the ed25519 key
""" """
ssh_keys = check_output(
[
"ssh-keyscan",
"-q",
"-t",
"ed25519",
ip,
]
).decode("utf-8").strip().splitlines()
if len(ssh_keys) != 1:
raise ValueError("Exactly one key should be returned")
key = ssh_keys.pop().lstrip(f"{ip} ").strip()
return key
def get_machine_config(machine_name: str) -> dict: def get_machine_config(machine_name: str) -> dict:
output = check_output( output = check_output(
@ -82,18 +99,24 @@ def main() -> int:
raise ValueError(f"Invalid IP address {args.machine_ip}") raise ValueError(f"Invalid IP address {args.machine_ip}")
machine_config = get_machine_config(machine_name) machine_config = get_machine_config(machine_name)
print(machine_config)
# We are bootstraping the machine first because we need their ssh keys # We are bootstraping the machine first because we need their ssh keys
print(f"Bootstrapping machine {args.machine_ip}")
bootstrap_machine() bootstrap_machine()
print("Machine bootstrapped")
print("Waiting for ssh connection")
while not _check_ssh_connection(): while not _check_ssh_connection():
time.sleep(5) time.sleep(5)
print("Machine is up and running")
# # connect and get ssh keys print("Getting ssh key")
ssh_key = get_ssh_key(args.machine_ip)
# ssh_key = get_ssh_key() print("Adding ssh key to secrets")
add_key_to_secrets(ssh_key)
rekey_secrets()
# Add the ssh key to keys in secrets/secrets.nix # Add the ssh key to keys in secrets/keys.json
# and rekey the secrets # and rekey the secrets
# install_machine() # install_machine()

13
secrets/keys.json Normal file
View file

@ -0,0 +1,13 @@
{
"hosts": {
"wenar-nix": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJl0Rdo2kHliBeIiPuiO4kYO5M0VZFNXw4siepV1p6Pj",
"lenar": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOUnlAjPnMwJYgZb7YuholdTxifOEFnAyXVqI+xFlHw6"
},
"servers" : {
"test-server": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID4ioqiTzYe6Y6H0YfFkWyDBbCB25wYs3gKNZIufE/Sn"
},
"secrets": {
"mypassword.age": ["hosts:wenar-nix", "hosts:lenar", "servers:test-server"]
}
}

Binary file not shown.

View file

@ -1,17 +1,12 @@
let let
wenar-nix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJl0Rdo2kHliBeIiPuiO4kYO5M0VZFNXw4siepV1p6Pj"; keyfile = builtins.fromJSON (builtins.readFile ./keys.json);
lenar = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOUnlAjPnMwJYgZb7YuholdTxifOEFnAyXVqI+xFlHw6";
users = [
wenar-nix
lenar
];
test-server = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID4ioqiTzYe6Y6H0YfFkWyDBbCB25wYs3gKNZIufE/Sn"; splitString = delim: str: builtins.filter builtins.isString (builtins.split delim str);
systems = [
test-server getKey = pair: keyfile.${builtins.elemAt pair 0}.${builtins.elemAt pair 1};
];
allKeys = users ++ systems; getKeys = secretName: builtins.map (x: getKey (splitString ":" x)) keyfile.secrets.${secretName};
in in
{ {
"mypassword.age".publicKeys = allKeys; "mypassword.age".publicKeys = getKeys "mypassword.age";
} }