wip
This commit is contained in:
parent
517d8330dd
commit
0e5187d194
3 changed files with 114 additions and 34 deletions
|
|
@ -46,14 +46,41 @@ let
|
||||||
sig="$(${pkgs.coreutils}/bin/printf '%s' "$h64.$p64" | ${pkgs.openssl}/bin/openssl dgst -sha256 -sign "$pem_file" | b64url)"
|
sig="$(${pkgs.coreutils}/bin/printf '%s' "$h64.$p64" | ${pkgs.openssl}/bin/openssl dgst -sha256 -sign "$pem_file" | b64url)"
|
||||||
assertion="$h64.$p64.$sig"
|
assertion="$h64.$p64.$sig"
|
||||||
|
|
||||||
${pkgs.curl}/bin/curl -sS -X POST "${cfg.zitadelTokenEndpoint}" \
|
resp=""
|
||||||
|
if ! resp="$(${pkgs.curl}/bin/curl -sS --fail-with-body -X POST "${cfg.zitadelTokenEndpoint}" \
|
||||||
-H 'content-type: application/x-www-form-urlencoded' \
|
-H 'content-type: application/x-www-form-urlencoded' \
|
||||||
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
|
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
|
||||||
--data-urlencode "assertion=$assertion" \
|
--data-urlencode "assertion=$assertion" \
|
||||||
--data-urlencode "scope=${cfg.zitadelScopes}" \
|
--data-urlencode "scope=${cfg.zitadelScopes}" \
|
||||||
| ${pkgs.jq}/bin/jq -r .access_token
|
)"; then
|
||||||
|
echo "Zitadel token endpoint returned error; response:" >&2
|
||||||
|
echo "$resp" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
token="$(${pkgs.jq}/bin/jq -r '.access_token // empty' <<<"$resp" 2>/dev/null || true)"
|
||||||
|
if [ -z "$token" ] || [ "$token" = "null" ]; then
|
||||||
|
echo "Zitadel token mint did not return access_token; response:" >&2
|
||||||
|
echo "$resp" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Quick sanity check: JWT should have 2 dots.
|
||||||
|
if ! ${pkgs.gnugrep}/bin/grep -q '\\.' <<<"$token"; then
|
||||||
|
echo "Zitadel access_token does not look like a JWT; response:" >&2
|
||||||
|
echo "$resp" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
${pkgs.coreutils}/bin/printf '%s' "$token"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
zitadelHost =
|
||||||
|
let
|
||||||
|
noProto = lib.strings.removePrefix "https://" (lib.strings.removePrefix "http://" cfg.zitadelTokenEndpoint);
|
||||||
|
in
|
||||||
|
builtins.head (lib.strings.splitString "/" noProto);
|
||||||
|
|
||||||
mkAgentConfig = pkgs.writeText "vault-agent.hcl" ''
|
mkAgentConfig = pkgs.writeText "vault-agent.hcl" ''
|
||||||
vault {
|
vault {
|
||||||
address = "${cfg.openBaoAddr}"
|
address = "${cfg.openBaoAddr}"
|
||||||
|
|
@ -231,8 +258,13 @@ in
|
||||||
zitadel-mint-jwt = {
|
zitadel-mint-jwt = {
|
||||||
description = "Mint Zitadel access token (JWT) for OpenBao";
|
description = "Mint Zitadel access token (JWT) for OpenBao";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network-online.target" "nss-lookup.target" ];
|
after = [
|
||||||
wants = [ "network-online.target" ];
|
"network-online.target"
|
||||||
|
"nss-lookup.target"
|
||||||
|
"NetworkManager-wait-online.service"
|
||||||
|
"systemd-resolved.service"
|
||||||
|
];
|
||||||
|
wants = [ "network-online.target" "NetworkManager-wait-online.service" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
|
@ -249,16 +281,50 @@ in
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Wait for DNS + routing to be up.
|
echo "zitadel-mint-jwt: starting (host=${zitadelHost})" >&2
|
||||||
for i in {1..60}; do
|
|
||||||
if ${pkgs.glibc}/bin/getent hosts sso.joshuabell.xyz >/dev/null; then
|
jwt_is_valid() {
|
||||||
|
local token="$1"
|
||||||
|
local payload_b64 payload_json exp now
|
||||||
|
|
||||||
|
payload_b64="$(${pkgs.coreutils}/bin/printf '%s' "$token" | ${pkgs.coreutils}/bin/cut -d. -f2)"
|
||||||
|
payload_b64="$(${pkgs.coreutils}/bin/printf '%s' "$payload_b64" | ${pkgs.gnused}/bin/sed -e 's/-/+/g' -e 's/_/\//g')"
|
||||||
|
|
||||||
|
case $((${pkgs.coreutils}/bin/printf '%s' "$payload_b64" | ${pkgs.coreutils}/bin/wc -c)) in
|
||||||
|
*1) payload_b64="$payload_b64=" ;;
|
||||||
|
*2) payload_b64="$payload_b64==" ;;
|
||||||
|
*3) : ;;
|
||||||
|
*0) : ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
payload_json="$(${pkgs.coreutils}/bin/printf '%s' "$payload_b64" | ${pkgs.coreutils}/bin/base64 -d 2>/dev/null || true)"
|
||||||
|
exp="$(${pkgs.jq}/bin/jq -r '.exp // empty' <<<"$payload_json" 2>/dev/null || true)"
|
||||||
|
if [ -z "$exp" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
now="$(${pkgs.coreutils}/bin/date +%s)"
|
||||||
|
if [ "$exp" -gt $(( now + 60 )) ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -s "${cfg.zitadelJwtPath}" ] && jwt_is_valid "$(cat "${cfg.zitadelJwtPath}")"; then
|
||||||
|
echo "zitadel-mint-jwt: existing token still valid; skipping" >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for DNS to be usable.
|
||||||
|
for i in {1..120}; do
|
||||||
|
if ${pkgs.glibc}/bin/getent hosts ${zitadelHost} >/dev/null; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! ${pkgs.glibc}/bin/getent hosts sso.joshuabell.xyz >/dev/null; then
|
if ! ${pkgs.glibc}/bin/getent hosts ${zitadelHost} >/dev/null; then
|
||||||
echo "DNS still not ready for sso.joshuabell.xyz" >&2
|
echo "DNS still not ready for ${zitadelHost}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -276,7 +342,10 @@ in
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${pkgs.coreutils}/bin/printf '%s' "$jwt" > "${cfg.zitadelJwtPath}"
|
tmp="$(${pkgs.coreutils}/bin/mktemp)"
|
||||||
|
trap '${pkgs.coreutils}/bin/rm -f "$tmp"' EXIT
|
||||||
|
${pkgs.coreutils}/bin/printf '%s' "$jwt" > "$tmp"
|
||||||
|
${pkgs.coreutils}/bin/mv -f "$tmp" "${cfg.zitadelJwtPath}"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -296,7 +365,7 @@ in
|
||||||
User = "root";
|
User = "root";
|
||||||
Group = "root";
|
Group = "root";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "2s";
|
RestartSec = "30s";
|
||||||
|
|
||||||
UMask = "0077";
|
UMask = "0077";
|
||||||
ExecStart = "${pkgs.openbao}/bin/bao agent -config=${mkAgentConfig}";
|
ExecStart = "${pkgs.openbao}/bin/bao agent -config=${mkAgentConfig}";
|
||||||
|
|
@ -310,6 +379,8 @@ in
|
||||||
description = "Wait for OpenBao secret ${name}";
|
description = "Wait for OpenBao secret ${name}";
|
||||||
after = [ "vault-agent.service" ];
|
after = [ "vault-agent.service" ];
|
||||||
requires = [ "vault-agent.service" ];
|
requires = [ "vault-agent.service" ];
|
||||||
|
startLimitIntervalSec = 300;
|
||||||
|
startLimitBurst = 3;
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
|
|
@ -346,3 +417,4 @@ in
|
||||||
) cfg.secrets;
|
) cfg.secrets;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
44
hosts/juni/flake.lock
generated
44
hosts/juni/flake.lock
generated
|
|
@ -6,11 +6,11 @@
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "flakes/beszel",
|
"dir": "flakes/beszel",
|
||||||
"lastModified": 1767293741,
|
"lastModified": 1767294731,
|
||||||
"narHash": "sha256-mqcZB2uthea2TMcFmEgfPYGDC+O2px5hc/XPrlqsYMs=",
|
"narHash": "sha256-hwTTYLO7nfPA98w3r6zXP2zj66yWBjHAf90gWGcX4Yw=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "8fff3be0425341a048167db5385d9639f6355133",
|
"rev": "d923e49c193ef38127ca6680013eec31c55c8809",
|
||||||
"revCount": 1031,
|
"revCount": 1032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
||||||
},
|
},
|
||||||
|
|
@ -39,11 +39,11 @@
|
||||||
"common": {
|
"common": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "flakes/common",
|
"dir": "flakes/common",
|
||||||
"lastModified": 1767293741,
|
"lastModified": 1767294731,
|
||||||
"narHash": "sha256-mqcZB2uthea2TMcFmEgfPYGDC+O2px5hc/XPrlqsYMs=",
|
"narHash": "sha256-hwTTYLO7nfPA98w3r6zXP2zj66yWBjHAf90gWGcX4Yw=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "8fff3be0425341a048167db5385d9639f6355133",
|
"rev": "d923e49c193ef38127ca6680013eec31c55c8809",
|
||||||
"revCount": 1031,
|
"revCount": 1032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
||||||
},
|
},
|
||||||
|
|
@ -59,11 +59,11 @@
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "flakes/de_plasma",
|
"dir": "flakes/de_plasma",
|
||||||
"lastModified": 1767293741,
|
"lastModified": 1767294731,
|
||||||
"narHash": "sha256-mqcZB2uthea2TMcFmEgfPYGDC+O2px5hc/XPrlqsYMs=",
|
"narHash": "sha256-hwTTYLO7nfPA98w3r6zXP2zj66yWBjHAf90gWGcX4Yw=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "8fff3be0425341a048167db5385d9639f6355133",
|
"rev": "d923e49c193ef38127ca6680013eec31c55c8809",
|
||||||
"revCount": 1031,
|
"revCount": 1032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
||||||
},
|
},
|
||||||
|
|
@ -79,11 +79,11 @@
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "flakes/flatpaks",
|
"dir": "flakes/flatpaks",
|
||||||
"lastModified": 1767293741,
|
"lastModified": 1767294731,
|
||||||
"narHash": "sha256-mqcZB2uthea2TMcFmEgfPYGDC+O2px5hc/XPrlqsYMs=",
|
"narHash": "sha256-hwTTYLO7nfPA98w3r6zXP2zj66yWBjHAf90gWGcX4Yw=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "8fff3be0425341a048167db5385d9639f6355133",
|
"rev": "d923e49c193ef38127ca6680013eec31c55c8809",
|
||||||
"revCount": 1031,
|
"revCount": 1032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
||||||
},
|
},
|
||||||
|
|
@ -1147,11 +1147,11 @@
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "flakes/opencode",
|
"dir": "flakes/opencode",
|
||||||
"lastModified": 1767293741,
|
"lastModified": 1767294731,
|
||||||
"narHash": "sha256-mqcZB2uthea2TMcFmEgfPYGDC+O2px5hc/XPrlqsYMs=",
|
"narHash": "sha256-hwTTYLO7nfPA98w3r6zXP2zj66yWBjHAf90gWGcX4Yw=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "8fff3be0425341a048167db5385d9639f6355133",
|
"rev": "d923e49c193ef38127ca6680013eec31c55c8809",
|
||||||
"revCount": 1031,
|
"revCount": 1032,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
"url": "https://git.joshuabell.xyz/ringofstorms/dotfiles"
|
||||||
},
|
},
|
||||||
|
|
@ -1310,8 +1310,8 @@
|
||||||
},
|
},
|
||||||
"secrets-bao": {
|
"secrets-bao": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767294512,
|
"lastModified": 1767294735,
|
||||||
"narHash": "sha256-VJsOr6MRAskbLVRHtLplIHBvi6K45yj0H2TSP0V2SKI=",
|
"narHash": "sha256-AF5iJYVdgmXuNBblVymhS8jAniZerX/CyfBbcM0Hh5g=",
|
||||||
"path": "/home/josh/.config/nixos-config/flakes/secrets-bao",
|
"path": "/home/josh/.config/nixos-config/flakes/secrets-bao",
|
||||||
"type": "path"
|
"type": "path"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
"/etc/nixos"
|
"/etc/nixos"
|
||||||
"/etc/ssh"
|
"/etc/ssh"
|
||||||
"/etc/shadow" # keep passwords
|
|
||||||
|
|
||||||
"/etc/NetworkManager/system-connections"
|
"/etc/NetworkManager/system-connections"
|
||||||
"/var/lib/bluetooth"
|
"/var/lib/bluetooth"
|
||||||
|
|
@ -21,7 +20,16 @@
|
||||||
"/var/lib/fail2ban"
|
"/var/lib/fail2ban"
|
||||||
];
|
];
|
||||||
files = [
|
files = [
|
||||||
|
"/machine-key.json"
|
||||||
"/etc/machine-id"
|
"/etc/machine-id"
|
||||||
|
"/etc/resolv.conf" # TODO describe
|
||||||
|
"/etc/shadow" # keep passwords
|
||||||
|
"/etc/group"
|
||||||
|
"/etc/passwd"
|
||||||
|
"/etc/sudoers"
|
||||||
|
"/etc/localtime"
|
||||||
|
"/etc/timezone"
|
||||||
|
"/etc/adjtime"
|
||||||
];
|
];
|
||||||
users."${primaryUser}" = {
|
users."${primaryUser}" = {
|
||||||
directories = [
|
directories = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue