From a5730eb736c2f71b3762621d978e38258932799a Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Mon, 8 Nov 2021 12:45:26 +0100 Subject: [PATCH 1/7] makeShell: make the help msg a shell derivation variable - The message is now a nix string, which simplifies formatting. - The message can be now be modified via overrideAttrs in client shells. This is more effective than changing the message in Bash. --- helper/makeShell.nix | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/helper/makeShell.nix b/helper/makeShell.nix index 3e10418..fa212fe 100644 --- a/helper/makeShell.nix +++ b/helper/makeShell.nix @@ -12,6 +12,31 @@ in pkgs.stdenv.mkDerivation { name = "nix-bitcoin-environment"; + helpMessage = '' + nix-bitcoin path: ${toString ../.} + + Available commands + ================== + deploy + Run krops-deploy and eval-config in parallel. + This ensures that eval failures appear quickly when deploying. + In this case, deployment is stopped. + + krops-deploy + Deploy your node via krops + + eval-config + Evaluate your node system configuration + + generate-secrets + Create secrets required by your node configuration. + Secrets are written to ./secrets/ + This function is automatically called by krops-deploy. + + update-nix-bitcoin + Fetch and use the latest version of nix-bitcoin + ''; + shellHook = '' export NIX_PATH="nixpkgs=${nixpkgs}:nix-bitcoin=${toString ../.}:." ${path} @@ -22,31 +47,10 @@ pkgs.stdenv.mkDerivation { # 2. the shell is interactive if [[ -t 1 && $- == *i* ]]; then isInteractive=1; else isInteractive=; fi - nixBitcoinHelp() { - echo "nix-bitcoin path: ${toString ../.}" - echo - echo "Available commands" - echo "==================" - echo "deploy" - echo " Run krops-deploy and eval-config in parallel." - echo " This ensures that eval failures appear quickly when deploying." - echo " In this case, deployment is stopped." - echo - echo "krops-deploy" - echo " Deploy your node via krops" - echo - echo "eval-config" - echo " Evaluate your node system configuration" - echo - echo "generate-secrets" - echo " Create secrets required by your node configuration." - echo " Secrets are written to ./secrets/" - echo " This function is automatically called by krops-deploy." - echo - echo "update-nix-bitcoin" - echo " Fetch and use the latest version of nix-bitcoin" - } - help() { nixBitcoinHelp; } + # Make this a non-environment var + export -n helpMessage + + help() { echo "$helpMessage"; } h() { help; } fetch-release() { From 7f77147b600b62326db9192c2f0c2e5ac62236be Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Mon, 8 Nov 2021 12:45:27 +0100 Subject: [PATCH 2/7] makeShell: minor improvements - import pkgs without the global config to avoid pulling in external state - rename `path` -> `setPath` - export `nixpkgsUnstable` This avoids garbage collection of nixpkgs-unstable for gcrooted shell environments (like those created by lorri) --- helper/makeShell.nix | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/helper/makeShell.nix b/helper/makeShell.nix index fa212fe..933ecb4 100644 --- a/helper/makeShell.nix +++ b/helper/makeShell.nix @@ -1,11 +1,12 @@ { configDir, shellVersion ? null, extraShellInitCmds ? (pkgs: "") }: let + pinned = import ../pkgs/nixpkgs-pinned.nix; + pkgs = import nixpkgs { config = {}; overlays = []; }; inherit (pkgs) lib; - nixpkgs = (import ../pkgs/nixpkgs-pinned.nix).nixpkgs; - pkgs = import nixpkgs {}; + inherit (pinned) nixpkgs; nbPkgs = import ../pkgs { inherit pkgs; }; cfgDir = toString configDir; - path = lib.optionalString pkgs.stdenv.isLinux '' + setPath = lib.optionalString pkgs.stdenv.isLinux '' export PATH="${lib.makeBinPath [ nbPkgs.pinned.extra-container ]}''${PATH:+:}$PATH" ''; in @@ -39,8 +40,9 @@ pkgs.stdenv.mkDerivation { shellHook = '' export NIX_PATH="nixpkgs=${nixpkgs}:nix-bitcoin=${toString ../.}:." - ${path} + ${setPath} export NIX_BITCOIN_EXAMPLES_DIR="${cfgDir}" + export nixpkgsUnstable="${pinned.nixpkgs-unstable}" # Set isInteractive=1 if # 1. stdout is a TTY, i.e. we're not piping the output From cb6e5ef7029954a737bdb45401c573d051cf9501 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Mon, 8 Nov 2021 12:45:28 +0100 Subject: [PATCH 3/7] netns-isolation: fix routing issues due to netns restarting Previously, restarting a service implied restarting its netns. For unknown reasons, this sometimes caused the netns-local address to not be routable from the root netns for up to 20 s. I.e., the service was sometimes unreachable after restarting. Now the netns is no longer stopped when the service is stopped. --- modules/netns-isolation.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/netns-isolation.nix b/modules/netns-isolation.nix index a2dc63f..655325e 100644 --- a/modules/netns-isolation.nix +++ b/modules/netns-isolation.nix @@ -164,9 +164,8 @@ in { "netns-${n}" = rec { requires = [ "nb-netns-bridge.service" ]; after = [ "nb-netns-bridge.service" ]; - bindsTo = [ "${n}.service" ]; - requiredBy = bindsTo; - before = bindsTo; + requiredBy = [ "${n}.service" ]; + before = requiredBy; script = '' ${ip} netns add ${netnsName} ${ipNetns} link set lo up From f58d67677e3179258159d0dc3145ac1aac65e1ec Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Mon, 8 Nov 2021 12:45:29 +0100 Subject: [PATCH 4/7] netns-isolation: separate host and netns setup - Improves readability - `netns exec ...` (called via `netnsIptables`) incurs a large overhead: In addition to netns switching, a mount namespace is setup and populated with the contents of /etc/netns//. Instead, simply run `nsenter`. --- modules/netns-isolation.nix | 70 ++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/modules/netns-isolation.nix b/modules/netns-isolation.nix index 655325e..f12e391 100644 --- a/modules/netns-isolation.nix +++ b/modules/netns-isolation.nix @@ -155,9 +155,42 @@ in { veth = "nb-veth-${toString v.id}"; peer = "nb-veth-br-${toString v.id}"; inherit (v) netnsName; - ipNetns = "${ip} -n ${netnsName}"; - netnsIptables = "${ip} netns exec ${netnsName} ${config.networking.firewall.package}/bin/iptables"; + nsenter = "${pkgs.utillinux}/bin/nsenter"; allowedAddresses = concatMapStringsSep "," (available: netns.${available}.address) v.availableNetns; + + setup = '' + ${ip} netns add ${netnsName} + ${ip} link add ${veth} type veth peer name ${peer} + ${ip} link set ${veth} netns ${netnsName} + # The peer link is never used directly, so don't auto-assign an IPv6 address + echo 1 > /proc/sys/net/ipv6/conf/${peer}/disable_ipv6 + ${ip} link set ${peer} up + ${ip} link set ${peer} master nb-br + exec ${nsenter} --net=/run/netns/${netnsName} ${script "in-netns" setupInNetns} + ''; + + setupInNetns = '' + ${ip} link set lo up + ${ip} addr add ${v.address}/24 dev ${veth} + ${ip} link set ${veth} up + ${ip} route add default via ${bridgeIp} + + ${iptables} -w -P INPUT DROP + ${iptables} -w -A INPUT -s 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT + # allow return traffic to outgoing connections initiated by the service itself + ${iptables} -w -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT + '' + optionalString (config.services.${n}.enforceTor or false) '' + ${iptables} -w -P OUTPUT DROP + ${iptables} -w -A OUTPUT -d 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT + '' + optionalString (v.availableNetns != []) '' + ${iptables} -w -A INPUT -s ${allowedAddresses} -j ACCEPT + ${iptables} -w -A OUTPUT -d ${allowedAddresses} -j ACCEPT + ''; + + script = name: src: pkgs.writers.writeDash name '' + set -e + ${src} + ''; in { "${n}".serviceConfig.NetworkNamespacePath = "/var/run/netns/${netnsName}"; @@ -166,29 +199,11 @@ in { after = [ "nb-netns-bridge.service" ]; requiredBy = [ "${n}.service" ]; before = requiredBy; - script = '' - ${ip} netns add ${netnsName} - ${ipNetns} link set lo up - ${ip} link add ${veth} type veth peer name ${peer} - ${ip} link set ${veth} netns ${netnsName} - ${ipNetns} addr add ${v.address}/24 dev ${veth} - # The peer link is never used directly, so don't auto-assign an IPv6 address - echo 1 > /proc/sys/net/ipv6/conf/${peer}/disable_ipv6 - ${ip} link set ${peer} up - ${ipNetns} link set ${veth} up - ${ip} link set ${peer} master nb-br - ${ipNetns} route add default via ${bridgeIp} - ${netnsIptables} -w -P INPUT DROP - ${netnsIptables} -w -A INPUT -s 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT - # allow return traffic to outgoing connections initiated by the service itself - ${netnsIptables} -w -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT - '' + optionalString (config.services.${n}.enforceTor or false) '' - ${netnsIptables} -w -P OUTPUT DROP - ${netnsIptables} -w -A OUTPUT -d 127.0.0.1,${bridgeIp},${v.address} -j ACCEPT - '' + optionalString (v.availableNetns != []) '' - ${netnsIptables} -w -A INPUT -s ${allowedAddresses} -j ACCEPT - ${netnsIptables} -w -A OUTPUT -d ${allowedAddresses} -j ACCEPT - ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = script "setup" setup; + }; # Link deletion is implicit in netns deletion, but it sometimes only happens # after `netns delete` finishes. Add an extra `link del` to ensure that # the link is deleted before the service stops, which is needed for service @@ -197,10 +212,7 @@ in { ${ip} netns delete ${netnsName} ${ip} link del ${peer} 2> /dev/null || true ''; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; + }; }; in foldl (services: n: From 6ad7107ddbd26a45b3838c38301bc4bbad40e4e4 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Wed, 10 Nov 2021 21:25:10 +0100 Subject: [PATCH 5/7] update nixpkgs btcpayserver: 1.3.1 -> 1.3.3 clightning: 0.10.1 -> 0.10.2 --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index f6fb8e2..32d1069 100644 --- a/flake.lock +++ b/flake.lock @@ -17,11 +17,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1635719588, - "narHash": "sha256-pWjdy0NheM97NsPE6+jUnr5LYyeA0sBGTdw4mfXMGZQ=", + "lastModified": 1636333654, + "narHash": "sha256-3wh9PtCzcaJQuZrgZ+ygKfhltkDNNqT6zOzGsRbjZEo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f0869b1a2c0b150aac26e10bb5c2364ffb2e804f", + "rev": "e74894146a42ba552ebafa19ab2d1df7ccbc1738", "type": "github" }, "original": { @@ -33,11 +33,11 @@ }, "nixpkgsUnstable": { "locked": { - "lastModified": 1635781173, - "narHash": "sha256-nTA2y2jIJiVj5RawHUNhlZUIy5J/Q2CA6YP4T1qBkLo=", + "lastModified": 1636470166, + "narHash": "sha256-0tyWSS5rgMtML5p41ZdE5ocuAnRdtOGvdsqQyMUBYAI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7053541084bf5ce2921ef307e5585d39d7ba8b3f", + "rev": "f096b7122ab08e93c8b052c92461ca71b80c0cc8", "type": "github" }, "original": { From 38a843d005698152e0d9cf0753a82f84944c40fe Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Wed, 10 Nov 2021 21:25:11 +0100 Subject: [PATCH 6/7] clightning: update python pkgs to new version --- pkgs/python-packages/default.nix | 1 + pkgs/python-packages/pyln-bolt7/default.nix | 22 ++++++++++++++++++++ pkgs/python-packages/pyln-client/default.nix | 8 ++++--- pkgs/python-packages/pyln-proto/default.nix | 14 +++++++++++-- 4 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 pkgs/python-packages/pyln-bolt7/default.nix diff --git a/pkgs/python-packages/default.nix b/pkgs/python-packages/default.nix index ea6d36a..44d0001 100644 --- a/pkgs/python-packages/default.nix +++ b/pkgs/python-packages/default.nix @@ -19,6 +19,7 @@ in { pyln-client = clightningPkg ./pyln-client; pyln-proto = clightningPkg ./pyln-proto; + pyln-bolt7 = clightningPkg ./pyln-bolt7; pylightning = clightningPkg ./pylightning; ## Specific versions of packages that already exist in nixpkgs diff --git a/pkgs/python-packages/pyln-bolt7/default.nix b/pkgs/python-packages/pyln-bolt7/default.nix new file mode 100644 index 0000000..8433ba0 --- /dev/null +++ b/pkgs/python-packages/pyln-bolt7/default.nix @@ -0,0 +1,22 @@ +{ buildPythonPackage, clightning, pyln-proto }: + +buildPythonPackage rec { + pname = "pyln-bolt7"; + + # See fn `bolt_meta` in + # https://github.com/ElementsProject/lightning/blob/master/contrib/pyln-spec/bolt7/setup.py + version = "1.0.2.186"; + + inherit (clightning) src; + + propagatedBuildInputs = [ pyln-proto ]; + + postUnpack = "sourceRoot=$sourceRoot/contrib/pyln-spec/bolt7"; + + # TODO-EXTERNAL + # Remove when this fix is released + # https://github.com/ElementsProject/lightning/pull/4910 + postPatch = '' + sed -i 's|pyln.proto|pyln-proto|' requirements.txt + ''; +} diff --git a/pkgs/python-packages/pyln-client/default.nix b/pkgs/python-packages/pyln-client/default.nix index a570691..9ca49f8 100644 --- a/pkgs/python-packages/pyln-client/default.nix +++ b/pkgs/python-packages/pyln-client/default.nix @@ -1,12 +1,14 @@ -{ buildPythonPackage, clightning, recommonmark }: +{ buildPythonPackage, clightning, pyln-bolt7, recommonmark, setuptools-scm }: buildPythonPackage rec { pname = "pyln-client"; - version = "0.10.1"; # defined in ${src}/contrib/pyln-client/pyln/client/__init__.py + version = clightning.version; inherit (clightning) src; - propagatedBuildInputs = [ recommonmark ]; + propagatedBuildInputs = [ pyln-bolt7 recommonmark setuptools-scm ]; + + SETUPTOOLS_SCM_PRETEND_VERSION = version; postUnpack = "sourceRoot=$sourceRoot/contrib/${pname}"; } diff --git a/pkgs/python-packages/pyln-proto/default.nix b/pkgs/python-packages/pyln-proto/default.nix index 9a07143..c7b269a 100644 --- a/pkgs/python-packages/pyln-proto/default.nix +++ b/pkgs/python-packages/pyln-proto/default.nix @@ -4,11 +4,12 @@ , coincurve , base58 , mypy +, setuptools-scm }: buildPythonPackage rec { pname = "pyln-proto"; - version = "0.10.1"; # defined in ${src}/contrib/pyln-proto/setup.py + version = clightning.version; inherit (clightning) src; @@ -18,8 +19,17 @@ buildPythonPackage rec { coincurve base58 mypy + setuptools-scm ]; - postUnpack = "sourceRoot=$sourceRoot/contrib/${pname}"; + SETUPTOOLS_SCM_PRETEND_VERSION = version; + postUnpack = "sourceRoot=$sourceRoot/contrib/pyln-proto"; + postPatch = '' + sed -i ' + s|coincurve ~= 13.0|coincurve == 15.0.0| + s|base58 ~= 2.0.1|base58 == 2.1.0| + s|mypy==0.790|mypy == 0.812| + ' requirements.txt + ''; } From 4a74b7de084f46655b1f11f738d9e1763ccefcc7 Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Wed, 10 Nov 2021 21:25:12 +0100 Subject: [PATCH 7/7] clightning: work around unsupported seccomp syscall --- modules/clightning.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/clightning.nix b/modules/clightning.nix index c380e2c..44809e4 100644 --- a/modules/clightning.nix +++ b/modules/clightning.nix @@ -137,6 +137,14 @@ in { Restart = "on-failure"; RestartSec = "10s"; ReadWritePaths = cfg.dataDir; + + # TODO-EXTERNAL: + # The seccomp version used by systemd in NixOS 21.05 doesn't support + # handling syscall 436 (close_range), which has only recently been added: + # https://github.com/seccomp/libseccomp/commit/ac849e7960547d418009a783da654d5917dbfe2d + # + # Disable seccomp filtering because clightning depends on this syscall. + SystemCallFilter = []; } // nbLib.allowedIPAddresses cfg.enforceTor; # Wait until the rpc socket appears postStart = ''