Archived
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4831c9370 |
+22
-63
@@ -63,6 +63,16 @@ creation_rules:
|
|||||||
- *lxc-nix-cache
|
- *lxc-nix-cache
|
||||||
- *proxmox-nix-cache
|
- *proxmox-nix-cache
|
||||||
|
|
||||||
|
# Host keytab for nix-cache FreeIPA enrollment (binary sops file).
|
||||||
|
# Generate with: sops -e --input-type binary /tmp/nix-cache.keytab > secrets/nix-cache.keytab
|
||||||
|
- path_regex: secrets/nix-cache\.keytab$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin
|
||||||
|
- *linode-nix-cache
|
||||||
|
- *lxc-nix-cache
|
||||||
|
- *proxmox-nix-cache
|
||||||
|
|
||||||
- path_regex: secrets/server\.yaml$
|
- path_regex: secrets/server\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
@@ -117,6 +127,16 @@ creation_rules:
|
|||||||
# scripts/secrets/sync-host-keys.sh yet, so whichever variant is actually
|
# scripts/secrets/sync-host-keys.sh yet, so whichever variant is actually
|
||||||
# deployed next needs its recipient added here (and `sops updatekeys` rerun)
|
# deployed next needs its recipient added here (and `sops updatekeys` rerun)
|
||||||
# before it can decrypt this.
|
# before it can decrypt this.
|
||||||
|
# Host keytab for tailscale-router FreeIPA enrollment (binary sops file).
|
||||||
|
# Generated by scripts/ipa/create-nixos-ipa-host-account.sh.
|
||||||
|
- path_regex: secrets/tailscale-router\.keytab$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *admin
|
||||||
|
- *lxc-tailscale-router
|
||||||
|
- *proxmox-tailscale-router
|
||||||
|
- *linode-tailscale-router
|
||||||
|
|
||||||
- path_regex: secrets/gui\.yaml$
|
- path_regex: secrets/gui\.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
@@ -126,72 +146,11 @@ creation_rules:
|
|||||||
- *linode-gui
|
- *linode-gui
|
||||||
- *proxmox-gui
|
- *proxmox-gui
|
||||||
|
|
||||||
# IPA host keytabs (binary sops files).
|
# Host keytab for pxe-boot FreeIPA enrollment (binary sops file).
|
||||||
# Each keytab is encrypted for all platform variants of that host so any
|
# Generated by scripts/ipa/create-nixos-ipa-host-account.sh.
|
||||||
# deployed variant can decrypt it at boot. Run
|
|
||||||
# scripts/ipa/create-nixos-ipa-host-account.sh <hostname> to enroll a new
|
|
||||||
# host and produce the keytab; this section is updated by that script.
|
|
||||||
|
|
||||||
- path_regex: secrets/nix-cache\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *linode-nix-cache
|
|
||||||
- *lxc-nix-cache
|
|
||||||
- *proxmox-nix-cache
|
|
||||||
|
|
||||||
- path_regex: secrets/tailscale-router\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *linode-tailscale-router
|
|
||||||
- *lxc-tailscale-router
|
|
||||||
- *proxmox-tailscale-router
|
|
||||||
|
|
||||||
- path_regex: secrets/pxe-boot\.keytab$
|
- path_regex: secrets/pxe-boot\.keytab$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *admin
|
- *admin
|
||||||
- *lxc-pxe-boot
|
- *lxc-pxe-boot
|
||||||
- *proxmox-pxe-boot
|
- *proxmox-pxe-boot
|
||||||
|
|
||||||
# nixos = the workstation (hosts/nixos/host.nix). All gui platform variants
|
|
||||||
# share the hostname "nixos" and must be able to decrypt at boot.
|
|
||||||
- path_regex: secrets/nixos\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *baremetal-gui
|
|
||||||
- *lxc-gui
|
|
||||||
- *proxmox-gui
|
|
||||||
- *linode-gui
|
|
||||||
|
|
||||||
- path_regex: secrets/server\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *linode-server
|
|
||||||
- *lxc-server
|
|
||||||
- *proxmox-server
|
|
||||||
|
|
||||||
- path_regex: secrets/docker\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *linode-docker
|
|
||||||
- *lxc-docker
|
|
||||||
- *proxmox-docker
|
|
||||||
|
|
||||||
- path_regex: secrets/tor-relay\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *lxc-tor-relay
|
|
||||||
|
|
||||||
- path_regex: secrets/nix-minimal\.keytab$
|
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *admin
|
|
||||||
- *lxc-minimal
|
|
||||||
- *proxmox-minimal
|
|
||||||
- *linode-minimal
|
|
||||||
|
|||||||
Generated
+6
-6
@@ -173,11 +173,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785119570,
|
"lastModified": 1784350909,
|
||||||
"narHash": "sha256-Rgs2xKnGLFWQscxUaXX07oyZeuMDOHEbqDOsgliLFGM=",
|
"narHash": "sha256-ZWyzLbS1yKUTeFJLmdVuWNnHttL333/ldJbEE+KzCrM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "d4fd24667c8cbef124bb70a20380cab75ec8474d",
|
"rev": "4ce190229c73d44536caa7072f6308fb2d8feeb3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -259,11 +259,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1785104993,
|
"lastModified": 1784432872,
|
||||||
"narHash": "sha256-eKbrvPoAOFutbYMdbB3r5EQVmFxKv24iKqHPPUXA0gM=",
|
"narHash": "sha256-n3gKTBIV4ZA5VQpUakffBe3KGu4+mhPoA34rrqS0GkA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "8623c4c20aa4ca2f5fb81510d2944066c3fb0d96",
|
"rev": "fd1462031fdee08f65fd0b4c6b64e22239a77870",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -6,10 +6,15 @@
|
|||||||
name = "nix-cache";
|
name = "nix-cache";
|
||||||
sopsFile = ../../secrets/nix-cache.yaml;
|
sopsFile = ../../secrets/nix-cache.yaml;
|
||||||
})
|
})
|
||||||
|
(import ../../modules/ipa/client.nix {
|
||||||
|
keytabSopsFile = ../../secrets/nix-cache.keytab;
|
||||||
|
caCertFile = ../../certs/ipa-ca.crt;
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = vars.nixCacheHost;
|
hostName = vars.nixCacheHost;
|
||||||
|
domain = vars.homeDomain;
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
||||||
address = vars.nixCacheIp;
|
address = vars.nixCacheIp;
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
{ vars, ... }:
|
{ vars, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
imports = [
|
||||||
|
(import ../../modules/ipa/client.nix {
|
||||||
|
keytabSopsFile = ../../secrets/pxe-boot.keytab;
|
||||||
|
caCertFile = ../../certs/ipa-ca.crt;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "pxe-boot";
|
hostName = "pxe-boot";
|
||||||
|
domain = vars.homeDomain;
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
||||||
address = vars.pxeServerIp;
|
address = vars.pxeServerIp;
|
||||||
|
|||||||
@@ -6,10 +6,15 @@
|
|||||||
name = "tailscale-router";
|
name = "tailscale-router";
|
||||||
sopsFile = ../../secrets/tailscale-router.yaml;
|
sopsFile = ../../secrets/tailscale-router.yaml;
|
||||||
})
|
})
|
||||||
|
(import ../../modules/ipa/client.nix {
|
||||||
|
keytabSopsFile = ../../secrets/tailscale-router.keytab;
|
||||||
|
caCertFile = ../../certs/ipa-ca.crt;
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "tailscale-router";
|
hostName = "tailscale-router";
|
||||||
|
domain = vars.homeDomain;
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
interfaces.${vars.lxcLanInterface}.ipv4.addresses = [{
|
||||||
address = vars.tailscaleRouterIp;
|
address = vars.tailscaleRouterIp;
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
{ config, pkgs, lib, inputs, vars, ... }:
|
{ config, pkgs, lib, inputs, vars, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
|
||||||
../docker/enable-service.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
|
||||||
(final: prev: {
|
|
||||||
docker = prev.docker_29;
|
|
||||||
docker_cli = prev.docker_29;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
inputs.nixos-conf-editor.packages.${pkgs.stdenv.hostPlatform.system}.nixos-conf-editor
|
inputs.nixos-conf-editor.packages.${pkgs.stdenv.hostPlatform.system}.nixos-conf-editor
|
||||||
nodejs
|
nodejs
|
||||||
|
|||||||
@@ -1,7 +1,50 @@
|
|||||||
_:
|
{ config, pkgs, lib, vars, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# Flake attribute names are now <platform>-<buildtype> (e.g. proxmox-docker)
|
||||||
|
# and no longer match networking.hostName, since a host's hostname stays
|
||||||
|
# fixed while the platform backing it can change. Each nixosConfiguration
|
||||||
|
# stamps its own active target name into /etc/flake-target at build time.
|
||||||
|
mySwitchCmd = ''
|
||||||
|
sudo nixos-rebuild switch \
|
||||||
|
--no-write-lock-file \
|
||||||
|
--refresh \
|
||||||
|
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target)
|
||||||
|
'';
|
||||||
|
myTestCmd = ''
|
||||||
|
sudo nixos-rebuild test \
|
||||||
|
--no-write-lock-file \
|
||||||
|
--refresh \
|
||||||
|
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target)
|
||||||
|
'';
|
||||||
|
|
||||||
|
# lxc-* hosts pre-seed their SSH host key at build time (see
|
||||||
|
# modules/platforms/lxc.nix) so sops-nix's .sops.yaml recipient matches on
|
||||||
|
# first boot -- without it, secrets permanently fail to decrypt (see that
|
||||||
|
# file's comment for the confirmed failure). That requires --impure plus
|
||||||
|
# NIXOS_HOST_KEYS_DIR pointing at the repo's host-keys/ dir, same pattern
|
||||||
|
# docs/auto-installer.md uses for the installer ISO. A function, not a
|
||||||
|
# shellAlias, since the target name has to interpolate into the middle of
|
||||||
|
# the flake attribute path, not just append after it. Must be run from the
|
||||||
|
# repo root, same as every other host-keys/ command in this repo.
|
||||||
|
buildImageFn = ''
|
||||||
|
buildImage() {
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "usage: buildImage <flake-target> (e.g. lxc-docker)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build --impure \
|
||||||
|
".#nixosConfigurations.$1.config.system.build.tarball"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in
|
||||||
{
|
{
|
||||||
# Switch-nix, Test-nix, and buildImage are defined system-wide in
|
programs.bash = {
|
||||||
# modules/common/configuration.nix so all users (including IPA accounts)
|
enable = true;
|
||||||
# get them. Add any Home-Manager-only per-user shell config here.
|
shellAliases = {
|
||||||
|
"Switch-nix" = mySwitchCmd;
|
||||||
|
"Test-nix" = myTestCmd;
|
||||||
|
};
|
||||||
|
initExtra = buildImageFn;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,12 @@
|
|||||||
{ config, lib, pkgs, vars, ... }:
|
{ config, lib, pkgs, vars, ... }:
|
||||||
|
|
||||||
let
|
|
||||||
switchCmd = ''
|
|
||||||
sudo nixos-rebuild switch \
|
|
||||||
--no-write-lock-file \
|
|
||||||
--refresh \
|
|
||||||
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target)
|
|
||||||
'';
|
|
||||||
testCmd = ''
|
|
||||||
sudo nixos-rebuild test \
|
|
||||||
--no-write-lock-file \
|
|
||||||
--refresh \
|
|
||||||
--flake git+https://${vars.lanDomain}/beatzaplenty/nixos.git#$(cat /etc/flake-target)
|
|
||||||
'';
|
|
||||||
buildImageFn = ''
|
|
||||||
buildImage() {
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "usage: buildImage <flake-target> (e.g. lxc-docker)" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build --impure \
|
|
||||||
".#nixosConfigurations.$1.config.system.build.tarball"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[
|
[
|
||||||
# Include the results of the hardware scan.
|
# Include the results of the hardware scan.
|
||||||
# ./hardware-configuration.nix
|
# ./hardware-configuration.nix
|
||||||
./set-locale.nix
|
./set-locale.nix
|
||||||
../ipa/client.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# System-wide shell config so all users (including IPA accounts) get the
|
|
||||||
# same management aliases as the local nixos user's Home Manager provides.
|
|
||||||
programs.bash = {
|
|
||||||
shellAliases = {
|
|
||||||
"Switch-nix" = switchCmd;
|
|
||||||
"Test-nix" = testCmd;
|
|
||||||
};
|
|
||||||
interactiveShellInit = buildImageFn;
|
|
||||||
};
|
|
||||||
# Use the GRUB 2 boot loader.
|
# Use the GRUB 2 boot loader.
|
||||||
# boot.loader.grub.enable = true;
|
# boot.loader.grub.enable = true;
|
||||||
#boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
|
#boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, vars, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# virtualisation.docker.enable = true;
|
# virtualisation.docker.enable = true;
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
# experimental = true;
|
# experimental = true;
|
||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
users.users.${vars.primaryUser}.extraGroups = [ "docker" ];
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
docker-compose
|
docker-compose
|
||||||
docker-buildx
|
docker-buildx
|
||||||
|
|||||||
+35
-120
@@ -1,15 +1,34 @@
|
|||||||
# Fully declarative FreeIPA domain membership.
|
# Fully declarative FreeIPA domain membership.
|
||||||
#
|
#
|
||||||
# Imported by modules/common/configuration.nix — no per-host wiring needed.
|
# Configures security.ipa (SSSD, Kerberos, PAM, NSSwitch) and places a
|
||||||
# Enables itself automatically on any host that has a sops-encrypted keytab
|
# pre-provisioned host keytab via sops-nix so no imperative ipa-client-install
|
||||||
# at secrets/<hostname>.keytab; is a no-op for all other hosts.
|
# step is needed after deployment.
|
||||||
#
|
#
|
||||||
# To enroll a new host:
|
# Usage (in a host.nix imports list):
|
||||||
# 0. scripts/secrets/sync-host-keys.sh <flake-target>
|
# (import ../../modules/ipa/client.nix {
|
||||||
# 1. scripts/ipa/create-nixos-ipa-host-account.sh [--ip <addr>] <hostname>
|
# keytabSopsFile = ../../secrets/<hostname>.keytab;
|
||||||
# (adds .sops.yaml rule, runs ipa host-add, encrypts keytab in one step)
|
# caCertFile = ../../certs/ipa-ca.crt; # already committed — do not re-fetch
|
||||||
# 2. git add secrets/<hostname>.keytab .sops.yaml && git commit
|
# })
|
||||||
# 3. Deploy — no further steps required.
|
#
|
||||||
|
# The host.nix networking block must also set:
|
||||||
|
# networking.domain = vars.homeDomain; # needed for Kerberos FQDN
|
||||||
|
# networking.nameservers = [ vars.domainControllerIp ]; # IPA DNS
|
||||||
|
#
|
||||||
|
# One-time operator setup per host (do this BEFORE deploying):
|
||||||
|
#
|
||||||
|
# 0. Generate SSH host keys and the host's age key for sops:
|
||||||
|
# scripts/secrets/sync-host-keys.sh <flake-target>
|
||||||
|
# This must run before step 1 so the host age key is in .sops.yaml
|
||||||
|
# and the keytab can be encrypted for the host to read at boot.
|
||||||
|
#
|
||||||
|
# 1. Add the IPA host account and produce the sops-encrypted keytab:
|
||||||
|
# scripts/ipa/create-nixos-ipa-host-account.sh [--ip <addr>] <hostname>
|
||||||
|
# The script handles ipa host-add, ipa-getkeytab, .sops.yaml patching,
|
||||||
|
# and sops encryption in one step. See the script header for details.
|
||||||
|
#
|
||||||
|
# 2. Wire up the host (see "Usage" above), then deploy:
|
||||||
|
# nixos-rebuild switch (or create-proxmox-resource.sh)
|
||||||
|
# No further manual enrollment steps are required after deployment.
|
||||||
#
|
#
|
||||||
# Manual fallback (if the script isn't usable):
|
# Manual fallback (if the script isn't usable):
|
||||||
# a. On the FreeIPA server: ipa host-add <fqdn> [--ip-address=<ip>] --force
|
# a. On the FreeIPA server: ipa host-add <fqdn> [--ip-address=<ip>] --force
|
||||||
@@ -19,32 +38,27 @@
|
|||||||
# sops -e --input-type binary -i secrets/<host>.keytab
|
# sops -e --input-type binary -i secrets/<host>.keytab
|
||||||
# d. Commit secrets/<host>.keytab and the updated .sops.yaml, then deploy.
|
# d. Commit secrets/<host>.keytab and the updated .sops.yaml, then deploy.
|
||||||
#
|
#
|
||||||
# vars dependencies: homeDomain, ipaServer, domainControllerIp, ipaUser
|
# vars dependencies: homeDomain, ipaServer, domainControllerIp
|
||||||
|
|
||||||
|
{ keytabSopsFile, caCertFile }:
|
||||||
{ config, lib, pkgs, vars, ... }:
|
{ config, lib, pkgs, vars, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
keytabPath = ../../secrets + "/${config.networking.hostName}.keytab";
|
|
||||||
enabled = builtins.pathExists keytabPath;
|
|
||||||
|
|
||||||
realm = lib.strings.toUpper vars.homeDomain;
|
realm = lib.strings.toUpper vars.homeDomain;
|
||||||
fqdn = "${config.networking.hostName}.${vars.homeDomain}";
|
fqdn = "${config.networking.hostName}.${vars.homeDomain}";
|
||||||
# "sweet.home" -> "dc=sweet,dc=home"
|
# "sweet.home" -> "dc=sweet,dc=home"
|
||||||
basedn = lib.strings.concatMapStringsSep "," (c: "dc=${c}") (lib.strings.splitString "." vars.homeDomain);
|
basedn = lib.strings.concatMapStringsSep "," (c: "dc=${c}") (lib.strings.splitString "." vars.homeDomain);
|
||||||
# security.ipa.certificate expects a derivation (package), not a raw path.
|
# security.ipa.certificate expects a derivation (package), not a raw path.
|
||||||
caCertPkg = pkgs.writeText "ipa-ca.crt" (builtins.readFile ../../certs/ipa-ca.crt);
|
caCertPkg = pkgs.writeText "ipa-ca.crt" (builtins.readFile caCertFile);
|
||||||
in
|
in
|
||||||
lib.mkIf enabled {
|
{
|
||||||
networking.domain = lib.mkDefault vars.homeDomain;
|
|
||||||
networking.nameservers = lib.mkDefault [ vars.domainControllerIp ];
|
|
||||||
|
|
||||||
security.ipa = {
|
security.ipa = {
|
||||||
enable = true;
|
enable = true;
|
||||||
domain = vars.homeDomain;
|
domain = vars.homeDomain;
|
||||||
inherit realm;
|
realm = realm;
|
||||||
server = vars.ipaServer;
|
server = vars.ipaServer;
|
||||||
certificate = caCertPkg;
|
certificate = caCertPkg;
|
||||||
inherit basedn;
|
basedn = basedn;
|
||||||
ipaHostname = fqdn;
|
ipaHostname = fqdn;
|
||||||
offlinePasswords = true;
|
offlinePasswords = true;
|
||||||
cacheCredentials = true;
|
cacheCredentials = true;
|
||||||
@@ -62,11 +76,6 @@ lib.mkIf enabled {
|
|||||||
"d /usr/local 0755 root root - -"
|
"d /usr/local 0755 root root - -"
|
||||||
"d /usr/local/bin 0755 root root - -"
|
"d /usr/local/bin 0755 root root - -"
|
||||||
"C+ /usr/local/bin/sss_ssh_authorizedkeys 0555 root root - ${pkgs.sssd}/bin/sss_ssh_authorizedkeys"
|
"C+ /usr/local/bin/sss_ssh_authorizedkeys 0555 root root - ${pkgs.sssd}/bin/sss_ssh_authorizedkeys"
|
||||||
# Pre-create the IPA user's home dir so Home Manager activation succeeds
|
|
||||||
# even before their first login. On a fresh system SSSD may not have
|
|
||||||
# resolved the user yet — tmpfiles warns and skips in that case (non-fatal),
|
|
||||||
# and pam_mkhomedir covers the first-login path as a fallback.
|
|
||||||
"d /home/${vars.ipaUser} 0700 ${vars.ipaUser} ${vars.ipaUser} - -"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
services.openssh.extraConfig = ''
|
services.openssh.extraConfig = ''
|
||||||
@@ -83,7 +92,7 @@ lib.mkIf enabled {
|
|||||||
# Placed at /etc/krb5.keytab before SSSD starts so the host authenticates
|
# Placed at /etc/krb5.keytab before SSSD starts so the host authenticates
|
||||||
# to IPA without running ipa-client-install.
|
# to IPA without running ipa-client-install.
|
||||||
sops.secrets."ipa-host-keytab" = {
|
sops.secrets."ipa-host-keytab" = {
|
||||||
sopsFile = keytabPath;
|
sopsFile = keytabSopsFile;
|
||||||
format = "binary";
|
format = "binary";
|
||||||
path = "/etc/krb5.keytab";
|
path = "/etc/krb5.keytab";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
@@ -91,98 +100,4 @@ lib.mkIf enabled {
|
|||||||
mode = "0600";
|
mode = "0600";
|
||||||
restartUnits = [ "sssd.service" ];
|
restartUnits = [ "sssd.service" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# security.ipa enables Kerberos (security.krb5) which causes systemd to
|
|
||||||
# start auth-rpcgss-module.service and rpc-gssd.service for Kerberos NFS
|
|
||||||
# authentication. LXC containers can't load the auth_rpcgss kernel module
|
|
||||||
# and don't have /var/lib/nfs/rpc_pipefs, so both services fail.
|
|
||||||
#
|
|
||||||
# The NixOS IPA module already adds a drop-in for auth-rpcgss-module.service
|
|
||||||
# with ConditionPathExists=/etc/krb5.keytab. We use lib.mkForce to win the
|
|
||||||
# text conflict and add ConditionVirtualization=!container alongside it so
|
|
||||||
# the service is skipped (not failed) in containers that do have a keytab.
|
|
||||||
# Same fix for rpc-gssd.service which also fails in containers.
|
|
||||||
systemd.units = lib.mkIf config.boot.isContainer {
|
|
||||||
"auth-rpcgss-module.service" = {
|
|
||||||
overrideStrategy = "asDropinIfExists";
|
|
||||||
text = lib.mkForce ''
|
|
||||||
[Unit]
|
|
||||||
ConditionPathExists=
|
|
||||||
ConditionPathExists=/etc/krb5.keytab
|
|
||||||
ConditionVirtualization=!container
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
# rpc-gssd also has ConditionPathExists from the NixOS IPA module (and an
|
|
||||||
# X-Restart-Triggers store path from systemd.nix). Use mkForce to win;
|
|
||||||
# omit X-Restart-Triggers since this service is skipped in containers anyway.
|
|
||||||
"rpc-gssd.service" = {
|
|
||||||
overrideStrategy = "asDropinIfExists";
|
|
||||||
text = lib.mkForce ''
|
|
||||||
[Unit]
|
|
||||||
ConditionPathExists=
|
|
||||||
ConditionPathExists=/etc/krb5.keytab
|
|
||||||
ConditionVirtualization=!container
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Home Manager config for the IPA primary user, applied on every enrolled
|
|
||||||
# host. Manages what IPA doesn't: dotfiles, user-scoped packages, session
|
|
||||||
# variables. Switch-nix/Test-nix/buildImage are system-wide (configuration.nix)
|
|
||||||
# so they don't need to be repeated here.
|
|
||||||
# NixOS requires isNormalUser/isSystemUser + group on any entry in
|
|
||||||
# users.users. HM with useUserPackages = true (set in flake.nix) adds a stub
|
|
||||||
# entry for each HM user so it can install packages to
|
|
||||||
# /etc/profiles/per-user/<name>/. This definition satisfies those assertions.
|
|
||||||
# With security.ipa setting "passwd: sss files" in nsswitch, SSSD's IPA entry
|
|
||||||
# takes priority for NSS lookups — this local stub is only a fallback when
|
|
||||||
# SSSD is unreachable (at which point auth fails anyway).
|
|
||||||
# HM with useUserPackages = true (flake.nix) sets users.users.${ipaUser}.packages,
|
|
||||||
# which forces the stub into /etc/passwd. pam_sss.so with the "localusers" flag
|
|
||||||
# (added by NixOS when SSSD is enabled) then skips SSSD for any user it finds in
|
|
||||||
# local /etc/passwd — including this stub — falling through to pam_unix, which has
|
|
||||||
# no password for the stub → sudo auth always fails.
|
|
||||||
#
|
|
||||||
# Fix: NOPASSWD for the IPA user. The IPA user already authenticated to reach a
|
|
||||||
# shell (SSH public key from IPA or Kerberos), so re-prompting via a broken PAM
|
|
||||||
# path is security theater on a single-admin homelab.
|
|
||||||
users.users.${vars.ipaUser} = {
|
|
||||||
isNormalUser = true;
|
|
||||||
group = "users";
|
|
||||||
extraGroups = [ "wheel" ];
|
|
||||||
createHome = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# home-manager-<user>.service fails on first enrollment because /home/wayne
|
|
||||||
# doesn't exist until the user's first login (pam_mkhomedir creates it then).
|
|
||||||
# ConditionPathExists makes systemd skip the service (exit 0, condition not
|
|
||||||
# met) instead of failing. After first login the dir exists and subsequent
|
|
||||||
# rebuilds activate HM normally.
|
|
||||||
systemd.services."home-manager-${vars.ipaUser}".unitConfig.ConditionPathExists =
|
|
||||||
"/home/${vars.ipaUser}";
|
|
||||||
|
|
||||||
security.sudo.extraRules = [{
|
|
||||||
users = [ vars.ipaUser ];
|
|
||||||
commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }];
|
|
||||||
}];
|
|
||||||
|
|
||||||
# Home Manager config for the IPA primary user, applied on every enrolled
|
|
||||||
# host. Manages what IPA doesn't: dotfiles, user-scoped packages, session
|
|
||||||
# variables. Switch-nix/Test-nix/buildImage are system-wide (configuration.nix)
|
|
||||||
# so they don't need to be repeated here.
|
|
||||||
#
|
|
||||||
# homeDirectory uses mkForce because HM's NixOS integration module sets it to
|
|
||||||
# "/var/empty" for users not found in config.users.users at eval time (SSSD
|
|
||||||
# users aren't visible there).
|
|
||||||
home-manager.users.${vars.ipaUser} = { pkgs, ... }: {
|
|
||||||
home = {
|
|
||||||
username = vars.ipaUser;
|
|
||||||
homeDirectory = lib.mkForce "/home/${vars.ipaUser}";
|
|
||||||
stateVersion = "26.05";
|
|
||||||
packages = with pkgs; [ tmux sshfs ];
|
|
||||||
sessionVariables.EDITOR = "nano";
|
|
||||||
};
|
|
||||||
programs.home-manager.enable = true;
|
|
||||||
programs.bash.enable = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,14 +19,6 @@
|
|||||||
# tailnet-specific subdomain (vars.tailnetDomain) instead.
|
# tailnet-specific subdomain (vars.tailnetDomain) instead.
|
||||||
services.dnsmasq = {
|
services.dnsmasq = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# NixOS's dnsmasq module defaults resolveLocalQueries to true, which adds
|
|
||||||
# 127.0.0.1 to networking.nameservers and makes dnsmasq bind to
|
|
||||||
# listen-address=127.0.0.1. This instance is not the host's local
|
|
||||||
# resolver — it only serves IPA's conditional forwarder for tailnet names.
|
|
||||||
# The host uses domainControllerIp directly (networking.nameservers in
|
|
||||||
# host.nix). Without this, all host DNS goes through dnsmasq, which has
|
|
||||||
# no upstream for general queries (no-resolv=true), breaking resolution.
|
|
||||||
resolveLocalQueries = false;
|
|
||||||
settings = {
|
settings = {
|
||||||
# Listen only on the LAN interface — not tailscale0 or loopback.
|
# Listen only on the LAN interface — not tailscale0 or loopback.
|
||||||
# bind-interfaces prevents dnsmasq from binding to 0.0.0.0 and
|
# bind-interfaces prevents dnsmasq from binding to 0.0.0.0 and
|
||||||
|
|||||||
@@ -81,14 +81,6 @@ if [[ -z "${TARGET}" ]]; then
|
|||||||
usage 1
|
usage 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Reject FQDNs passed by mistake — the script appends HOME_DOMAIN itself.
|
|
||||||
# "nixos.sweet.home" → FQDN would become "nixos.sweet.home.sweet.home".
|
|
||||||
if [[ "${TARGET}" == *"."* ]]; then
|
|
||||||
echo "Error: <hostname> must be the short name (e.g. 'nixos'), not a FQDN." >&2
|
|
||||||
echo " The FQDN is derived automatically as ${TARGET}.${HOME_DOMAIN}." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
FQDN="${TARGET}.${HOME_DOMAIN}"
|
FQDN="${TARGET}.${HOME_DOMAIN}"
|
||||||
KEYTAB_SECRET="${REPO_ROOT}/secrets/${TARGET}.keytab"
|
KEYTAB_SECRET="${REPO_ROOT}/secrets/${TARGET}.keytab"
|
||||||
# Temp path on the domain controller — use a name that won't collide.
|
# Temp path on the domain controller — use a name that won't collide.
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data://9IEHIVCfHjyMNao5sCu2zNlZ/CaW+JyxVpGpD/vab2qvURunCUY7eMfSOyvOx/2WPXnWWlkoVJPCR1ec/yUg09EaSMfxrvqlu4UJI3Sxvu9xNuDszMwMMD/sCulJDiMWFNLp8qaYt7UGzexp4+GlGiqWDxk3ZEu/iLmSApzBrpciTF0lfehT4qblDovo9QXG2KDWFhCt2SwEKmHJ61Yl3pVAQnPLyTWaNhwWD/mYL76mIiDVKq7DJlvi9MBxzi3aYh/ttuHgRCvnCL0C9oUvOyT2cljwra0LXuOrum7FhPIXXboA7WTEbTHJm1LB5yLfxDrnWCrGxQzFQAwNixVHIcjuvjjvA/LifTvbj5FYM8x7an+DwXPfPhruFrDew1paAWsEGNNYXSmAlju2QLI/OwLHFFLuDyLnBKQ6RLtZbCEAOUKf2h4iZj7nH86eb/aGU=,iv:rj76+MJBCpiYyx2Ogut5UxJj3Gn+bygvu2mtuY5hFLA=,tag:yQmTvWVu8ZLug/7fo6RnwA==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqcURBS2tIMGl1aWxLMHFQ\nS3ZGVTE0cnYzTmpnQ0daL1F3QnlpemRCMmtjClJiZzIrc2syN29sRXVoaXlPRUNF\nakw4RndmbEduTFg5ZVRKUTVwRWpGRjgKLS0tIHZ5ZFlyODlGWTJoNGpXR3RhY0ZH\nOGpPdDZQVmt6UWZXbHkxQTBoeW1JencKbsfH1V1lUj8mmHyLNj36VaRDgaBojcDU\ndoQWmSEXxjticJqdadbVKb3UABpvzAZxASCy81sa3wH0gT+7zLaNyQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1njap586hc0q43kr03g6c8eqhdsmk8zcafkl3f83xwlc2gqhlmfgs4tmwad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrbFdaMmRjcHgyV3Y0eWZL\neG1uMEtpQVUxQmNTU0Z3aC95Zi9uQlgvMEhRCmJiVlRTR2NocGlnbVU1UmlLVVA2\neERiMXpiQlVPNVhRU09XVGxrY0Ixa2sKLS0tIFRuOHdoelJxOXNRRHBJNnlhSE9j\nUUZHZmQzOVFwRmhFV3pvdnpRMTMraGcKRHBuSUpbHaEzH2tuSBE5MsLJDCuH3vUx\nO0jnDldCWkCw7Wvr/tQAkaDI8axZcYVDUkCEk+xqAdxDozLCPhEO6g==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17e89ty6p0fw24daanen57wg8uald9s025t3wwxsw269svwpmgvrshfvfvt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZMW5taXh2QkJkT0JjaVpq\nQlBjVFpFYUhXTHhOT3prbFcvUFB0YnRGUzMwCjhHT01lY3dPWDE2dDZWZnJza1hN\nS1AvZWIvdjZoYmRjWlliK1hiOEdrT00KLS0tIDljWWY0NlQveS9VR2hOSUNyTUtH\nK2gvbEVibmZSdktPemdEQ2p5U0Y4d2MKKitoTi2vbxJ41IoWMlj4vO91Ahpj0hHP\nrKCPyx7ws/IUMmKGyvDLpZ3pYqHD9jl5pLfB05Hh4Emhv4lA1qtwwQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17jqc66x9yeshfgd9v78mj483r4zzarqdtuxtrkxe4x5mw679gphshd94th"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3K2dVV1BHbDk2Z3FhNmdV\nZEN2Um94K0pma1k4b1V5ZUJxQ1hWU1grZjJNCi9iRVVqOVpEMmtBUi80NThlYldY\nTUtZOVErT2VSWk43NndpVzBlL1lQaTgKLS0tIEpCM3Q4NjM3N1lpUE56N04rTXN0\nZkZ6TkV1TU9OV3dpc25RNWRpVnprM00KItUzKBdShakOfX8Sr+k906nsvYPl8QLb\nge//1GA+ukGsaS9rcChOY89vFdm61JDmj1jXSJ0CN4wLMW9/eblZRw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1arhf2q45zw6wf2uevju4savp575x3m2tfvved5zzq3ay92ynua9s3cm92c"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-07-28T01:44:28Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:efFXIqbauOURR7lrVpK7kqRIPgYjgWfenBYoX7mUrQ/thFc+ApcAx58Fi1zg4biwIs7NarJAgDqAxZi+yKb2Sll8H/wlsEjWDU4iQlLJdIQw7wey9eDW8pgBLd+6E7FXrgn1Vh49dS5GXlC6clAYk1lCiB4NvfzPDy5Ktpl+Chs=,iv:+zCqj5I1MLJfRRiIrqgocYB49PZnlV45PUTH4gYlfrQ=,tag:WxY1sF4kFOTEzbSFcfJFbQ==,type:str]",
|
|
||||||
"version": "3.13.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:apiijrtrqd77CTizITg0R35BfCi8PBnufpxIyC+hLYqwoBzP//3z/yjFyHPLG98m/c/qywoi3Kn+zsaTT7MjP++9OMhhX94YKlSHV1/cHB76OkwsNc+ClqWxl6vpaFX29Qvh3gFX9c/NR3xvYQutYwrIrQ9NR+t/M52IMC8hvtR1LQy0ak3VIuXJlSnG2r4kF2Ym1iP7phjuq39Gd245Axzw8OB7yGvOjNxSdTPxW/qL0fMlzNcMrjr9hw15WlqnZfWPOsB1+gZjHXpGfPD5BCbAAMoTRJd75vhKKXP/ERhIffewuuH2x/QHfSFvXVB3QyhBQMxd2b8QEEE5cjvcExOST3tkj6QARkzoUpRT7AE3jhl3XZ0uA2qu9SwyrSvbr0tBRKxCdK0g2E2/hqwcK/Tck5GB1eKb4aN+UkqxOblNDH+B1RfDoyNAuN+KEg==,iv:0p+ScrKpP4kQvO52gBAlwAis6oAzZ0EHFnU74hYPrn4=,tag:ON7qOjztF52xsJWAou7ogg==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlYXB3cVAzb2xEZ2pGa1RJ\nbS9ZVTc4Ums5eUZJUjEvd1g1aGVyNUNramowCnptZXFOZVB3MFRFcUtzSXBEZk1B\neEtKcDdLS0h0b1h3VjRjRXRvV3V5V3MKLS0tIHBDemkyUnV6ZXhTeE5VOVVOMlky\nWWMzVGVzZlAxMjZYUGpQUCs5QmxiYkkKcuBshCgWX4TwfVlQ5lHikzvwWdLEXWD1\n/uSiy0J6yMSiu8u6cg2SxeFrlKJ3j47dDlT6WHCxS0PfeEA0bJb3LA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1njap586hc0q43kr03g6c8eqhdsmk8zcafkl3f83xwlc2gqhlmfgs4tmwad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGa2VTc2NWdkFRNUJxelVR\nWFk4RWxoelYzNHo1UFVhU2ZkLzEySlRWN2xNCmNmcmJod2crL3NMRlVsSmpmVkU2\nMjlXMktjc3piUVNhUXlTdnVGTWJkUTQKLS0tIGQrMUxrNDlNTkRCSUtFWkxRdXgw\nRlV4ZmtYSGhPQU84eWtiQXVqTmxUK3cKk5fn72UZPH68t5ZappfAhZJwzpLkfKmT\ny9TbUPIr4Pbrexau6YiH43QIbDQFdwYPfkBjGkd57zCg8AVo1+MBRw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1adur9g330gua4l6ndk8cqjg35qc8yxwgme6wrl2hpylcc7vxm38q05ejuy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArNWkwQXFWT1RpaDNvbzYy\nQWc1aHhmNHFEUXVsQjZqb0EzM0wrV0dwN1hnCjFsUFJiT3REK05uSGRWTEw2SFE4\nY1FleE1XVjhBbndiMmZxTWNTYmhYeVEKLS0tIEJiZzJvS3BsYzB3cHIxa2k5N1Ro\nenFFZDVaODNnVGdBZTBOYWJwRjQzc1kKlXJgee8wTSN4Beq4P0t9cYbk0BWHCseQ\nyaWpiPT9aZBEGLFmuEd3zKABc8lrilX/ySTmOG49vRg6CPmr7cT0Wg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1rrxqea6q6pn39sw8y5te63h2py8jgjl9v0jyper86w3ggtn67upqg3ah39"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEa0JYenFMNmNzWnVmcXdz\ndG90ZUZ0WWlIU0FCZG9OaWpBM3ZDWnFhZFhNCjhuV1FTOTJ2WVJGa2RuNVV2MjR0\naVNXa3diaWxWUlJtdkNOQXZ2R2NsQkUKLS0tIDcyYXh3N3B2QmNiK3dzemFFMGV1\nNTZpTk5yNGV5YVo3cGswK0NLWFQxQlEKIe0N5OxooWXzt1cUViBmjihmGEe3G6/f\nkz2/IscnG78ZvNgYKjdoG1jlsyje/3zI4C8aWXLq2DnIyxUyAhPgsQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age19mn8zrxl8zpps9yvrh4euquvygpp4fp8queg7xc6qhtnl4ng8c9qx02qwn"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2b0NVVm9QNm9waUUzcXBi\nWnZWU0JETjZRZmprZVRUL1h6ZHB4cXkrdm5rCm9GZ0VnTXB3S1BYSmlGWFJVcDhJ\naUl3RjR0ak9BRmQvVk1GRnQxNmtYM00KLS0tIFlTU1p2OHhWUGlOWngwbE56NEhF\nRW5QSkVVUWZpdDZXWEIxZ1BkbzVwclEK2P25nBgf8255vaKW/+T97aNTecRgNjLu\nedIUiPdXbFATCe3v/YRo6sqzFwIsvM6Bl9yHh/SXo6Ftc7eWZZd8zQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hrx8qj02fj2ea6d4g9vqhyj9hl7fppkjqfdx2l37py3h6pdkr95s8n8rvs"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-07-28T01:44:24Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:J0D8bEs5mHLraLS6TvYuCgfiNU1xKM2Yfb5Y0f/q/4wM4LzXufNzv3+SWDHumTe328U8UnNXLqjNHEKL0bZi0coxpU5hVM+BvPcmqD72vscETzbQ2hnU05sfW+XjfZhcN8/ke0bpLt7nP0crD5hsZv3esV1E2UWvzjEiYtWzFHY=,iv:lcmXYG2H469UKBYDndWKMO+GP0mSGLztenm+kBaUdYI=,tag:ujiXbLM9CUsuoFwQQWI84Q==,type:str]",
|
|
||||||
"version": "3.13.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:aqlMnoVkGtH9z3fJRweeC0OYf7LGqJU2sWA9Q25dKK6NuNyJd4BvjPtpfeg/WhVtJsaOtcbwVm4WAhVK9FARE8g8j+vmq0f6BAU4s6mx0ZIhl+mP+/hIpt//LOdd+9YezelJxdpzUyZbdAngU99rsTluLRe2XmZ7Fquxd8yH/OHenSDY6dizp9+5jfEi8EU+EmuXvuWMPY59xnlnqYNPfSFxs43/pS402LzJoJ5H+cBPprddkUBVzy4cBQvMnrRFUSjnqp74ovZkfIWFqDWQ5YgSU2PjatBg18oulZ7wNRhQ6OLqj6gsu+xrMjNFwnp7rMlA3X//hIidxTkVcYITycXd8KzuMIaofUpnwoyT34fy6+H35/39iiEyG4LRTrOOKRDzXkY2rhJUxFSZ8GlhNhMd0RlkmLngVYrtjsswJ9meIwoAFLPYt7BC61PJf0TXdtk=,iv:mCA819J9LpAOj8QxFAkrHI9wFJIy8qVxv31D6IwWFnk=,tag:qqMtM0eyHbQEyl6ND/wf7g==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOZVpRYmNMQ1E4ZlFXMDVq\nbW1FcnYzWTBHQmdhSjlsZUtZK3dzNUZjY1FvCkV4VXU4MTcwNVZoZUpVVS9JeHE5\nbGk3UzE3YmpZQ1JISHV0RHJqSG9ZNXcKLS0tIHhBdnIvMjJkeWlVRE9Fb0FhWjNX\nUjBVWDltK2w0akkwOTJaTGNSWWNrRXMKqZRNnHiXvn1QBoSGdABp7vOqNlsEN6Xr\nDp3NByXow6PuRuWvQXHzd+WC+ADkwNaaiT6TUrbZcd/Pl8Ges9kcZg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1njap586hc0q43kr03g6c8eqhdsmk8zcafkl3f83xwlc2gqhlmfgs4tmwad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2VFBxc2ZMUFp0YkJhVFhW\nc0ZNbnJUcGtkT1VLR2YrVGhRRFVTZFlyZXlJCmVnblNBNGxIdHh4Q0IweWR1b0dq\nRWFyOURuWkdkRE1RTnJRMEpXdk9HaUUKLS0tIFhKV3FoWW1zRk1pMlhuWWlhV2E5\nQzJTRHAyc0JtSjd2NHlJODZVbndaVDgKFA4565X/4FqNq/fZDZTg81/55hZi4c7b\nTti2AnyE3OcY/kurXJFHRinVMqURQf1fx9MxqUYRitiCz4qe5zFF+A==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sweerhrga9yf8x6sv0apz4ed4g48rnlcq34rpv20t0rcelwgpgeqwvndzz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwRWlKTFNocnBRN01pZ0hm\na3pyRUkxMWM3dE1iTkZZcGRYUFcyb1RDb2h3Ckt4blpGZHBjcnZ4SVE5UnF4cmY4\nWW0rZG5wUkZINVk5a2lmSzN2L3JJY1kKLS0tIExpWGlBRFZJVGpGbFhxRE5ZYjBo\nQVliTlFIZ1U5dE9xbDhHMUtxenpBSm8KY6sIFEfK8p+70IXsC4Jwb9Lm/pd9+V6K\n4JAzGrpA6mAuIwwSNnbdcA5j8FmBhCpK6nLBWmFhGm9Y+MRTaM7Jrw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1nruncs4l0ufk7yuc4des8p99c0alfndl0lhsws8tycl5pplfp56s30af5f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoV0pIUXlyOFFTUHVTdllu\neG10VENOYWl5Wk0ycnpLUytTbnlrQ25pMkFRCnhyRU5xWW9vQXJJOHdFMGZqMkR1\nSktqT3lOdVVPRUN4YTlveGp0NXpqd0kKLS0tIGRaTktra0ZtSVpzSHBrY3VSSUph\nRVRZOSsxTTNmMmltMlJnVy9oT2VEWU0Krxf49B1BsrWn05fqg+cZ0k0PtfJJNfn0\nUL44RUWXWbK2igQHaIct9DfYe7DEonBJeROuxDYm8g7yNOv15S+P4Q==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1529taqdwr6t0w7cvzmty0d5y5593wffl0krt48j6uc4u39k56g2qf6ywtp"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-07-28T01:44:26Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:eyOSn03dzHSgkshPzLVwc95382eEFaDQarHs9l83dtcsb1Ui9CjkKipl2DVSUb6bdMUH1qKYmXqJhwFnAZbFZFjT4VTKtutNtM+OkhVXfT+fJs+1+u7k+ZUYFL9HuxKA6AWpwX3eJ8vmJDJZaAayJbm4PRzOyJywvKeneQqdUS0=,iv:QRKltR4qzVofo/Elt2Us/lrHlD7BenX605X31x+Ng78=,tag:SZ97CcfgMJeu3yqNk8Y/cA==,type:str]",
|
|
||||||
"version": "3.13.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:QvViw/s1N7eIN3CoD27llEjriuSrohOou4Cv310nigcW8xMnA2SDN2id3H3AoKii1JlJ+qWpKn+gUmt5HOM0UlbeNe3os2RVwiX38O7eN9xFH9F5kA3TFs6Umqq3EoI586PwIVmB2LyxDnTeEEXVd7v5PFkBcfu7u8YIcNF7lpcj+6rOyHMB8uxPhrGep3yiKawFd9c9wWD0hlSSatV5tMHA1qmdK8VmDbCU/iuGwIoMzN1eZwGAXzG6LkCA63bUfdxU6yGuTboD+kN2Wbo+GZB0EACmiZoofl2wqlXuiw6qwTvlXkyauc9O5EG//PUkIECzDwiXcX+qSOM9DIBlZNth4ebhtic/PskyF09etL/gICz5YvV4ph5lyrWHq41KxljSU7QXOkGhzagruuMrYzhZb35wFH4Tie1ee2DXbGhreJr8V3Zse/zTMaD+iM57V8bvNcarTzOFXyKfp7Y=,iv:XBPhj2wT0k/yRCRHU4d+BQA/k00ZHWSKOucnZ5+PGys=,tag:Nh5MOxZIUXAYVZY5SZh/JA==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0aUtETXlBMmRlTC9vK3NF\nRW4zS1FrSmo1dDN0OGN4SmV5ODd5MTRVejFJCnpPQkM2MVJ5WFlYRW1NVjduV1hv\nUWUzY0hHV05LV1BROVZVUlM2NldsTlEKLS0tIHFsTzI2SVZzYUtJWTM0MmFiUlVQ\neHEvUXgzc1pxSU1OZFo0cXhSZDdGUVEKpLVfzQEnntluUGsblnkHZJ9Jezu8tFte\nxEoV96GVHxUca6TFWpTLMqdR7NtuQGCkx295W3i1tkp58DP1OzRTUA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1njap586hc0q43kr03g6c8eqhdsmk8zcafkl3f83xwlc2gqhlmfgs4tmwad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4ZW5ybVBvTkxibWJMWGRL\nZ1lnWEkxZ3l6d0FWbmxMY2VsTVlzOHJJM3owClNYd3BlQi9pL1lIdzJmekJUVEVi\ncWhSK3ZkZEMyeTNoZlpTT0NMUXZFWVEKLS0tIHVkVlhmQXdRQktTK3J5dXZ4aTNt\ncUw3WCt5dXJhTkdUbVpmeWoxWkoxNnMKj4XtdwmgFVOiVsIJs2Du7QJ09A9tv/Lf\nkFOq8y4tlZe0nCwRjq43sVz7hdCTdQ0rsaWjBGY90LLkJbOA+f+Wrw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age16kqfmvz4e23hmdlqresnyw69ej604s320mmd49h4hm3fhqchtgyqrws0k2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-07-28T01:44:30Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:zR2WLWX7NaHA15gi4kX0jDvzUIe9jtz5bMCAggbPW+IXOEedPrddAHZ8OfPErVMfx8O1pJKkAKSzoPTAbEle54FisSLMHXp8fI0297MByJrF9pOsMFpVcDy/L4Q+pBzmB7aS9r7+u7KRVVTZT3QwG1rFWZaDs5dFTP80RhtCbWQ=,iv:ZzPoO+h7ebS+jsSH7tWMx6QK8umpa2/HFQmx9dnJN+Y=,tag:vG9+ifxw4HaBE6YsmOwXcg==,type:str]",
|
|
||||||
"version": "3.13.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -80,11 +80,6 @@
|
|||||||
# one-line change.
|
# one-line change.
|
||||||
primaryUser = "nixos";
|
primaryUser = "nixos";
|
||||||
|
|
||||||
# Primary IPA/domain user. Home Manager is configured for this user on every
|
|
||||||
# IPA-enrolled host (see modules/ipa/client.nix) to manage the environment
|
|
||||||
# that IPA itself doesn't cover: dotfiles, user packages, session variables.
|
|
||||||
ipaUser = "wayne";
|
|
||||||
|
|
||||||
# HA file server cluster
|
# HA file server cluster
|
||||||
# LAN IPs (vmbr0 / ens18) — client-facing: iSCSI initiators, NFS, management.
|
# LAN IPs (vmbr0 / ens18) — client-facing: iSCSI initiators, NFS, management.
|
||||||
# Storage IPs (vmbr1 / ens19) — isolated internal bridge, used for DRBD
|
# Storage IPs (vmbr1 / ens19) — isolated internal bridge, used for DRBD
|
||||||
|
|||||||
Reference in New Issue
Block a user