From 752e1ef54a784d09bd8434c9e16e11921ec01181 Mon Sep 17 00:00:00 2001 From: Sergey Gulin Date: Tue, 5 Mar 2024 15:53:15 +0300 Subject: [PATCH] [OPS-1161] Harden systemd services Problem: We want to harden the security of our systemd services. Solution: Use the hardening profile defined in serokell.nix. --- flake.nix | 8 ++++---- nix/modules/common.nix | 20 +++++++++----------- nix/modules/tezos-accuser.nix | 3 ++- nix/modules/tezos-baker.nix | 6 +++++- nix/modules/tezos-node.nix | 12 ++++++++++-- nix/modules/tezos-signer.nix | 5 +++-- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/flake.nix b/flake.nix index 71c900e8a..9cdb2c548 100644 --- a/flake.nix +++ b/flake.nix @@ -43,10 +43,10 @@ in pkgs-darwin.lib.recursiveUpdate { nixosModules = { - tezos-node = import ./nix/modules/tezos-node.nix; - tezos-accuser = import ./nix/modules/tezos-accuser.nix; - tezos-baker = import ./nix/modules/tezos-baker.nix; - tezos-signer = import ./nix/modules/tezos-signer.nix; + tezos-node = import ./nix/modules/tezos-node.nix { inherit inputs; }; + tezos-accuser = import ./nix/modules/tezos-accuser.nix { inherit inputs; }; + tezos-baker = import ./nix/modules/tezos-baker.nix { inherit inputs; }; + tezos-signer = import ./nix/modules/tezos-signer.nix { inherit inputs; }; }; devShells."aarch64-darwin".autorelease-macos = diff --git a/nix/modules/common.nix b/nix/modules/common.nix index 20bb38529..357ef91a8 100644 --- a/nix/modules/common.nix +++ b/nix/modules/common.nix @@ -1,10 +1,12 @@ # SPDX-FileCopyrightText: 2021 Oxhead Alpha # SPDX-License-Identifier: LicenseRef-MIT-OA -{ lib, pkgs, ... }: +{ lib, pkgs, inputs, ... }: with lib; -rec { +let + inherit (inputs.serokell-nix.lib.systemd) hardeningProfiles withHardeningProfile; +in rec { sharedOptions = { logVerbosity = mkOption { @@ -46,14 +48,14 @@ rec { }; }; - genDaemonConfig = { instancesCfg, service-name, service-pkgs, service-start-script, service-prestart-script ? (_: "")}: + genDaemonConfig = { instancesCfg, service-name, service-pkgs, service-start-script, service-prestart-script ? (_: ""), extraServiceConfig ? {}}: mkIf (instancesCfg != {}) { users = mkMerge (flip mapAttrsToList instancesCfg (node-name: node-cfg: genUsers node-name )); systemd = mkMerge (flip mapAttrsToList instancesCfg (node-name: node-cfg: let octez-client = "${pkgs.octezPackages.octez-client}/bin/octez-client"; passwordFilenameArg = if node-cfg.passwordFilename != null then "-f ${node-cfg.passwordFilename}" else ""; in { - services."tezos-${node-name}-octez-${service-name}" = lib.recursiveUpdate (genSystemdService node-name node-cfg service-name) rec { + services."tezos-${node-name}-octez-${service-name}" = lib.recursiveUpdate (genSystemdService node-name node-cfg service-name (extraServiceConfig // {Type = "forking";})) rec { bindsTo = [ "network.target" "tezos-${node-name}-octez-node.service" ]; after = bindsTo; path = with pkgs; [ curl ]; @@ -77,9 +79,6 @@ rec { fi '' + service-prestart-script node-cfg; script = service-start-script node-cfg; - serviceConfig = { - Type = "forking"; - }; }; })); }; @@ -89,20 +88,19 @@ rec { users."tezos-${node-name}" = { group = "tezos-${node-name}"; isNormalUser = true; }; }; - genSystemdService = node-name: node-cfg: service-name: { + genSystemdService = node-name: node-cfg: service-name: extraServiceConfig: { inherit (node-cfg) enable; wantedBy = [ "multi-user.target" ]; description = "Octez ${service-name}"; environment = { OCTEZ_LOG = "* -> ${node-cfg.logVerbosity}"; }; - serviceConfig = { + serviceConfig = withHardeningProfile hardeningProfiles.backend ({ User = "tezos-${node-name}"; Group = "tezos-${node-name}"; StateDirectory = "tezos-${node-name}"; Restart = "always"; RestartSec = "10"; - }; + } // extraServiceConfig); }; - } diff --git a/nix/modules/tezos-accuser.nix b/nix/modules/tezos-accuser.nix index e40f1817e..db3ce9320 100644 --- a/nix/modules/tezos-accuser.nix +++ b/nix/modules/tezos-accuser.nix @@ -1,6 +1,7 @@ # SPDX-FileCopyrightText: 2021 Oxhead Alpha # SPDX-License-Identifier: LicenseRef-MIT-OA +{inputs}: {config, lib, pkgs, ...}: with lib; @@ -13,7 +14,7 @@ let "${pkgs.octezPackages.octez-accuser-Proxford}/bin/octez-accuser-Proxford"; }; cfg = config.services.octez-accuser; - common = import ./common.nix { inherit lib; inherit pkgs; }; + common = import ./common.nix { inherit lib pkgs inputs; }; instanceOptions = types.submodule ( {...} : { options = common.daemonOptions // { diff --git a/nix/modules/tezos-baker.nix b/nix/modules/tezos-baker.nix index db51a5e1a..9d952d2d1 100644 --- a/nix/modules/tezos-baker.nix +++ b/nix/modules/tezos-baker.nix @@ -1,6 +1,7 @@ # SPDX-FileCopyrightText: 2021 Oxhead Alpha # SPDX-License-Identifier: LicenseRef-MIT-OA +{inputs}: {config, lib, pkgs, ...}: with lib; @@ -14,7 +15,7 @@ let }; octez-client = "${pkgs.octezPackages.octez-client}/bin/octez-client"; cfg = config.services.octez-baker; - common = import ./common.nix { inherit lib; inherit pkgs; }; + common = import ./common.nix { inherit lib pkgs inputs; }; instanceOptions = types.submodule ( {...} : { options = common.daemonOptions // { @@ -76,5 +77,8 @@ in { service-pkgs = octez-baker-pkgs; service-start-script = baker-start-script; service-prestart-script = baker-prestart-script; + extraServiceConfig = { + PrivateDevices = "no"; + }; }; } diff --git a/nix/modules/tezos-node.nix b/nix/modules/tezos-node.nix index 2cf91ce6e..718f34526 100644 --- a/nix/modules/tezos-node.nix +++ b/nix/modules/tezos-node.nix @@ -1,6 +1,7 @@ # SPDX-FileCopyrightText: 2021 Oxhead Alpha # SPDX-License-Identifier: LicenseRef-MIT-OA +{inputs}: { config, lib, pkgs, ... }: with lib; @@ -15,7 +16,14 @@ let --net-addr ":${toString netPort}" \ --network "${network}" ${builtins.concatStringsSep " " options} ''; - common = import ./common.nix { inherit lib; inherit pkgs; }; + common = import ./common.nix { inherit lib pkgs inputs; }; + extraServiceConfig = { + RestrictAddressFamilies = [ + "AF_INET" + "AF_UNIX" + "AF_INET6" + ]; + }; instanceOptions = types.submodule ( {...} : { options = common.sharedOptions // { enable = mkEnableOption "Octez node service"; @@ -92,7 +100,7 @@ in { config = mkIf (cfg.instances != {}) { users = mkMerge (flip mapAttrsToList cfg.instances (node-name: node-cfg: common.genUsers node-name )); systemd = mkMerge (flip mapAttrsToList cfg.instances (node-name: node-cfg: { - services."tezos-${node-name}-octez-node" = common.genSystemdService node-name node-cfg "node" // { + services."tezos-${node-name}-octez-node" = common.genSystemdService node-name node-cfg "node" extraServiceConfig // { after = [ "network.target" ]; preStart = '' diff --git a/nix/modules/tezos-signer.nix b/nix/modules/tezos-signer.nix index 956d39c4b..203ed1738 100644 --- a/nix/modules/tezos-signer.nix +++ b/nix/modules/tezos-signer.nix @@ -2,13 +2,14 @@ # # SPDX-License-Identifier: LicenseRef-MIT-TQ +{inputs}: {config, lib, pkgs, ...}: with lib; let octez-signer-launch = "${pkgs.octezPackages.octez-signer}/bin/octez-signer launch"; - common = import ./common.nix { inherit lib; inherit pkgs; }; + common = import ./common.nix { inherit lib pkgs inputs; }; cfg = config.services.octez-signer; instanceOptions = types.submodule ( {...} : { options = common.sharedOptions // { @@ -98,7 +99,7 @@ in { "${octez-signer-launch} local signer --socket ${node-cfg.unixSocket}"; }; in { - services."tezos-${node-name}-octez-signer" = common.genSystemdService node-name node-cfg "signer" // { + services."tezos-${node-name}-octez-signer" = common.genSystemdService node-name node-cfg "signer" {} // { after = [ "network.target" ]; script = '' ${octez-signers.${node-cfg.networkProtocol}}