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:
Erik Arvstedt 2020-05-22 15:59:18 +02:00 committed by nixbitcoin
parent a040e52854
commit 5f3f362451
No known key found for this signature in database
GPG Key ID: DD11F9AD5308B3BA
3 changed files with 63 additions and 56 deletions

View File

@ -95,41 +95,38 @@ 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}";
} // (if cfg.enforceTor ExecStartPost = [
then nix-bitcoin-services.allowTor # Run fully privileged for secrets dir write access
else nix-bitcoin-services.allowAnyIP "+${nix-bitcoin-services.script ''
) // nix-bitcoin-services.allowAnyProtocol; # For ZMQ
postStart = let
mainnetDir = "${cfg.dataDir}/chain/bitcoin/mainnet";
in ''
umask 377
attempts=50 attempts=50
while ! { exec 3>/dev/tcp/127.0.0.1/8080 && exec 3>&-; } &>/dev/null; do while ! { exec 3>/dev/tcp/127.0.0.1/8080 && exec 3>&-; } &>/dev/null; do
((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; } ((attempts-- == 0)) && { echo "lnd REST service unreachable"; exit 1; }
sleep 0.1 sleep 0.1
done done
if [[ ! -f ${secretsDir}/lnd-seed-mnemonic ]]; then mnemonic=${secretsDir}/lnd-seed-mnemonic
if [[ ! -f $mnemonic ]]; then
echo Create lnd seed echo Create lnd seed
${pkgs.curl}/bin/curl -s \ ${pkgs.curl}/bin/curl -s \
--cacert ${secretsDir}/lnd-cert \ --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 -X GET https://127.0.0.1:8080/v1/genseed | ${pkgs.jq}/bin/jq -c '.cipher_seed_mnemonic' > "$mnemonic"
fi 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 if [[ ! -f ${mainnetDir}/wallet.db ]]; then
echo Create lnd wallet echo Create lnd wallet
@ -159,7 +156,12 @@ in {
while ! { exec 3>/dev/tcp/127.0.0.1/${toString cfg.rpcPort}; } &>/dev/null; do while ! { exec 3>/dev/tcp/127.0.0.1/${toString cfg.rpcPort}; } &>/dev/null; do
sleep 0.1 sleep 0.1
done done
''; ''}"
];
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP
) // nix-bitcoin-services.allowAnyProtocol; # For ZMQ
}; };
users.users.lnd = { users.users.lnd = {
description = "LND User"; description = "LND User";

View File

@ -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;
}; };
}; };

View File

@ -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}
'';
} }