From df184b6e06cc3404add42ccf5ae68306395e8d6c Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Wed, 12 Aug 2026 18:01:26 +0000 Subject: [PATCH] lnd: don't pass the admin macaroon in `curl` argv `lnd-create-macaroons` interpolated the hex-encoded admin macaroon into `curl`'s argv, where any local user could read it from world-readable `/proc//cmdline`. The unit's `ProtectProc=invisible` doesn't apply, because `nbLib.rootScript`'s `+` prefix disables sandboxing for the process. Pass the header on a file descriptor instead, so the credential never enters any argv (`printf` is a bash builtin); the request sent to lnd is unchanged. Only configurations with a non-empty `services.lnd.macaroons` were affected, which `services.charge-lnd` and `services.btcpayserver` with `lightningBackend = "lnd"` set automatically. --- modules/lnd.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/lnd.nix b/modules/lnd.nix index 24a5ffe..94e26b6 100644 --- a/modules/lnd.nix +++ b/modules/lnd.nix @@ -265,13 +265,16 @@ in { curl = "${pkgs.curl}/bin/curl -fsS --cacert ${cfg.certPath}"; restUrl = "https://${nbLib.addressWithPort cfg.restAddress cfg.restPort}/v1"; # Setting macaroon permissions for other users needs root permissions + # The admin macaroon is passed to curl via a fd because argv is + # world-readable through /proc//cmdline script = nbLib.rootScript "lnd-create-macaroons" '' umask ug=r,o= ${lib.concatMapStrings (macaroon: '' echo "Create custom macaroon ${macaroon}" macaroonPath="$RUNTIME_DIRECTORY/${macaroon}.macaroon" + adminMacaroonHex=$(${pkgs.xxd}/bin/xxd -ps -u -c 99999 '${networkDir}/admin.macaroon') ${curl} \ - -H "Grpc-Metadata-macaroon: $(${pkgs.xxd}/bin/xxd -ps -u -c 99999 '${networkDir}/admin.macaroon')" \ + -H @<(printf 'Grpc-Metadata-macaroon: %s\n' "$adminMacaroonHex") \ -X POST \ -d '{"permissions":[${cfg.macaroons.${macaroon}.permissions}]}' \ ${restUrl}/macaroon |\