lnd: add strict hardening
Add ProtectSystem=strict, remove PermissionStartOnly. Extract the section of postStart that needs secrets dir write access into a separate script with full privileges. Simplify preStart and fix dataDir quoting.
This commit is contained in:
parent
a040e52854
commit
5f3f362451
110
modules/lnd.nix
110
modules/lnd.nix
@ -95,71 +95,73 @@ in {
|
|||||||
requires = [ "bitcoind.service" ];
|
requires = [ "bitcoind.service" ];
|
||||||
after = [ "bitcoind.service" ];
|
after = [ "bitcoind.service" ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
cp ${configFile} ${cfg.dataDir}/lnd.conf
|
install -m600 ${configFile} '${cfg.dataDir}/lnd.conf'
|
||||||
chown -R 'lnd:lnd' '${cfg.dataDir}'
|
|
||||||
chmod u=rw,g=r,o= ${cfg.dataDir}/lnd.conf
|
|
||||||
echo "bitcoind.rpcpass=$(cat ${secretsDir}/bitcoin-rpcpassword)" >> '${cfg.dataDir}/lnd.conf'
|
echo "bitcoind.rpcpass=$(cat ${secretsDir}/bitcoin-rpcpassword)" >> '${cfg.dataDir}/lnd.conf'
|
||||||
'';
|
'';
|
||||||
serviceConfig = nix-bitcoin-services.defaultHardening // {
|
serviceConfig = nix-bitcoin-services.defaultHardening // {
|
||||||
PermissionsStartOnly = "true";
|
|
||||||
ExecStart = "${cfg.package}/bin/lnd --configfile=${cfg.dataDir}/lnd.conf";
|
ExecStart = "${cfg.package}/bin/lnd --configfile=${cfg.dataDir}/lnd.conf";
|
||||||
User = "lnd";
|
User = "lnd";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
ProtectSystem = "full"; # ToDo: Make more restrictive
|
ReadWritePaths = "${cfg.dataDir}";
|
||||||
|
ExecStartPost = [
|
||||||
|
# Run fully privileged for secrets dir write access
|
||||||
|
"+${nix-bitcoin-services.script ''
|
||||||
|
attempts=50
|
||||||
|
while ! { exec 3>/dev/tcp/127.0.0.1/8080 && exec 3>&-; } &>/dev/null; do
|
||||||
|
((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; }
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
mnemonic=${secretsDir}/lnd-seed-mnemonic
|
||||||
|
if [[ ! -f $mnemonic ]]; then
|
||||||
|
echo Create lnd seed
|
||||||
|
|
||||||
|
${pkgs.curl}/bin/curl -s \
|
||||||
|
--cacert ${secretsDir}/lnd-cert \
|
||||||
|
-X GET https://127.0.0.1:8080/v1/genseed | ${pkgs.jq}/bin/jq -c '.cipher_seed_mnemonic' > "$mnemonic"
|
||||||
|
fi
|
||||||
|
chown lnd: "$mnemonic"
|
||||||
|
chmod 400 "$mnemonic"
|
||||||
|
''}"
|
||||||
|
"${let
|
||||||
|
mainnetDir = "${cfg.dataDir}/chain/bitcoin/mainnet";
|
||||||
|
in nix-bitcoin-services.script ''
|
||||||
|
if [[ ! -f ${mainnetDir}/wallet.db ]]; then
|
||||||
|
echo Create lnd wallet
|
||||||
|
|
||||||
|
${pkgs.curl}/bin/curl -s --output /dev/null --show-error \
|
||||||
|
--cacert ${secretsDir}/lnd-cert \
|
||||||
|
-X POST -d "{\"wallet_password\": \"$(cat ${secretsDir}/lnd-wallet-password | tr -d '\n' | base64 -w0)\", \
|
||||||
|
\"cipher_seed_mnemonic\": $(cat ${secretsDir}/lnd-seed-mnemonic | tr -d '\n')}" \
|
||||||
|
https://127.0.0.1:8080/v1/initwallet
|
||||||
|
|
||||||
|
# Guarantees that RPC calls with cfg.cli succeed after the service is started
|
||||||
|
echo Wait until wallet is created
|
||||||
|
while [[ ! -f ${mainnetDir}/admin.macaroon ]]; do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo Unlock lnd wallet
|
||||||
|
|
||||||
|
${pkgs.curl}/bin/curl -s \
|
||||||
|
-H "Grpc-Metadata-macaroon: $(${pkgs.xxd}/bin/xxd -ps -u -c 99999 '${mainnetDir}/admin.macaroon')" \
|
||||||
|
--cacert ${secretsDir}/lnd-cert \
|
||||||
|
-X POST \
|
||||||
|
-d "{\"wallet_password\": \"$(cat ${secretsDir}/lnd-wallet-password | tr -d '\n' | base64 -w0)\"}" \
|
||||||
|
https://127.0.0.1:8080/v1/unlockwallet
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait until the RPC port is open
|
||||||
|
while ! { exec 3>/dev/tcp/127.0.0.1/${toString cfg.rpcPort}; } &>/dev/null; do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
''}"
|
||||||
|
];
|
||||||
} // (if cfg.enforceTor
|
} // (if cfg.enforceTor
|
||||||
then nix-bitcoin-services.allowTor
|
then nix-bitcoin-services.allowTor
|
||||||
else nix-bitcoin-services.allowAnyIP
|
else nix-bitcoin-services.allowAnyIP
|
||||||
) // nix-bitcoin-services.allowAnyProtocol; # For ZMQ
|
) // nix-bitcoin-services.allowAnyProtocol; # For ZMQ
|
||||||
postStart = let
|
|
||||||
mainnetDir = "${cfg.dataDir}/chain/bitcoin/mainnet";
|
|
||||||
in ''
|
|
||||||
umask 377
|
|
||||||
|
|
||||||
attempts=50
|
|
||||||
while ! { exec 3>/dev/tcp/127.0.0.1/8080 && exec 3>&-; } &>/dev/null; do
|
|
||||||
((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; }
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ ! -f ${secretsDir}/lnd-seed-mnemonic ]]; then
|
|
||||||
echo Create lnd seed
|
|
||||||
|
|
||||||
${pkgs.curl}/bin/curl -s \
|
|
||||||
--cacert ${secretsDir}/lnd-cert \
|
|
||||||
-X GET https://127.0.0.1:8080/v1/genseed | ${pkgs.jq}/bin/jq -c '.cipher_seed_mnemonic' > ${secretsDir}/lnd-seed-mnemonic
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f ${mainnetDir}/wallet.db ]]; then
|
|
||||||
echo Create lnd wallet
|
|
||||||
|
|
||||||
${pkgs.curl}/bin/curl -s --output /dev/null --show-error \
|
|
||||||
--cacert ${secretsDir}/lnd-cert \
|
|
||||||
-X POST -d "{\"wallet_password\": \"$(cat ${secretsDir}/lnd-wallet-password | tr -d '\n' | base64 -w0)\", \
|
|
||||||
\"cipher_seed_mnemonic\": $(cat ${secretsDir}/lnd-seed-mnemonic | tr -d '\n')}" \
|
|
||||||
https://127.0.0.1:8080/v1/initwallet
|
|
||||||
|
|
||||||
# Guarantees that RPC calls with cfg.cli succeed after the service is started
|
|
||||||
echo Wait until wallet is created
|
|
||||||
while [[ ! -f ${mainnetDir}/admin.macaroon ]]; do
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo Unlock lnd wallet
|
|
||||||
|
|
||||||
${pkgs.curl}/bin/curl -s \
|
|
||||||
-H "Grpc-Metadata-macaroon: $(${pkgs.xxd}/bin/xxd -ps -u -c 99999 '${mainnetDir}/admin.macaroon')" \
|
|
||||||
--cacert ${secretsDir}/lnd-cert \
|
|
||||||
-X POST \
|
|
||||||
-d "{\"wallet_password\": \"$(cat ${secretsDir}/lnd-wallet-password | tr -d '\n' | base64 -w0)\"}" \
|
|
||||||
https://127.0.0.1:8080/v1/unlockwallet
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait until the RPC port is open
|
|
||||||
while ! { exec 3>/dev/tcp/127.0.0.1/${toString cfg.rpcPort}; } &>/dev/null; do
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
users.users.lnd = {
|
users.users.lnd = {
|
||||||
description = "LND User";
|
description = "LND User";
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
options = {
|
options = {
|
||||||
nix-bitcoin-services = lib.mkOption {
|
nix-bitcoin-services = lib.mkOption {
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
default = import ./nix-bitcoin-services.nix lib;
|
default = import ./nix-bitcoin-services.nix lib pkgs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# See `man systemd.exec` and `man systemd.resource-control` for an explanation
|
# See `man systemd.exec` and `man systemd.resource-control` for an explanation
|
||||||
# of the various systemd options available through this module.
|
# of the various systemd options available through this module.
|
||||||
|
|
||||||
lib:
|
lib: pkgs:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
{
|
{
|
||||||
@ -42,4 +42,9 @@ with lib;
|
|||||||
to 127.0.0.1;";
|
to 127.0.0.1;";
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script = src: pkgs.writers.writeBash "script" ''
|
||||||
|
set -eo pipefail
|
||||||
|
${src}
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user