Skip to content

Commit 81503eb

Browse files
committed
Merge #315: Use doas instead of sudo
47d257a docs: add rationale for doas to README and FAQ (nixbitcoin) b0039d6 docs: discourage users from ssh'ing into the root user (nixbitcoin) 2ca92a3 services: use doas if enabled (nixbitcoin) ce2b445 treewide: use runuser for dropping privileges (Erik Arvstedt) Pull request description: ACKs for top commit: jonasnick: ACK 47d257a Tree-SHA512: 84bab7de1cc6fb3d405a4fc4589f2be825275f69e48dede6ff62d1a27e3a386fea530c91a234d006ec6305a46d0ec54ca836f52f197541a3df215369c9b7c1e2
2 parents f968388 + 47d257a commit 81503eb

File tree

11 files changed

+56
-30
lines changed

11 files changed

+56
-30
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ NixOS modules
8181

8282
Security
8383
---
84-
* **Simplicity:** Only services you select in `configuration.nix` and their dependencies are installed, packages and dependencies are [pinned](pkgs/nixpkgs-pinned.nix), most packages are built from the [NixOS stable channel](https://github.com/NixOS/nixpkgs/tree/nixos-20.09), with a few exceptions that are built from the nixpkgs unstable channel, builds happen in a [sandboxed environment](https://nixos.org/manual/nix/stable/#conf-sandbox), code is continuously reviewed and refined.
84+
* **Simplicity:** Only services you select in `configuration.nix` and their dependencies are installed, packages and dependencies are [pinned](pkgs/nixpkgs-pinned.nix), support for [doas](https://github.com/Duncaen/OpenDoas) ([sudo alternative](https://lobste.rs/s/efsvqu/heap_based_buffer_overflow_sudo_cve_2021#c_c6fcfa)), most packages are built from the [NixOS stable channel](https://github.com/NixOS/nixpkgs/tree/nixos-20.09), with a few exceptions that are built from the nixpkgs unstable channel, builds happen in a [sandboxed environment](https://nixos.org/manual/nix/stable/#conf-sandbox), code is continuously reviewed and refined.
8585
* **Integrity:** Nix package manager, NixOS and packages can be built from source to reduce reliance on binary caches, nix-bitcoin merge commits are signed, all commits are approved by multiple nix-bitcoin developers, upstream packages are cryptographically verified where possible, we use this software ourselves.
8686
* **Principle of Least Privilege:** Services operate with least privileges; they each have their own user and are restricted further with [systemd options](pkgs/lib.nix), [RPC whitelisting](modules/bitcoind-rpc-public-whitelist.nix), and [netns-isolation](modules/netns-isolation.nix). There's a non-root user *operator* to interact with the various services.
8787
* **Defense-in-depth:** nix-bitcoin is built with a [hardened kernel](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/hardened.nix) by default, services are confined through discretionary access control, Linux namespaces, [dbus firewall](modules/security.nix) and seccomp-bpf with continuous improvements.

docs/faq.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@
3232
* **A:** Check your clightning logs with `journalctl -eu clightning`. Do you see something like `bitcoin-cli getblock ... false` failed? Are you using pruned mode? That means that clightning hasn't seen all the blocks it needs to and it can't get that block because your node is pruned. If you're just setting up a new node you can `systemctl stop clightning` and wipe your `/var/lib/clightning` directory. Otherwise you need to reindex the Bitcoin node.
3333
* **Q:** My disk space is getting low due to nix.
3434
* **A:** run `nix-collect-garbage -d`
35+
* **Q:** Where is `sudo`???
36+
* **A:** we replaced sudo with OpenBSD's doas after [CVE-2021-3156](https://www.openwall.com/lists/oss-security/2021/01/26/3). It has greatly reduced complexity, and is therefore less likely to be a source of severe vulnerabilities in the future.

docs/install.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ You can also build Nix from source by following the instructions at https://nixo
147147
nixops ssh operator@bitcoin-node
148148
```
149149
150+
For security reasons, all normal system management tasks can and should be performed with the `operator` user. Logging in as `root` should be done as rarely as possible.
151+
150152
See [usage.md](usage.md) for usage instructions, such as how to update.
151153
152154
To resize the VM disk image, you can use this helper script from within nix-shell:
@@ -426,4 +428,6 @@ Follow the [Setup deployment directory](#3-setup-deployment-directory) instructi
426428
nixops ssh operator@bitcoin-node
427429
```
428430
431+
For security reasons, all normal system management tasks can and should be performed with the `operator` user. Logging in as `root` should be done as rarely as possible.
432+
429433
See [usage.md](usage.md) for usage instructions, such as how to update.

modules/joinmarket.nix

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ let
77
nbLib = config.nix-bitcoin.lib;
88
nbPkgs = config.nix-bitcoin.pkgs;
99
secretsDir = config.nix-bitcoin.secretsDir;
10+
runAsUser = config.nix-bitcoin.runAsUserCmd;
1011

1112
inherit (config.services) bitcoind;
1213
torAddress = builtins.head (builtins.split ":" config.services.tor.client.socksListenAddress);
@@ -84,7 +85,7 @@ let
8485
for bin in jm-*; do
8586
{
8687
echo "#!${pkgs.bash}/bin/bash";
87-
echo "cd '${cfg.dataDir}' && ${cfg.cliExec} sudo -u ${cfg.user} $jm/$bin --datadir='${cfg.dataDir}' \"\$@\"";
88+
echo "cd '${cfg.dataDir}' && ${cfg.cliExec} ${runAsUser} ${cfg.user} $jm/$bin --datadir='${cfg.dataDir}' \"\$@\"";
8889
} > $out/bin/$bin
8990
done
9091
chmod -R +x $out/bin
@@ -166,7 +167,6 @@ in {
166167
wantedBy = [ "multi-user.target" ];
167168
requires = [ "bitcoind.service" ];
168169
after = [ "bitcoind.service" ];
169-
path = [ pkgs.sudo ];
170170
serviceConfig = nbLib.defaultHardening // {
171171
ExecStartPre = nbLib.privileged "joinmarket-create-config" ''
172172
install -o '${cfg.user}' -g '${cfg.group}' -m 640 ${configFile} ${cfg.dataDir}/joinmarket.cfg
@@ -183,7 +183,8 @@ in {
183183
echo "Create wallet"
184184
pw=$(cat "${secretsDir}"/jm-wallet-password)
185185
cd ${cfg.dataDir}
186-
if ! sudo -u ${cfg.user} ${nbPkgs.joinmarket}/bin/jm-genwallet --datadir=${cfg.dataDir} $walletname $pw \
186+
if ! ${pkgs.utillinux}/bin/runuser -u ${cfg.user} -- \
187+
${nbPkgs.joinmarket}/bin/jm-genwallet --datadir=${cfg.dataDir} $walletname $pw \
187188
| grep 'recovery_seed' \
188189
| cut -d ':' -f2 \
189190
| (umask u=r,go=; cat > "${secretsDir}/jm-wallet-seed"); then
@@ -211,7 +212,7 @@ in {
211212
users.groups.${cfg.group} = {};
212213
nix-bitcoin.operator = {
213214
groups = [ cfg.group ];
214-
sudoUsers = [ cfg.group ];
215+
allowRunAsUsers = [ cfg.group ];
215216
};
216217

217218
nix-bitcoin.secrets.jm-wallet-password.user = cfg.user;

modules/lnd-rest-onion-service.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ let
66
cfg = config.services.lnd.restOnionService;
77
nbLib = config.nix-bitcoin.lib;
88
secretsDir = config.nix-bitcoin.secretsDir;
9+
runAsUser = config.nix-bitcoin.runAsUserCmd;
910

1011
lnd = config.services.lnd;
1112

1213
bin = pkgs.writeScriptBin "lndconnect-rest-onion" ''
13-
#!/usr/bin/env -S sudo -u lnd ${pkgs.bash}/bin/bash
14+
#!/usr/bin/env -S ${runAsUser} lnd ${pkgs.bash}/bin/bash
1415
1516
exec ${cfg.package}/bin/lndconnect \
1617
--host=$(cat ${config.nix-bitcoin.onionAddresses.dataDir}/lnd/lnd-rest) \

modules/lnd.nix

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ let
66
cfg = config.services.lnd;
77
nbLib = config.nix-bitcoin.lib;
88
secretsDir = config.nix-bitcoin.secretsDir;
9+
runAsUser = config.nix-bitcoin.runAsUserCmd;
910

1011
bitcoind = config.services.bitcoind;
1112
bitcoindRpcAddress = bitcoind.rpc.address;
@@ -123,7 +124,7 @@ in {
123124
default = pkgs.writeScriptBin "lncli"
124125
# Switch user because lnd makes datadir contents readable by user only
125126
''
126-
sudo -u lnd ${cfg.package}/bin/lncli \
127+
${runAsUser} lnd ${cfg.package}/bin/lncli \
127128
--rpcserver ${cfg.rpcAddress}:${toString cfg.rpcPort} \
128129
--tlscertpath '${secretsDir}/lnd-cert' \
129130
--macaroonpath '${networkDir}/admin.macaroon' "$@"
@@ -270,7 +271,7 @@ in {
270271
users.groups.lnd = {};
271272
nix-bitcoin.operator = {
272273
groups = [ "lnd" ];
273-
sudoUsers = [ "lnd" ];
274+
allowRunAsUsers = [ "lnd" ];
274275
};
275276

276277
nix-bitcoin.secrets = {

modules/modules.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ with lib;
5757
"$@"
5858
'';
5959
};
60+
61+
# A helper for using doas instead of sudo when doas is enabled
62+
runAsUserCmd = mkOption {
63+
readOnly = true;
64+
default = if config.security.doas.enable
65+
then "doas -u"
66+
else "sudo -u";
67+
};
6068
};
6169
};
6270

modules/operator.nix

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ in {
2222
default = [];
2323
description = "Extra groups.";
2424
};
25-
sudoUsers = mkOption {
25+
allowRunAsUsers = mkOption {
2626
type = with types; listOf str;
2727
default = [];
2828
description = "Users as which the operator is allowed to run commands.";
@@ -38,10 +38,14 @@ in {
3838
] ++ cfg.groups;
3939
};
4040

41-
security.sudo.extraConfig = mkIf (cfg.sudoUsers != []) (let
42-
users = builtins.concatStringsSep "," cfg.sudoUsers;
43-
in ''
44-
${cfg.name} ALL=(${users}) NOPASSWD: ALL
45-
'');
41+
security = mkIf (cfg.allowRunAsUsers != []) {
42+
# Use doas instead of sudo if enabled
43+
doas.extraConfig = mkIf config.security.doas.enable ''
44+
${lib.concatMapStrings (user: "permit nopass ${cfg.name} as ${user}\n") cfg.allowRunAsUsers}
45+
'';
46+
sudo.extraConfig = mkIf (!config.security.doas.enable) ''
47+
${cfg.name} ALL=(${builtins.concatStringsSep "," cfg.allowRunAsUsers}) NOPASSWD: ALL
48+
'';
49+
};
4650
};
4751
}

modules/presets/secure-node.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ in {
2020

2121
nix-bitcoin.security.hideProcessInformation = true;
2222

23+
# Use doas instead of sudo
24+
security.doas.enable = true;
25+
security.sudo.enable = false;
26+
2327
environment.systemPackages = with pkgs; [
2428
jq
2529
];

modules/recurring-donations.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ in {
7878
systemd.services.recurring-donations = {
7979
requires = [ "clightning.service" ];
8080
after = [ "clightning.service" ];
81-
path = with pkgs; [ nix-bitcoin.clightning curl sudo jq ];
81+
path = with pkgs; [ nix-bitcoin.clightning curl jq ];
8282
serviceConfig = nbLib.defaultHardening // {
8383
ExecStart = "${pkgs.bash}/bin/bash ${recurring-donations-script}";
8484
User = "recurring-donations";

0 commit comments

Comments
 (0)