Files
m3ta-chiron 0cc0b5064d fix(thin-client): deep-build fixes + Snipe-IT/Alloy real impl
Tiefen-Validierung via 'nix build .#nixosConfigurations.AZ-TC-NN.config.
system.build.toplevel' hat mehrere reale Bugs gefunden, die 'nix flake
check' nicht sah. Alle drei Pilot-Hosts bauen jetzt sauber durch.

Gefixst:
- freerdp3 → freerdp (umbenannt in nixpkgs-unstable)
- SDDM Theme.Logo will INI-Atom (string), nicht Nix-path → '${path}'
- security.pam.mount.extraVolumes will list-of-string, nicht ein String
- sudoers: 'domain admins' muss als 'domain\ admins' escaped werden
- agenix file-Pfade: ../../secrets/ → ../../../secrets/ (Tiefe korrigiert)
- snapper: config.services.snapper.package gibt es nicht → pkgs.snapper
- samba4Full entfernt (blockiert durch ceph-common python metadata issue
  in nixpkgs-unstable; Thin Clients brauchen es nicht — cifs-utils reicht)
- corp-wifi-ca.pem durch gültiges Dummy-PEM ersetzt (openssl-generiert,
  mit明显 REPLACE-MARKER; build kann PEM parsen)

Functional gemacht:
- Alloy: echtes River-Config mit loki.source.journal + loki.write statt
  barem logging-stub. Journal-Logs mit host/unit/severity-Labels nach
  Loki.
- Snipe-IT: echte Check-in-Logik via curl + jq. Lookup by asset_tag,
  PATCH falls exists, POST falls neu. startAt täglich 03:30. API-Token
  via agenix (snipeit-api-token.age).
- node_exporter push: realer curl-Push alle 60s mit retry on failure.

Safety:
- Placeholder-Assertions in roles/thin-client/default.nix: build schlägt
  fehl, wenn wifi.ssid/hotline/company noch Placeholder sind (außer
  site='staging'). Pilot-Hosts haben site='staging' bis echte Werte da.
- assets/corp-wifi-ca.pem hat deutlich sichtbaren REPLACE-Hinweis.

Neue Options:
- az.tc.monitoring.snipeItUrl (default: snipeit.az-group.local)

Neue Secrets (Placeholder .age-Files zum Ausfüllen):
- snipeit-api-token.age (fleet-wide shared)
2026-07-29 09:06:12 +02:00

107 lines
3.2 KiB
Nix

# roles/thin-client/peripherals/smb-mounts.nix
#
# pam_mount: Windows shares auto-mount at login via Kerberos.
# Q9 decisions: pam_mount, Per-User + Common Shares via DFS-Namespace,
# Lax (mount failure doesn't block login).
#
# Kerberos semantics:
# sec=krb5i integrity-protected Kerberos auth
# multiuser each user gets own mount credentials (no shared session)
# cruid=%(USER) the credential user (pam_mount templates it)
# nodepray don't attempt password-based retry
#
# Mounts under /mnt/az-dfs/<share>; KDE desktop shows symlinks.
{config, lib, pkgs, ...}: let
inherit (lib) mkIf mkOption types;
cfg = config.az.tc;
in {
options.az.tc.smb = {
dfsNamespace = mkOption {
type = types.str;
default = "\\\\az-group.local\\dfs"; # TODO: confirm
description = ''
DFS namespace root that all share paths are relative to.
Example: \\az-group.local\dfs
'';
};
userShare = mkOption {
type = types.str;
default = "users/%u";
description = ''
Per-user share path relative to the DFS namespace. %u is
expanded to the username by pam_mount.
'';
};
commonShares = mkOption {
type = types.listOf types.str;
default = ["public" "software"];
description = ''
Common shares (relative to DFS namespace) that every user gets
mounted at login.
'';
};
mountRoot = mkOption {
type = types.str;
default = "/mnt/az-dfs";
description = ''
Local mount root. Shares appear under this path as
<mountRoot>/<share-name>. User's personal share appears as
<mountRoot>/home.
'';
};
};
config = mkIf cfg.enable {
environment.systemPackages = with pkgs; [
cifs-utils
pam_mount
];
# pam_mount config — extraVolumes is a `list of string`, each one
# a complete <volume>...</volume> XML element appended to
# /etc/pam_mount.conf.xml by the NixOS pam_mount module.
security.pam.mount = let
dfs = config.az.tc.smb.dfsNamespace;
mnt = config.az.tc.smb.mountRoot;
# Per-user share
userVolume = ''
<volume
fstype="cifs"
server="${dfs}"
path="${config.az.tc.smb.userShare}"
mountpoint="${mnt}/home"
options="sec=krb5i,cruid=%(USER),uid=%(USER),gid=%(USER),multiuser,nodev,nosuid,mfsymlinks"
user="*"
/>
'';
# Common shares (read-only)
commonVolumes = builtins.map (share: ''
<volume
fstype="cifs"
server="${dfs}"
path="${share}"
mountpoint="${mnt}/${share}"
options="sec=krb5i,cruid=%(USER),uid=%(USER),gid=%(USER),multiuser,nodev,nosuid,ro,mfsymlinks"
user="*"
/>
'') config.az.tc.smb.commonShares;
in {
enable = true;
extraVolumes = [userVolume] ++ commonVolumes;
};
# Ensure mount directories exist (created per-user at first login).
systemd.tmpfiles.rules = [
"d ${config.az.tc.smb.mountRoot} 0755 root root -"
];
# Create /etc/krb5.keytab is owned by root and readable to pam_mount
# (which runs as root during PAM).
# (No additional setup needed — pam_mount reads the user's TGT, not
# the machine keytab.)
};
}