Skip to content

Commit

Permalink
Merge #174: Hardening systemd
Browse files Browse the repository at this point in the history
ccc3a70 service hardening: add more restrictions (nixbitcoin)
3fbfa98 service hardening: replace obtuse SystemCallFilter with @System-service (nixbitcoin)
e34d1c8 service hardening: Add PrivateUsers (nixbitcoin)
1c75543 clightning: add user and group options (nixbitcoin)
5f3f362 lnd: add strict hardening (Erik Arvstedt)
a040e52 All modules: ProtectSystem = strict (nixbitcoin)
adc71b8 Remove PermissionStartOnly where possible and replace with bitcoinrpc (nixbitcoin)
91b6b2c All modules with preStart: Use systemd.tmpfiles.rules (nixbitcoin)
423ebf8 lnd: only enable bitcoind zmqpub if lnd.enable (nixbitcoin)
81a1c3f service hardening: Add CapabilityBoundingSets (nixbitcoin)
3cd6150 webindex & onion-chef: Run non-network-facing services in PrivateNetwork (nixbitcoin)
7c70dd4 All modules: Give service config precedence over defaultHardening (nixbitcoin)

Pull request description:

ACKs for top commit:
  erikarvstedt:
    ACK ccc3a70
  jonasnick:
    ACK ccc3a70 very nice

Tree-SHA512: 069f74b11b46b17fd180e9da5328a3b9952aa90100b5077251d1e56a4d64f03ba64587adf153ddc6cf42f750c13a168f9f0fe43bc379bcd4a9f6709e635e512a
  • Loading branch information
jonasnick committed May 26, 2020
2 parents 0ac1e49 + ccc3a70 commit 8cc0b30
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 129 deletions.
29 changes: 13 additions & 16 deletions modules/bitcoind.nix
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,17 @@ in {
sysperms = true;
};

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
"d '${cfg.dataDir}/blocks' 0770 ${cfg.user} ${cfg.group} - -"
];

systemd.services.bitcoind = {
description = "Bitcoin daemon";
requires = [ "nix-bitcoin-secrets.target" ];
after = [ "network.target" "nix-bitcoin-secrets.target" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
if [[ ! -e ${cfg.dataDir} ]]; then
mkdir -m 0770 -p '${cfg.dataDir}'
fi
if [[ ! -e ${cfg.dataDir}/blocks ]]; then
mkdir -m 0770 -p '${cfg.dataDir}/blocks'
fi
chown -R '${cfg.user}:${cfg.group}' '${cfg.dataDir}'
${optionalString cfg.dataDirReadableByGroup "chmod -R g+rX '${cfg.dataDir}/blocks'"}
cfg=$(cat ${configFile}; printf "rpcpassword="; cat "${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword")
Expand All @@ -282,17 +280,14 @@ in {
sleep 0.05
done
'';
serviceConfig = {
serviceConfig = nix-bitcoin-services.defaultHardening // {
User = "${cfg.user}";
Group = "${cfg.group}";
ExecStart = "${cfg.package}/bin/bitcoind -datadir='${cfg.dataDir}'";
Restart = "on-failure";
UMask = mkIf cfg.dataDirReadableByGroup "0027";

# Permission for preStart
PermissionsStartOnly = "true";
} // nix-bitcoin-services.defaultHardening
// (if cfg.enforceTor
ReadWritePaths = "${cfg.dataDir}";
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP)
// optionalAttrs (cfg.zmqpubrawblock != null || cfg.zmqpubrawtx != null) nix-bitcoin-services.allowAnyProtocol;
Expand Down Expand Up @@ -320,21 +315,23 @@ in {
fi
done
'';
serviceConfig = {
serviceConfig = nix-bitcoin-services.defaultHardening // {
User = "${cfg.user}";
Group = "${cfg.group}";
} // nix-bitcoin-services.defaultHardening
// nix-bitcoin-services.allowTor;
ReadWritePaths = "${cfg.dataDir}";
} // nix-bitcoin-services.allowTor;
};

users.users.${cfg.user} = {
group = cfg.group;
description = "Bitcoin daemon user";
};
users.groups.${cfg.group} = {};
users.groups.bitcoinrpc = {};

nix-bitcoin.secrets.bitcoin-rpcpassword = {
user = "bitcoin";
group = "bitcoinrpc";
};
};
}
33 changes: 23 additions & 10 deletions modules/clightning.nix
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ in {
default = "/var/lib/clightning";
description = "The data directory for clightning.";
};
user = mkOption {
type = types.str;
default = "clightning";
description = "The user as which to run clightning.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run clightning.";
};
cli = mkOption {
readOnly = true;
default = pkgs.writeScriptBin "lightning-cli"
Expand All @@ -72,11 +82,16 @@ in {

config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.nix-bitcoin.clightning (hiPrio cfg.cli) ];
users.users.clightning = {
users.users.${cfg.user} = {
description = "clightning User";
group = "clightning";
group = cfg.group;
extraGroups = [ "bitcoinrpc" ];
};
users.groups.clightning = {};
users.groups.${cfg.group} = {};

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];

systemd.services.clightning = {
description = "Run clightningd";
Expand All @@ -85,22 +100,20 @@ in {
requires = [ "bitcoind.service" ];
after = [ "bitcoind.service" ];
preStart = ''
mkdir -m 0770 -p ${cfg.dataDir}
cp ${configFile} ${cfg.dataDir}/config
chown -R 'clightning:clightning' '${cfg.dataDir}'
chown -R '${cfg.user}:${cfg.group}' '${cfg.dataDir}'
# The RPC socket has to be removed otherwise we might have stale sockets
rm -f ${cfg.dataDir}/bitcoin/lightning-rpc
chmod 600 ${cfg.dataDir}/config
echo "bitcoin-rpcpassword=$(cat ${config.nix-bitcoin.secretsDir}/bitcoin-rpcpassword)" >> '${cfg.dataDir}/config'
'';
serviceConfig = {
PermissionsStartOnly = "true";
serviceConfig = nix-bitcoin-services.defaultHardening // {
ExecStart = "${pkgs.nix-bitcoin.clightning}/bin/lightningd --lightning-dir=${cfg.dataDir}";
User = "clightning";
User = "${cfg.user}";
Restart = "on-failure";
RestartSec = "10s";
} // nix-bitcoin-services.defaultHardening
// (if cfg.enforceTor
ReadWritePaths = "${cfg.dataDir}";
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP
);
Expand Down
15 changes: 8 additions & 7 deletions modules/electrs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,23 @@ in {
config = mkIf cfg.enable (mkMerge [{
environment.systemPackages = [ pkgs.nix-bitcoin.electrs ];

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];

systemd.services.electrs = {
description = "Electrs Electrum Server";
wantedBy = [ "multi-user.target" ];
requires = [ "bitcoind.service" ];
after = [ "bitcoind.service" ];
preStart = ''
mkdir -m 0770 -p ${cfg.dataDir}
chown -R '${cfg.user}:${cfg.group}' ${cfg.dataDir}
echo "cookie = \"${config.services.bitcoind.rpcuser}:$(cat ${secretsDir}/bitcoin-rpcpassword)\"" \
> electrs.toml
'';
serviceConfig = {
serviceConfig = nix-bitcoin-services.defaultHardening // {
RuntimeDirectory = "electrs";
RuntimeDirectoryMode = "700";
WorkingDirectory = "/run/electrs";
PermissionsStartOnly = "true";
ExecStart = ''
${pkgs.nix-bitcoin.electrs}/bin/electrs -vvv \
${if cfg.high-memory then
Expand All @@ -96,8 +97,8 @@ in {
Group = cfg.group;
Restart = "on-failure";
RestartSec = "10s";
} // nix-bitcoin-services.defaultHardening
// (if cfg.enforceTor
ReadWritePaths = "${cfg.dataDir} ${if cfg.high-memory then "${config.services.bitcoind.dataDir}" else ""}";
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP
);
Expand All @@ -106,7 +107,7 @@ in {
users.users.${cfg.user} = {
description = "electrs User";
group = cfg.group;
extraGroups = optionals cfg.high-memory [ "bitcoin" ];
extraGroups = [ "bitcoinrpc" ] ++ optionals cfg.high-memory [ "bitcoin" ];
};
users.groups.${cfg.group} = {};
}
Expand Down
7 changes: 4 additions & 3 deletions modules/lightning-charge.nix
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,16 @@ in {
chmod 600 ${cfg.dataDir}/lightning-charge.db
fi
'';
serviceConfig = {
serviceConfig = nix-bitcoin-services.defaultHardening // {
# Needed to access clightning.dataDir in preStart
PermissionsStartOnly = "true";
EnvironmentFile = "${config.nix-bitcoin.secretsDir}/lightning-charge-env";
ExecStart = "${pkgs.nix-bitcoin.lightning-charge}/bin/charged -l ${config.services.clightning.dataDir}/bitcoin -d ${cfg.dataDir}/lightning-charge.db";
User = user;
Restart = "on-failure";
RestartSec = "10s";
} // nix-bitcoin-services.defaultHardening
// nix-bitcoin-services.nodejs
ReadWritePaths = "${cfg.dataDir}";
} // nix-bitcoin-services.nodejs
// nix-bitcoin-services.allowTor;
};
nix-bitcoin.secrets.lightning-charge-env.user = user;
Expand Down
21 changes: 10 additions & 11 deletions modules/liquid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,39 @@ in {
(hiPrio cfg.cli)
(hiPrio cfg.swap-cli)
];

systemd.tmpfiles.rules = [
"d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
];

systemd.services.liquidd = {
description = "Elements daemon providing access to the Liquid sidechain";
requires = [ "bitcoind.service" ];
after = [ "bitcoind.service" ];
wantedBy = [ "multi-user.target" ];
preStart = ''
if ! test -e ${cfg.dataDir}; then
mkdir -m 0770 -p '${cfg.dataDir}'
fi
cp '${configFile}' '${cfg.dataDir}/elements.conf'
chmod o-rw '${cfg.dataDir}/elements.conf'
chmod 640 '${cfg.dataDir}/elements.conf'
chown -R '${cfg.user}:${cfg.group}' '${cfg.dataDir}'
echo "rpcpassword=$(cat ${secretsDir}/liquid-rpcpassword)" >> '${cfg.dataDir}/elements.conf'
echo "mainchainrpcpassword=$(cat ${secretsDir}/bitcoin-rpcpassword)" >> '${cfg.dataDir}/elements.conf'
'';
serviceConfig = {
serviceConfig = nix-bitcoin-services.defaultHardening // {
Type = "simple";
User = "${cfg.user}";
Group = "${cfg.group}";
ExecStart = "${pkgs.nix-bitcoin.elementsd}/bin/elementsd ${cmdlineOptions}";
StateDirectory = "liquidd";
PIDFile = "${pidFile}";
Restart = "on-failure";

# Permission for preStart
PermissionsStartOnly = "true";
} // nix-bitcoin-services.defaultHardening
// (if cfg.enforceTor
ReadWritePaths = "${cfg.dataDir}";
} // (if cfg.enforceTor
then nix-bitcoin-services.allowTor
else nix-bitcoin-services.allowAnyIP
);
};
users.users.${cfg.user} = {
group = cfg.group;
extraGroups = [ "bitcoinrpc" ];
description = "Liquid sidechain user";
};
users.groups.${cfg.group} = {};
Expand Down
Loading

0 comments on commit 8cc0b30

Please sign in to comment.