feat: get to a solid bootstrap on public ssh
This commit is contained in:
parent
642869ce9b
commit
3850948f71
27 changed files with 262 additions and 865 deletions
211
flake.nix
211
flake.nix
|
|
@ -16,14 +16,6 @@
|
|||
url = "github:serokell/deploy-rs";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixos-anywhere = {
|
||||
url = "github:nix-community/nixos-anywhere";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
|
|
@ -32,8 +24,6 @@
|
|||
nixpkgs,
|
||||
agenix,
|
||||
deploy-rs,
|
||||
disko,
|
||||
nixos-anywhere,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
|
@ -45,7 +35,14 @@
|
|||
wikiName = "Noisebridge";
|
||||
baseDomain = "noisebridge.net";
|
||||
replicaSubdomain = "replica";
|
||||
sshUser = "root";
|
||||
sshUser = "jet";
|
||||
adminUsers = {
|
||||
jet = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu jetthomaspham@gmail.com"
|
||||
];
|
||||
};
|
||||
};
|
||||
primaryHostName = "main-wiki";
|
||||
replicaHostName = "replica-wiki";
|
||||
|
||||
|
|
@ -58,11 +55,11 @@
|
|||
hosts = {
|
||||
primary = {
|
||||
nixosName = primaryHostName;
|
||||
tailscaleName = primaryHostName;
|
||||
publicIpv4 = "134.199.221.52";
|
||||
};
|
||||
replica = {
|
||||
nixosName = replicaHostName;
|
||||
tailscaleName = replicaHostName;
|
||||
publicIpv4 = "167.99.174.109";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -82,12 +79,8 @@
|
|||
publicDomain = mkPublicDomain role;
|
||||
};
|
||||
|
||||
mkHost =
|
||||
{
|
||||
hostMeta,
|
||||
hostModule,
|
||||
roleModules,
|
||||
}:
|
||||
mkDeployHost =
|
||||
hostModule: hostMeta:
|
||||
lib.nixosSystem {
|
||||
inherit system;
|
||||
specialArgs = {
|
||||
|
|
@ -95,16 +88,11 @@
|
|||
};
|
||||
modules = [
|
||||
agenix.nixosModules.default
|
||||
disko.nixosModules.disko
|
||||
hostModule
|
||||
./disk-config.nix
|
||||
./modules/common.nix
|
||||
./modules/security.nix
|
||||
./modules/tailscale.nix
|
||||
./modules/caddy.nix
|
||||
./modules/mediawiki-base.nix
|
||||
]
|
||||
++ roleModules;
|
||||
./modules/admin-users.nix
|
||||
./modules/deploy-ssh.nix
|
||||
];
|
||||
};
|
||||
|
||||
primaryMeta = mkHostMeta "primary";
|
||||
|
|
@ -112,40 +100,28 @@
|
|||
in
|
||||
{
|
||||
nixosConfigurations = {
|
||||
main-wiki = mkHost {
|
||||
hostMeta = primaryMeta;
|
||||
hostModule = ./hosts/main-wiki;
|
||||
roleModules = [
|
||||
./modules/wiki-primary/mysql.nix
|
||||
./modules/wiki-primary/mediawiki.nix
|
||||
];
|
||||
};
|
||||
main-wiki = mkDeployHost ./hosts/main-wiki.nix primaryMeta;
|
||||
|
||||
replica-wiki = mkHost {
|
||||
hostMeta = replicaMeta;
|
||||
hostModule = ./hosts/replica-wiki;
|
||||
roleModules = [
|
||||
./modules/wiki-replica/mysql.nix
|
||||
./modules/wiki-replica/mediawiki.nix
|
||||
];
|
||||
};
|
||||
replica-wiki = mkDeployHost ./hosts/replica-wiki.nix replicaMeta;
|
||||
};
|
||||
|
||||
deploy.nodes = {
|
||||
main-wiki = {
|
||||
hostname = primaryMeta.tailscaleName;
|
||||
hostname = primaryMeta.publicIpv4;
|
||||
remoteBuild = true;
|
||||
sshUser = siteConfig.sshUser;
|
||||
profiles.system = {
|
||||
user = siteConfig.sshUser;
|
||||
sshUser = siteConfig.sshUser;
|
||||
user = "root";
|
||||
path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.main-wiki;
|
||||
};
|
||||
};
|
||||
|
||||
replica-wiki = {
|
||||
hostname = replicaMeta.tailscaleName;
|
||||
hostname = replicaMeta.publicIpv4;
|
||||
remoteBuild = true;
|
||||
sshUser = siteConfig.sshUser;
|
||||
profiles.system = {
|
||||
user = siteConfig.sshUser;
|
||||
sshUser = siteConfig.sshUser;
|
||||
user = "root";
|
||||
path = deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.replica-wiki;
|
||||
};
|
||||
};
|
||||
|
|
@ -175,129 +151,19 @@
|
|||
|
||||
bootstrap-host = {
|
||||
type = "app";
|
||||
program = "${pkgs.writeShellScript "bootstrap-host" ''
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
nix run .#bootstrap-host -- <main-wiki|replica-wiki> <target-host> [ssh-identity-file]
|
||||
nix run .#bootstrap-host -- <main-target-host> <replica-target-host> [ssh-identity-file]
|
||||
|
||||
Examples:
|
||||
nix run .#bootstrap-host -- main-wiki root@203.0.113.10 ~/.ssh/do-bootstrap
|
||||
nix run .#bootstrap-host -- root@203.0.113.10 root@203.0.113.11 ~/.ssh/do-bootstrap
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo_root="$(pwd)"
|
||||
if [ ! -f "$repo_root/flake.nix" ]; then
|
||||
printf 'Run bootstrap-host from the repo root\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ssh_identity_file=""
|
||||
main_target=""
|
||||
replica_target=""
|
||||
selected_host=""
|
||||
|
||||
case "$1" in
|
||||
main-wiki|replica-wiki)
|
||||
selected_host="$1"
|
||||
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
if [ "$selected_host" = "main-wiki" ]; then
|
||||
main_target="$2"
|
||||
else
|
||||
replica_target="$2"
|
||||
fi
|
||||
ssh_identity_file="''${3:-}"
|
||||
;;
|
||||
*)
|
||||
main_target="$1"
|
||||
replica_target="$2"
|
||||
ssh_identity_file="''${3:-}"
|
||||
;;
|
||||
esac
|
||||
|
||||
install_root="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "$install_root"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
ensure_host_key() {
|
||||
local host_name="$1"
|
||||
local private_key_file="$repo_root/.bootstrap/$host_name/host.age"
|
||||
local public_key_file="$repo_root/secrets/hosts/$host_name.age.pub"
|
||||
local public_key
|
||||
|
||||
mkdir -p "$(dirname "$private_key_file")" "$(dirname "$public_key_file")"
|
||||
|
||||
if [ ! -s "$private_key_file" ]; then
|
||||
public_key="$(${pkgs.age}/bin/age-keygen -o "$private_key_file" | sed 's/^Public key: //')"
|
||||
chmod 600 "$private_key_file"
|
||||
printf 'Generated host age key for %s\n' "$host_name"
|
||||
else
|
||||
public_key="$(${pkgs.age}/bin/age-keygen -y "$private_key_file")"
|
||||
printf 'Reused existing host age key for %s\n' "$host_name"
|
||||
fi
|
||||
|
||||
printf '%s\n' "$public_key" > "$public_key_file"
|
||||
}
|
||||
|
||||
run_bootstrap() {
|
||||
local host_name="$1"
|
||||
local target_host="$2"
|
||||
local private_key_file="$repo_root/.bootstrap/$host_name/host.age"
|
||||
local -a nixos_anywhere_args
|
||||
|
||||
mkdir -p "$install_root/var/lib/agenix"
|
||||
${pkgs.coreutils}/bin/install -m 0400 "$private_key_file" "$install_root/var/lib/agenix/host.age"
|
||||
|
||||
nixos_anywhere_args=(
|
||||
--extra-files "$install_root"
|
||||
--flake "path:$repo_root#$host_name"
|
||||
)
|
||||
|
||||
if [ -n "$ssh_identity_file" ]; then
|
||||
nixos_anywhere_args+=( -i "$ssh_identity_file" )
|
||||
fi
|
||||
|
||||
printf 'Bootstrapping %s onto %s\n' "$host_name" "$target_host"
|
||||
${
|
||||
nixos-anywhere.packages.${system}.default
|
||||
}/bin/nixos-anywhere "''${nixos_anywhere_args[@]}" "$target_host"
|
||||
rm -f "$install_root/var/lib/agenix/host.age"
|
||||
}
|
||||
|
||||
if [ -n "$main_target" ]; then
|
||||
ensure_host_key main-wiki
|
||||
fi
|
||||
if [ -n "$replica_target" ]; then
|
||||
ensure_host_key replica-wiki
|
||||
fi
|
||||
|
||||
printf 'Rekeying agenix secrets\n'
|
||||
${agenix.packages.${system}.default}/bin/agenix -r
|
||||
|
||||
if [ -n "$main_target" ]; then
|
||||
run_bootstrap main-wiki "$main_target"
|
||||
fi
|
||||
if [ -n "$replica_target" ]; then
|
||||
run_bootstrap replica-wiki "$replica_target"
|
||||
fi
|
||||
|
||||
printf '\nBootstrap complete. The hosts should now join Tailscale using their configured hostnames.\n'
|
||||
''}";
|
||||
meta.description = "Install NixOS on one or both raw hosts and seed agenix identities";
|
||||
program = "${pkgs.writeShellScript "bootstrap-host" (
|
||||
builtins.replaceStrings
|
||||
[ "@ADMIN_KEYS@" ]
|
||||
[
|
||||
(lib.concatMapStringsSep "\n" (key: " \"${key}\"") (
|
||||
lib.flatten (
|
||||
lib.mapAttrsToList (_: userCfg: userCfg.openssh.authorizedKeys.keys or [ ]) siteConfig.adminUsers
|
||||
)
|
||||
))
|
||||
]
|
||||
(builtins.readFile ./scripts/bootstrap-host.sh)
|
||||
)}";
|
||||
meta.description = "Convert one or both Ubuntu DigitalOcean hosts into a minimal NixOS bootstrap config with nixos-infect";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -305,7 +171,6 @@
|
|||
packages = with pkgs; [
|
||||
agenix.packages.${system}.default
|
||||
deploy-rs.packages.${system}.default
|
||||
nixos-anywhere.packages.${system}.default
|
||||
mariadb.client
|
||||
rsync
|
||||
curl
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue