Loading nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ ./services/backup/znapzend.nix ./services/blockchain/ethereum/geth.nix ./services/blockchain/ethereum/erigon.nix ./services/blockchain/ethereum/lighthouse.nix ./services/backup/zrepl.nix ./services/cluster/corosync/default.nix ./services/cluster/hadoop/default.nix Loading nixos/modules/services/blockchain/ethereum/erigon.nix +24 −2 Original line number Diff line number Diff line Loading @@ -13,6 +13,15 @@ in { services.erigon = { enable = mkEnableOption (lib.mdDoc "Ethereum implementation on the efficiency frontier"); group = mkOption { type = types.str; default = "ethereum"; description = lib.mdDoc '' Group of the user running the lighthouse process. This is used to share the jwt secret with the execution layer. ''; }; settings = mkOption { description = lib.mdDoc '' Configuration for Erigon Loading Loading @@ -55,6 +64,19 @@ in { }; config = mkIf cfg.enable { users = { users.erigon = { name = "erigon"; group = cfg.group; description = "Erigon user"; home = "/var/lib/erigon"; isSystemUser = true; }; groups = mkIf (cfg.group == "ethereum") { ethereum = {}; }; }; # Default values are the same as in the binary, they are just written here for convenience. services.erigon.settings = { datadir = mkDefault "/var/lib/erigon"; Loading @@ -77,10 +99,11 @@ in { serviceConfig = { ExecStart = "${pkgs.erigon}/bin/erigon --config ${configFile}"; User = "erigon"; Group = cfg.group; Restart = "on-failure"; StateDirectory = "erigon"; CapabilityBoundingSet = ""; DynamicUser = true; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; Loading @@ -97,7 +120,6 @@ in { RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; Loading nixos/modules/services/blockchain/ethereum/lighthouse.nix 0 → 100644 +333 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: with lib; let cfg = config.services.lighthouse; in { options = { services.lighthouse = { beacon = mkOption { description = lib.mdDoc "Beacon node"; type = types.submodule { options = { enable = lib.mkEnableOption (lib.mdDoc "Lightouse Beacon node"); dataDir = mkOption { type = types.str; default = "/var/lib/lighthouse-beacon"; description = lib.mdDoc '' Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. ''; }; address = mkOption { type = types.str; default = "0.0.0.0"; description = lib.mdDoc '' Listen address of Beacon node. ''; }; port = mkOption { type = types.port; default = 9000; description = lib.mdDoc '' Port number the Beacon node will be listening on. ''; }; openFirewall = mkOption { type = types.bool; default = false; description = lib.mdDoc '' Open the port in the firewall ''; }; disableDepositContractSync = mkOption { type = types.bool; default = false; description = lib.mdDoc '' Explictly disables syncing of deposit logs from the execution node. This overrides any previous option that depends on it. Useful if you intend to run a non-validating beacon node. ''; }; group = mkOption { type = types.str; default = "ethereum"; description = lib.mdDoc '' Group of the user running the lighthouse process. This is used to share the jwt secret with the execution layer. ''; }; execution = { address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address for the execution layer. ''; }; port = mkOption { type = types.port; default = 8551; description = lib.mdDoc '' Port number the Beacon node will be listening on for the execution layer. ''; }; jwtPath = mkOption { type = types.str; default = ""; description = lib.mdDoc '' Path for the jwt secret required to connect to the execution layer. ''; }; }; http = { enable = lib.mkEnableOption (lib.mdDoc "Beacon node http api"); port = mkOption { type = types.port; default = 5052; description = lib.mdDoc '' Port number of Beacon node RPC service. ''; }; address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Beacon node RPC service. ''; }; }; metrics = { enable = lib.mkEnableOption (lib.mdDoc "Beacon node prometheus metrics"); address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Beacon node metrics service. ''; }; port = mkOption { type = types.port; default = 5054; description = lib.mdDoc '' Port number of Beacon node metrics service. ''; }; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to the lighthouse beacon command. ''; default = ""; example = ""; }; }; }; }; validator = mkOption { description = lib.mdDoc "Validator node"; type = types.submodule { options = { enable = mkOption { type = types.bool; default = false; description = lib.mdDoc "Enable Lightouse Validator node."; }; dataDir = mkOption { type = types.str; default = "/var/lib/lighthouse-validator"; description = lib.mdDoc '' Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. ''; }; beaconNodes = mkOption { type = types.listOf types.str; default = ["http://localhost:5052"]; description = lib.mdDoc '' Beacon nodes to connect to. ''; }; metrics = { enable = lib.mkEnableOption (lib.mdDoc "Validator node prometheus metrics"); address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Validator node metrics service. ''; }; port = mkOption { type = types.port; default = 5056; description = lib.mdDoc '' Port number of Validator node metrics service. ''; }; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to the lighthouse validator command. ''; default = ""; example = ""; }; }; }; }; network = mkOption { type = types.enum [ "mainnet" "prater" "goerli" "gnosis" "kiln" "ropsten" "sepolia" ]; default = "mainnet"; description = lib.mdDoc '' The network to connect to. Mainnet is the default ethereum network. ''; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to every lighthouse command. ''; default = ""; example = ""; }; }; }; config = mkIf (cfg.beacon.enable || cfg.validator.enable) { users = { users.lighthouse-beacon = { name = "lighthouse-beacon"; group = cfg.beacon.group; description = "Lighthouse beacon node user"; home = "${cfg.beacon.dataDir}"; isSystemUser = true; }; groups = mkIf (cfg.beacon.group == "ethereum") { ethereum = {}; }; }; environment.systemPackages = [ pkgs.lighthouse ] ; networking.firewall = mkIf cfg.beacon.enable { allowedTCPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; allowedUDPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; }; systemd.services.lighthouse-beacon = mkIf cfg.beacon.enable { description = "Lighthouse beacon node (connect to P2P nodes and verify blocks)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' # make sure the chain data directory is created on first run mkdir -p ${cfg.beacon.dataDir}/${cfg.network} ${pkgs.lighthouse}/bin/lighthouse beacon_node \ --disable-upnp \ ${lib.optionalString cfg.beacon.disableDepositContractSync "--disable-deposit-contract-sync"} \ --port ${toString cfg.beacon.port} \ --listen-address ${cfg.beacon.address} \ --network ${cfg.network} \ --datadir ${cfg.beacon.dataDir}/${cfg.network} \ --execution-endpoint http://${cfg.beacon.execution.address}:${toString cfg.beacon.execution.port} \ --execution-jwt ${cfg.beacon.execution.jwtPath} \ ${lib.optionalString cfg.beacon.http.enable '' --http --http-address ${cfg.beacon.http.address} --http-port ${toString cfg.beacon.http.port}''} \ ${lib.optionalString cfg.beacon.metrics.enable '' --metrics --metrics-address ${cfg.beacon.metrics.address} --metrics-port ${toString cfg.beacon.metrics.port}''} \ ${cfg.extraArgs} ${cfg.beacon.extraArgs} ''; serviceConfig = { User = "lighthouse-beacon"; Group = cfg.beacon.group; Restart = "on-failure"; StateDirectory = "lighthouse-beacon"; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; ProtectClock = true; ProtectProc = "noaccess"; ProcSubset = "pid"; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectControlGroups = true; ProtectHostname = true; RestrictSUIDSGID = true; RestrictRealtime = true; RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; systemd.services.lighthouse-validator = mkIf cfg.validator.enable { description = "Lighthouse validtor node (manages validators, using data obtained from the beacon node via a HTTP API)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' # make sure the chain data directory is created on first run mkdir -p ${cfg.validator.dataDir}/${cfg.network} ${pkgs.lighthouse}/bin/lighthouse validator_client \ --network ${cfg.network} \ --beacon-nodes ${lib.concatStringsSep "," cfg.validator.beaconNodes} \ --datadir ${cfg.validator.dataDir}/${cfg.network} ${optionalString cfg.validator.metrics.enable ''--metrics --metrics-address ${cfg.validator.metrics.address} --metrics-port ${toString cfg.validator.metrics.port}''} \ ${cfg.extraArgs} ${cfg.validator.extraArgs} ''; serviceConfig = { Restart = "on-failure"; StateDirectory = "lighthouse-validator"; CapabilityBoundingSet = ""; DynamicUser = true; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; ProtectClock = true; ProtectProc = "noaccess"; ProcSubset = "pid"; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectControlGroups = true; ProtectHostname = true; RestrictSUIDSGID = true; RestrictRealtime = true; RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; }; } Loading
nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ ./services/backup/znapzend.nix ./services/blockchain/ethereum/geth.nix ./services/blockchain/ethereum/erigon.nix ./services/blockchain/ethereum/lighthouse.nix ./services/backup/zrepl.nix ./services/cluster/corosync/default.nix ./services/cluster/hadoop/default.nix Loading
nixos/modules/services/blockchain/ethereum/erigon.nix +24 −2 Original line number Diff line number Diff line Loading @@ -13,6 +13,15 @@ in { services.erigon = { enable = mkEnableOption (lib.mdDoc "Ethereum implementation on the efficiency frontier"); group = mkOption { type = types.str; default = "ethereum"; description = lib.mdDoc '' Group of the user running the lighthouse process. This is used to share the jwt secret with the execution layer. ''; }; settings = mkOption { description = lib.mdDoc '' Configuration for Erigon Loading Loading @@ -55,6 +64,19 @@ in { }; config = mkIf cfg.enable { users = { users.erigon = { name = "erigon"; group = cfg.group; description = "Erigon user"; home = "/var/lib/erigon"; isSystemUser = true; }; groups = mkIf (cfg.group == "ethereum") { ethereum = {}; }; }; # Default values are the same as in the binary, they are just written here for convenience. services.erigon.settings = { datadir = mkDefault "/var/lib/erigon"; Loading @@ -77,10 +99,11 @@ in { serviceConfig = { ExecStart = "${pkgs.erigon}/bin/erigon --config ${configFile}"; User = "erigon"; Group = cfg.group; Restart = "on-failure"; StateDirectory = "erigon"; CapabilityBoundingSet = ""; DynamicUser = true; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; Loading @@ -97,7 +120,6 @@ in { RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; Loading
nixos/modules/services/blockchain/ethereum/lighthouse.nix 0 → 100644 +333 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: with lib; let cfg = config.services.lighthouse; in { options = { services.lighthouse = { beacon = mkOption { description = lib.mdDoc "Beacon node"; type = types.submodule { options = { enable = lib.mkEnableOption (lib.mdDoc "Lightouse Beacon node"); dataDir = mkOption { type = types.str; default = "/var/lib/lighthouse-beacon"; description = lib.mdDoc '' Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. ''; }; address = mkOption { type = types.str; default = "0.0.0.0"; description = lib.mdDoc '' Listen address of Beacon node. ''; }; port = mkOption { type = types.port; default = 9000; description = lib.mdDoc '' Port number the Beacon node will be listening on. ''; }; openFirewall = mkOption { type = types.bool; default = false; description = lib.mdDoc '' Open the port in the firewall ''; }; disableDepositContractSync = mkOption { type = types.bool; default = false; description = lib.mdDoc '' Explictly disables syncing of deposit logs from the execution node. This overrides any previous option that depends on it. Useful if you intend to run a non-validating beacon node. ''; }; group = mkOption { type = types.str; default = "ethereum"; description = lib.mdDoc '' Group of the user running the lighthouse process. This is used to share the jwt secret with the execution layer. ''; }; execution = { address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address for the execution layer. ''; }; port = mkOption { type = types.port; default = 8551; description = lib.mdDoc '' Port number the Beacon node will be listening on for the execution layer. ''; }; jwtPath = mkOption { type = types.str; default = ""; description = lib.mdDoc '' Path for the jwt secret required to connect to the execution layer. ''; }; }; http = { enable = lib.mkEnableOption (lib.mdDoc "Beacon node http api"); port = mkOption { type = types.port; default = 5052; description = lib.mdDoc '' Port number of Beacon node RPC service. ''; }; address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Beacon node RPC service. ''; }; }; metrics = { enable = lib.mkEnableOption (lib.mdDoc "Beacon node prometheus metrics"); address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Beacon node metrics service. ''; }; port = mkOption { type = types.port; default = 5054; description = lib.mdDoc '' Port number of Beacon node metrics service. ''; }; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to the lighthouse beacon command. ''; default = ""; example = ""; }; }; }; }; validator = mkOption { description = lib.mdDoc "Validator node"; type = types.submodule { options = { enable = mkOption { type = types.bool; default = false; description = lib.mdDoc "Enable Lightouse Validator node."; }; dataDir = mkOption { type = types.str; default = "/var/lib/lighthouse-validator"; description = lib.mdDoc '' Directory where data will be stored. Each chain will be stored under it's own specific subdirectory. ''; }; beaconNodes = mkOption { type = types.listOf types.str; default = ["http://localhost:5052"]; description = lib.mdDoc '' Beacon nodes to connect to. ''; }; metrics = { enable = lib.mkEnableOption (lib.mdDoc "Validator node prometheus metrics"); address = mkOption { type = types.str; default = "127.0.0.1"; description = lib.mdDoc '' Listen address of Validator node metrics service. ''; }; port = mkOption { type = types.port; default = 5056; description = lib.mdDoc '' Port number of Validator node metrics service. ''; }; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to the lighthouse validator command. ''; default = ""; example = ""; }; }; }; }; network = mkOption { type = types.enum [ "mainnet" "prater" "goerli" "gnosis" "kiln" "ropsten" "sepolia" ]; default = "mainnet"; description = lib.mdDoc '' The network to connect to. Mainnet is the default ethereum network. ''; }; extraArgs = mkOption { type = types.str; description = lib.mdDoc '' Additional arguments passed to every lighthouse command. ''; default = ""; example = ""; }; }; }; config = mkIf (cfg.beacon.enable || cfg.validator.enable) { users = { users.lighthouse-beacon = { name = "lighthouse-beacon"; group = cfg.beacon.group; description = "Lighthouse beacon node user"; home = "${cfg.beacon.dataDir}"; isSystemUser = true; }; groups = mkIf (cfg.beacon.group == "ethereum") { ethereum = {}; }; }; environment.systemPackages = [ pkgs.lighthouse ] ; networking.firewall = mkIf cfg.beacon.enable { allowedTCPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; allowedUDPPorts = mkIf cfg.beacon.openFirewall [ cfg.beacon.port ]; }; systemd.services.lighthouse-beacon = mkIf cfg.beacon.enable { description = "Lighthouse beacon node (connect to P2P nodes and verify blocks)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' # make sure the chain data directory is created on first run mkdir -p ${cfg.beacon.dataDir}/${cfg.network} ${pkgs.lighthouse}/bin/lighthouse beacon_node \ --disable-upnp \ ${lib.optionalString cfg.beacon.disableDepositContractSync "--disable-deposit-contract-sync"} \ --port ${toString cfg.beacon.port} \ --listen-address ${cfg.beacon.address} \ --network ${cfg.network} \ --datadir ${cfg.beacon.dataDir}/${cfg.network} \ --execution-endpoint http://${cfg.beacon.execution.address}:${toString cfg.beacon.execution.port} \ --execution-jwt ${cfg.beacon.execution.jwtPath} \ ${lib.optionalString cfg.beacon.http.enable '' --http --http-address ${cfg.beacon.http.address} --http-port ${toString cfg.beacon.http.port}''} \ ${lib.optionalString cfg.beacon.metrics.enable '' --metrics --metrics-address ${cfg.beacon.metrics.address} --metrics-port ${toString cfg.beacon.metrics.port}''} \ ${cfg.extraArgs} ${cfg.beacon.extraArgs} ''; serviceConfig = { User = "lighthouse-beacon"; Group = cfg.beacon.group; Restart = "on-failure"; StateDirectory = "lighthouse-beacon"; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; ProtectClock = true; ProtectProc = "noaccess"; ProcSubset = "pid"; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectControlGroups = true; ProtectHostname = true; RestrictSUIDSGID = true; RestrictRealtime = true; RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; systemd.services.lighthouse-validator = mkIf cfg.validator.enable { description = "Lighthouse validtor node (manages validators, using data obtained from the beacon node via a HTTP API)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' # make sure the chain data directory is created on first run mkdir -p ${cfg.validator.dataDir}/${cfg.network} ${pkgs.lighthouse}/bin/lighthouse validator_client \ --network ${cfg.network} \ --beacon-nodes ${lib.concatStringsSep "," cfg.validator.beaconNodes} \ --datadir ${cfg.validator.dataDir}/${cfg.network} ${optionalString cfg.validator.metrics.enable ''--metrics --metrics-address ${cfg.validator.metrics.address} --metrics-port ${toString cfg.validator.metrics.port}''} \ ${cfg.extraArgs} ${cfg.validator.extraArgs} ''; serviceConfig = { Restart = "on-failure"; StateDirectory = "lighthouse-validator"; CapabilityBoundingSet = ""; DynamicUser = true; NoNewPrivileges = true; PrivateTmp = true; ProtectHome = true; ProtectClock = true; ProtectProc = "noaccess"; ProcSubset = "pid"; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectControlGroups = true; ProtectHostname = true; RestrictSUIDSGID = true; RestrictRealtime = true; RestrictNamespaces = true; LockPersonality = true; RemoveIPC = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; SystemCallFilter = [ "@system-service" "~@privileged" ]; }; }; }; }