0cc0b5064d
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)
107 lines
3.2 KiB
Nix
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.)
|
|
};
|
|
}
|