feat: sops-nix for samba password secret
- add sops-nix input + module (jupiter only, not the VM) - secrets/jupiter.yaml: age-encrypted samba_password (safe to commit) - .sops.yaml: encryption rule for admin age key - secrets.nix: decrypt samba_password to /run/secrets on the host - provisioning oneshot reads sops secret (host) or plaintext (VM), single value - .sops private key stays off-repo (~/.config, /var/lib/sops-nix on host) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
# sops-nix encryption rules.
|
||||
# Secrets under secrets/ are encrypted to the age recipient(s) below.
|
||||
# The matching PRIVATE key lives OFF-repo (~/.config/sops/age/keys.txt for
|
||||
# editing; /var/lib/sops-nix/key.txt on the host for decryption).
|
||||
#
|
||||
# Add the host's own age key here later (derived from its ssh host key) so the
|
||||
# machine can decrypt without shipping a separate key.
|
||||
keys:
|
||||
- &admin age1cekcqyf7073fsytcjxaa9dr9zwkmn4vjg36rv2tgxdglzfv4jvxqvcj6z2
|
||||
creation_rules:
|
||||
- path_regex: secrets/.*\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *admin
|
||||
Generated
+22
-1
@@ -39,7 +39,28 @@
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
},
|
||||
"sops-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783174389,
|
||||
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -7,9 +7,13 @@
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, disko, ... }@inputs:
|
||||
outputs = { self, nixpkgs, disko, sops-nix, ... }@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
in
|
||||
@@ -22,6 +26,7 @@
|
||||
specialArgs = { inherit inputs; };
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
sops-nix.nixosModules.sops
|
||||
./jupiter/configuration.nix
|
||||
];
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./disk-config.nix # disko: OS-disk partitions + filesystems
|
||||
./secrets.nix # sops-nix: samba password etc.
|
||||
./services.nix
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{ ... }:
|
||||
|
||||
# sops-nix secret wiring (real host only; not imported by vm.nix).
|
||||
# Encrypted values live in ../secrets/jupiter.yaml, decrypted at activation to
|
||||
# /run/secrets/<name>. The host needs the age PRIVATE key at the keyFile path.
|
||||
#
|
||||
# Deploy the private key with the install, e.g. nixos-anywhere:
|
||||
# --extra-files, placing your key at /var/lib/sops-nix/key.txt
|
||||
# or later derive a host age key from its ssh host key and add it to .sops.yaml.
|
||||
{
|
||||
sops.defaultSopsFile = ../secrets/jupiter.yaml;
|
||||
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||
|
||||
# Decrypts to /run/secrets/samba_password (root-only by default).
|
||||
sops.secrets.samba_password = { };
|
||||
}
|
||||
+12
-6
@@ -68,9 +68,10 @@
|
||||
# `services.samba` never sets it, so logins fail until provisioned.
|
||||
# This runs AFTER samba-smbd so its state dir (/var/lib/samba/private) exists
|
||||
# — an activation script runs too early and smbpasswd fails to init the passdb.
|
||||
# The secret file must contain the password twice (new + confirm), one per line.
|
||||
# VM test: vm.nix writes /etc/samba/smb-password with a throwaway value.
|
||||
# Real host: supply it via sops-nix/agenix — do NOT commit plaintext.
|
||||
# Reads a single-line password from the first file that exists:
|
||||
# Real host: /run/secrets/samba_password (sops-nix, see secrets.nix)
|
||||
# VM test: /etc/samba/smb-password (plaintext, see vm.nix)
|
||||
# smbpasswd prompts new + confirm, so the value is fed twice.
|
||||
systemd.services.samba-smbpasswd = {
|
||||
description = "Provision Samba password for darman";
|
||||
after = [ "samba-smbd.service" ];
|
||||
@@ -81,9 +82,14 @@
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
if [ -f /etc/samba/smb-password ]; then
|
||||
${pkgs.samba}/bin/smbpasswd -a -s darman < /etc/samba/smb-password
|
||||
fi
|
||||
for f in /run/secrets/samba_password /etc/samba/smb-password; do
|
||||
if [ -f "$f" ]; then
|
||||
pw=$(head -n1 "$f")
|
||||
printf '%s\n%s\n' "$pw" "$pw" | ${pkgs.samba}/bin/smbpasswd -a -s darman
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
echo "no samba password source found" >&2
|
||||
'';
|
||||
};
|
||||
services.avahi = {
|
||||
|
||||
+3
-6
@@ -18,14 +18,11 @@
|
||||
users.users.root.initialPassword = "test";
|
||||
|
||||
# Throwaway SMB password for testing (samba-smbd login = darman / test).
|
||||
# Two lines: smbpasswd wants the new password + confirmation.
|
||||
# Single line — the provisioning oneshot feeds it twice for smbpasswd.
|
||||
# Real host must NOT do this — plaintext lands in the world-readable Nix
|
||||
# store. Use sops-nix/agenix to place /etc/samba/smb-password instead.
|
||||
# store. It uses sops-nix (secrets.nix) instead.
|
||||
environment.etc."samba/smb-password" = {
|
||||
text = ''
|
||||
test
|
||||
test
|
||||
'';
|
||||
text = "test\n";
|
||||
mode = "0600";
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
samba_password: ENC[AES256_GCM,data:Ur5CuAlJhdw=,iv:po7oxygUqKS9yoJS8efQJe2mTr7e5zYkZjAVRgeoUB0=,tag:Mf0K3rIga5I4jnNU3glDyg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlL0E3cWNIby95Q3RBcjlm
|
||||
QklPREM4cWRaelZEckFGUWpKUWExYmxrcWdrClByTVBlWDNlRGhMUkhEQzJONzFn
|
||||
alJVSzRMODN3U0cyRG93T3lHZkhXTWcKLS0tIFJ2V3I0V1NwakVlc2dCUW1iMHdR
|
||||
RlNsWnJJaDkvVnJnVlcyRXZmK1VkMUUKnv02m3vGjy8nTZV9ouItOEWmfZOABKDP
|
||||
VCvWcSy8R0NikkQ004XrBd1WhvyrUvqC6X9f4N9208BvmyDxEpKZbw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1cekcqyf7073fsytcjxaa9dr9zwkmn4vjg36rv2tgxdglzfv4jvxqvcj6z2
|
||||
lastmodified: "2026-07-12T18:10:45Z"
|
||||
mac: ENC[AES256_GCM,data:ynQU/B5RvwGw1ILJJexrZWtzNr7z3IUyy86v8q0KhRsMH2qSHF0BK0Pzq/DcT3vru+MwKat1hJfO21Pdu+HRsqtzUZRViTCbjtz+vmnjwyQvBqBPhEtxDeBoTgd5RqjXxzcuOADfv0NkfvU9p06x8YF8AVYq9ONvOEZiC4MamoY=,iv:1Wm4JP5Djyc9jdExMBcSjWw/zF1EXexjjMhePOEWCt8=,tag:A51vbK8fpb8sg+eCLwbWmg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.1
|
||||
Reference in New Issue
Block a user