about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
author0x4A6F <0x4A6F@users.noreply.github.com>2022-02-25 17:03:09 +0100
committerGitHub <noreply@github.com>2022-02-25 17:03:09 +0100
commit7ad39a412588dad2c64ee2abd5de51fad7c9cccc (patch)
treefc3b58e6d2627e7563e0336d27368ac78ea6a1bd /nixos
parent2b9029fc3fe344a06928353c56639f184e426666 (diff)
parentad161944605a00dbf036dee4eea10eab8a286121 (diff)
downloadnixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar.gz
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar.bz2
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar.lz
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar.xz
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.tar.zst
nixlib-7ad39a412588dad2c64ee2abd5de51fad7c9cccc.zip
Merge pull request #161193 from Mic92/bird1
bird: drop bird1 package & modules; hardening
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2205.section.xml8
-rw-r--r--nixos/doc/manual/release-notes/rl-2205.section.md2
-rw-r--r--nixos/modules/services/networking/bird.nix188
-rw-r--r--nixos/tests/bird.nix131
4 files changed, 133 insertions, 196 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index d59af54aa2fa..56f9f60f3ebe 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -548,6 +548,14 @@
       </listitem>
       <listitem>
         <para>
+          <literal>bird1</literal> and its modules
+          <literal>services.bird</literal> as well as
+          <literal>services.bird6</literal> have been removed. Upgrade
+          to <literal>services.bird2</literal>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           The options
           <literal>networking.interfaces.&lt;name&gt;.ipv4.routes</literal>
           and
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index 201969badc95..2994facffc97 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -178,6 +178,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 
 - `tilp2` was removed together with its module
 
+- `bird1` and its modules `services.bird` as well as `services.bird6` have been removed. Upgrade to `services.bird2`.
+
 - The options `networking.interfaces.<name>.ipv4.routes` and `networking.interfaces.<name>.ipv6.routes` are no longer ignored when using networkd instead of the default scripted network backend by setting `networking.useNetworkd` to `true`.
 
 - MultiMC has been replaced with the fork PolyMC due to upstream developers being hostile to 3rd party package maintainers. PolyMC removes all MultiMC branding and is aimed at providing proper 3rd party packages like the one contained in Nixpkgs. This change affects the data folder where game instances and other save and configuration files are stored. Users with existing installations should rename `~/.local/share/multimc` to `~/.local/share/polymc`. The main config file's path has also moved from `~/.local/share/multimc/multimc.cfg` to `~/.local/share/polymc/polymc.cfg`.
diff --git a/nixos/modules/services/networking/bird.nix b/nixos/modules/services/networking/bird.nix
index fc06cdaa6e58..4a5192424819 100644
--- a/nixos/modules/services/networking/bird.nix
+++ b/nixos/modules/services/networking/bird.nix
@@ -3,103 +3,107 @@
 let
   inherit (lib) mkEnableOption mkIf mkOption optionalString types;
 
-  generic = variant:
-    let
-      cfg = config.services.${variant};
-      pkg = pkgs.${variant};
-      birdBin = if variant == "bird6" then "bird6" else "bird";
-      birdc = if variant == "bird6" then "birdc6" else "birdc";
-      descr =
-        { bird = "1.6.x with IPv4 support";
-          bird6 = "1.6.x with IPv6 support";
-          bird2 = "2.x";
-        }.${variant};
-    in {
-      ###### interface
-      options = {
-        services.${variant} = {
-          enable = mkEnableOption "BIRD Internet Routing Daemon (${descr})";
-          config = mkOption {
-            type = types.lines;
-            description = ''
-              BIRD Internet Routing Daemon configuration file.
-              <link xlink:href='http://bird.network.cz/'/>
-            '';
-          };
-          checkConfig = mkOption {
-            type = types.bool;
-            default = true;
-            description = ''
-              Whether the config should be checked at build time.
-              When the config can't be checked during build time, for example when it includes
-              other files, either disable this option or use <code>preCheckConfig</code> to create
-              the included files before checking.
-            '';
-          };
-          preCheckConfig = mkOption {
-            type = types.lines;
-            default = "";
-            example = ''
-              echo "cost 100;" > include.conf
-            '';
-            description = ''
-              Commands to execute before the config file check. The file to be checked will be
-              available as <code>${variant}.conf</code> in the current directory.
+  cfg = config.services.bird2;
+in
+{
+  ###### interface
+  options = {
+    services.bird2 = {
+      enable = mkEnableOption "BIRD Internet Routing Daemon";
+      config = mkOption {
+        type = types.lines;
+        description = ''
+          BIRD Internet Routing Daemon configuration file.
+          <link xlink:href='http://bird.network.cz/'/>
+        '';
+      };
+      checkConfig = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether the config should be checked at build time.
+          When the config can't be checked during build time, for example when it includes
+          other files, either disable this option or use <code>preCheckConfig</code> to create
+          the included files before checking.
+        '';
+      };
+      preCheckConfig = mkOption {
+        type = types.lines;
+        default = "";
+        example = ''
+          echo "cost 100;" > include.conf
+        '';
+        description = ''
+          Commands to execute before the config file check. The file to be checked will be
+          available as <code>bird2.conf</code> in the current directory.
 
-              Files created with this option will not be available at service runtime, only during
-              build time checking.
-            '';
-          };
-        };
+          Files created with this option will not be available at service runtime, only during
+          build time checking.
+        '';
       };
+    };
+  };
 
-      ###### implementation
-      config = mkIf cfg.enable {
-        environment.systemPackages = [ pkg ];
 
-        environment.etc."bird/${variant}.conf".source = pkgs.writeTextFile {
-          name = "${variant}.conf";
-          text = cfg.config;
-          checkPhase = optionalString cfg.checkConfig ''
-            ln -s $out ${variant}.conf
-            ${cfg.preCheckConfig}
-            ${pkg}/bin/${birdBin} -d -p -c ${variant}.conf
-          '';
-        };
+  imports = [
+    (lib.mkRemovedOptionModule [ "services" "bird" ] "Use services.bird2 instead")
+    (lib.mkRemovedOptionModule [ "services" "bird6" ] "Use services.bird2 instead")
+  ];
 
-        systemd.services.${variant} = {
-          description = "BIRD Internet Routing Daemon (${descr})";
-          wantedBy = [ "multi-user.target" ];
-          reloadIfChanged = true;
-          restartTriggers = [ config.environment.etc."bird/${variant}.conf".source ];
-          serviceConfig = {
-            Type = "forking";
-            Restart = "on-failure";
-            ExecStart = "${pkg}/bin/${birdBin} -c /etc/bird/${variant}.conf -u ${variant} -g ${variant}";
-            ExecReload = "/bin/sh -c '${pkg}/bin/${birdBin} -c /etc/bird/${variant}.conf -p && ${pkg}/bin/${birdc} configure'";
-            ExecStop = "${pkg}/bin/${birdc} down";
-            CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
-                                      # see bird/sysdep/linux/syspriv.h
-                                      "CAP_NET_BIND_SERVICE" "CAP_NET_BROADCAST" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
-            ProtectSystem = "full";
-            ProtectHome = "yes";
-            SystemCallFilter="~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
-            MemoryDenyWriteExecute = "yes";
-          };
-        };
-        users = {
-          users.${variant} = {
-            description = "BIRD Internet Routing Daemon user";
-            group = variant;
-            isSystemUser = true;
-          };
-          groups.${variant} = {};
-        };
-      };
-    };
+  ###### implementation
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.bird ];
 
-in
+    environment.etc."bird/bird2.conf".source = pkgs.writeTextFile {
+      name = "bird2";
+      text = cfg.config;
+      checkPhase = optionalString cfg.checkConfig ''
+        ln -s $out bird2.conf
+        ${cfg.preCheckConfig}
+        ${pkgs.bird}/bin/bird -d -p -c bird2.conf
+      '';
+    };
 
-{
-  imports = map generic [ "bird" "bird6" "bird2" ];
+    systemd.services.bird2 = {
+      description = "BIRD Internet Routing Daemon";
+      wantedBy = [ "multi-user.target" ];
+      reloadIfChanged = true;
+      restartTriggers = [ config.environment.etc."bird/bird2.conf".source ];
+      serviceConfig = {
+        Type = "forking";
+        Restart = "on-failure";
+        # We need to start as root so bird can open netlink sockets i.e. for ospf
+        ExecStart = "${pkgs.bird}/bin/bird -c /etc/bird/bird2.conf -u bird2 -g bird2";
+        ExecReload = "/bin/sh -c '${pkgs.bird}/bin/bird -c /etc/bird/bird2.conf -p && ${pkgs.bird}/bin/birdc configure'";
+        ExecStop = "${pkgs.bird}/bin/birdc down";
+        RuntimeDirectory = "bird";
+        CapabilityBoundingSet = [
+          "CAP_CHOWN"
+          "CAP_FOWNER"
+          "CAP_SETUID"
+          "CAP_SETGID"
+          "CAP_NET_ADMIN"
+          "CAP_NET_BROADCAST"
+          "CAP_NET_BIND_SERVICE"
+          "CAP_NET_RAW"
+        ];
+        ProtectSystem = "full";
+        ProtectHome = "yes";
+        ProtectKernelTunables = true;
+        ProtectControlGroups = true;
+        PrivateTmp = true;
+        PrivateDevices = true;
+        SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
+        MemoryDenyWriteExecute = "yes";
+      };
+    };
+    users = {
+      users.bird2 = {
+        description = "BIRD Internet Routing Daemon user";
+        group = "bird2";
+        isSystemUser = true;
+      };
+      groups.bird2 = { };
+    };
+  };
 }
diff --git a/nixos/tests/bird.nix b/nixos/tests/bird.nix
index 50d397be14ee..befcf4fb8acf 100644
--- a/nixos/tests/bird.nix
+++ b/nixos/tests/bird.nix
@@ -9,7 +9,7 @@ let
   inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
   inherit (pkgs.lib) optionalString;
 
-  hostShared = hostId: { pkgs, ... }: {
+  makeBird2Host = hostId: { pkgs, ... }: {
     virtualisation.vlans = [ 1 ];
 
     environment.systemPackages = with pkgs; [ jq ];
@@ -24,105 +24,6 @@ let
       name = "eth1";
       networkConfig.Address = "10.0.0.${hostId}/24";
     };
-  };
-
-  birdTest = v4:
-    let variant = "bird${optionalString (!v4) "6"}"; in
-    makeTest {
-      name = variant;
-
-      nodes.host1 = makeBirdHost variant "1";
-      nodes.host2 = makeBirdHost variant "2";
-
-      testScript = makeTestScript variant v4 (!v4);
-    };
-
-  bird2Test = makeTest {
-    name = "bird2";
-
-    nodes.host1 = makeBird2Host "1";
-    nodes.host2 = makeBird2Host "2";
-
-    testScript = makeTestScript "bird2" true true;
-  };
-
-  makeTestScript = variant: v4: v6: ''
-    start_all()
-
-    host1.wait_for_unit("${variant}.service")
-    host2.wait_for_unit("${variant}.service")
-
-    ${optionalString v4 ''
-    with subtest("Waiting for advertised IPv4 routes"):
-      host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
-      host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
-    ''}
-    ${optionalString v6 ''
-    with subtest("Waiting for advertised IPv6 routes"):
-      host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
-      host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
-    ''}
-
-    with subtest("Check fake routes in preCheckConfig do not exists"):
-      ${optionalString v4 ''host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")''}
-      ${optionalString v4 ''host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")''}
-
-      ${optionalString v6 ''host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")''}
-      ${optionalString v6 ''host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")''}
-  '';
-
-  makeBirdHost = variant: hostId: { pkgs, ... }: {
-    imports = [ (hostShared hostId) ];
-
-    services.${variant} = {
-      enable = true;
-
-      config = ''
-        log syslog all;
-
-        debug protocols all;
-
-        router id 10.0.0.${hostId};
-
-        protocol device {
-        }
-
-        protocol kernel {
-          import none;
-          export all;
-        }
-
-        protocol static {
-          include "static.conf";
-        }
-
-        protocol ospf {
-          export all;
-          area 0 {
-            interface "eth1" {
-              hello 5;
-              wait 5;
-            };
-          };
-        }
-      '';
-
-      preCheckConfig =
-        let
-          route = { bird = "1.2.3.4/32"; bird6 = "fd00::/128"; }.${variant};
-        in
-        ''echo "route ${route} blackhole;" > static.conf'';
-    };
-
-    systemd.tmpfiles.rules =
-      let
-        route = { bird = "10.10.0.${hostId}/32"; bird6 = "fdff::${hostId}/128"; }.${variant};
-      in
-      [ "f /etc/bird/static.conf - - - - route ${route} blackhole;" ];
-  };
-
-  makeBird2Host = hostId: { pkgs, ... }: {
-    imports = [ (hostShared hostId) ];
 
     services.bird2 = {
       enable = true;
@@ -198,8 +99,30 @@ let
     ];
   };
 in
-{
-  bird = birdTest true;
-  bird6 = birdTest false;
-  bird2 = bird2Test;
+makeTest {
+  name = "bird2";
+
+  nodes.host1 = makeBird2Host "1";
+  nodes.host2 = makeBird2Host "2";
+
+  testScript = ''
+    start_all()
+
+    host1.wait_for_unit("bird2.service")
+    host2.wait_for_unit("bird2.service")
+
+    with subtest("Waiting for advertised IPv4 routes"):
+      host1.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.2\")) | any'")
+      host2.wait_until_succeeds("ip --json r | jq -e 'map(select(.dst == \"10.10.0.1\")) | any'")
+    with subtest("Waiting for advertised IPv6 routes"):
+      host1.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::2\")) | any'")
+      host2.wait_until_succeeds("ip --json -6 r | jq -e 'map(select(.dst == \"fdff::1\")) | any'")
+
+    with subtest("Check fake routes in preCheckConfig do not exists"):
+      host1.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
+      host2.fail("ip --json r | jq -e 'map(select(.dst == \"1.2.3.4\")) | any'")
+
+      host1.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
+      host2.fail("ip --json -6 r | jq -e 'map(select(.dst == \"fd00::\")) | any'")
+  '';
 }