about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/mail/public-inbox.nix15
-rw-r--r--nixos/modules/services/networking/adguardhome.nix16
-rw-r--r--nixos/modules/services/networking/fakeroute.nix22
-rw-r--r--nixos/modules/testing/test-instrumentation.nix2
-rw-r--r--nixos/tests/adguardhome.nix69
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/fakeroute.nix22
-rw-r--r--nixos/tests/nix-ld.nix3
-rw-r--r--nixos/tests/public-inbox.nix3
9 files changed, 124 insertions, 29 deletions
diff --git a/nixos/modules/services/mail/public-inbox.nix b/nixos/modules/services/mail/public-inbox.nix
index a7d7097065a28..4944d46fbd736 100644
--- a/nixos/modules/services/mail/public-inbox.nix
+++ b/nixos/modules/services/mail/public-inbox.nix
@@ -89,7 +89,7 @@ let
       PrivateNetwork = mkDefault (!needNetwork);
       ProcSubset = "pid";
       ProtectClock = true;
-      ProtectHome = mkDefault true;
+      ProtectHome = "tmpfs";
       ProtectHostname = true;
       ProtectKernelLogs = true;
       ProtectProc = "invisible";
@@ -460,6 +460,8 @@ in
           after = [ "public-inbox-init.service" "public-inbox-watch.service" ];
           requires = [ "public-inbox-init.service" ];
           serviceConfig = {
+            BindPathsReadOnly =
+              map (c: c.dir) (lib.attrValues cfg.settings.coderepo);
             ExecStart = escapeShellArgs (
               [ "${cfg.package}/bin/public-inbox-httpd" ] ++
               cfg.http.args ++
@@ -563,16 +565,7 @@ in
                 ${pkgs.git}/bin/git config core.sharedRepository 0640
               fi
             '') cfg.inboxes
-            ) + ''
-            shopt -s nullglob
-            for inbox in ${stateDir}/inboxes/*/; do
-              # This should be idempotent, but only do it for new
-              # inboxes anyway because it's only needed once, and could
-              # be slow for large pre-existing inboxes.
-              ls -1 "$inbox" | grep -q '^xap' ||
-              ${cfg.package}/bin/public-inbox-index "$inbox"
-            done
-          '';
+            );
           serviceConfig = {
             Type = "oneshot";
             RemainAfterExit = true;
diff --git a/nixos/modules/services/networking/adguardhome.nix b/nixos/modules/services/networking/adguardhome.nix
index bda99cb7942b8..1701e5b439c18 100644
--- a/nixos/modules/services/networking/adguardhome.nix
+++ b/nixos/modules/services/networking/adguardhome.nix
@@ -41,6 +41,20 @@ in
       '';
     };
 
+    allowDHCP = mkOption {
+      default = cfg.settings.dhcp.enabled or false;
+      defaultText = literalExpression ''config.services.adguardhome.settings.dhcp.enabled or false'';
+      type = bool;
+      description = lib.mdDoc ''
+        Allows AdGuard Home to open raw sockets (`CAP_NET_RAW`), which is
+        required for the integrated DHCP server.
+
+        The default enables this conditionally if the declarative configuration
+        enables the integrated DHCP server. Manually setting this option is only
+        required for non-declarative setups.
+      '';
+    };
+
     mutableSettings = mkOption {
       default = true;
       type = bool;
@@ -147,7 +161,7 @@ in
       serviceConfig = {
         DynamicUser = true;
         ExecStart = "${pkgs.adguardhome}/bin/adguardhome ${args}";
-        AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
+        AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ] ++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ];
         Restart = "always";
         RestartSec = 10;
         RuntimeDirectory = "AdGuardHome";
diff --git a/nixos/modules/services/networking/fakeroute.nix b/nixos/modules/services/networking/fakeroute.nix
index ed6b1a3c4d262..faf5879a6ed31 100644
--- a/nixos/modules/services/networking/fakeroute.nix
+++ b/nixos/modules/services/networking/fakeroute.nix
@@ -1,10 +1,8 @@
 { config, lib, pkgs, ... }:
 
-with lib;
-
 let
   cfg = config.services.fakeroute;
-  routeConf = pkgs.writeText "route.conf" (concatStringsSep "\n" cfg.route);
+  routeConf = pkgs.writeText "route.conf" (lib.concatStringsSep "\n" cfg.route);
 
 in
 
@@ -16,16 +14,10 @@ in
 
     services.fakeroute = {
 
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = lib.mdDoc ''
-          Whether to enable the fakeroute service.
-        '';
-      };
+      enable = lib.mkEnableOption (lib.mdDoc "the fakeroute service");
 
-      route = mkOption {
-        type = types.listOf types.str;
+      route = lib.mkOption {
+        type = with lib.types; listOf str;
         default = [];
         example = [
           "216.102.187.130"
@@ -46,14 +38,16 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = lib.mkIf cfg.enable {
     systemd.services.fakeroute = {
       description = "Fakeroute Daemon";
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
         Type = "forking";
-        User = "root";
+        User = "fakeroute";
+        DynamicUser = true;
+        AmbientCapabilities = [ "CAP_NET_RAW" ];
         ExecStart = "${pkgs.fakeroute}/bin/fakeroute -f ${routeConf}";
       };
     };
diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix
index 67fdc0ea43357..6dc4091bad178 100644
--- a/nixos/modules/testing/test-instrumentation.nix
+++ b/nixos/modules/testing/test-instrumentation.nix
@@ -115,10 +115,12 @@ in
       ShowStatus=no
       # Allow very slow start
       DefaultTimeoutStartSec=300
+      DefaultDeviceTimeoutSec=300
     '';
     systemd.user.extraConfig = ''
       # Allow very slow start
       DefaultTimeoutStartSec=300
+      DefaultDeviceTimeoutSec=300
     '';
 
     boot.initrd.systemd.extraConfig = config.systemd.extraConfig;
diff --git a/nixos/tests/adguardhome.nix b/nixos/tests/adguardhome.nix
index ec1cc1e497b50..9f8ddc33f57e9 100644
--- a/nixos/tests/adguardhome.nix
+++ b/nixos/tests/adguardhome.nix
@@ -40,6 +40,67 @@
         };
       };
     };
+
+    dhcpConf = { lib, ... }: {
+      virtualisation.vlans = [ 1 ];
+
+      networking = {
+        # Configure static IP for DHCP server
+        useDHCP = false;
+        interfaces."eth1" = lib.mkForce {
+          useDHCP = false;
+          ipv4 = {
+            addresses = [{
+              address = "10.0.10.1";
+              prefixLength = 24;
+            }];
+
+            routes = [{
+              address = "10.0.10.0";
+              prefixLength = 24;
+            }];
+          };
+        };
+
+        # Required for DHCP
+        firewall.allowedUDPPorts = [ 67 68 ];
+      };
+
+      services.adguardhome = {
+        enable = true;
+        allowDHCP = true;
+        mutableSettings = false;
+        settings = {
+          schema_version = 0;
+          dns = {
+            bind_host = "0.0.0.0";
+            bootstrap_dns = "127.0.0.1";
+          };
+          dhcp = {
+            # This implicitly enables CAP_NET_RAW
+            enabled = true;
+            interface_name = "eth1";
+            local_domain_name = "lan";
+            dhcpv4 = {
+              gateway_ip = "10.0.10.1";
+              range_start = "10.0.10.100";
+              range_end = "10.0.10.101";
+              subnet_mask = "255.255.255.0";
+            };
+          };
+        };
+      };
+    };
+
+    client = { lib, ... }: {
+      virtualisation.vlans = [ 1 ];
+      networking = {
+        interfaces.eth1 = {
+          useDHCP = true;
+          ipv4.addresses = lib.mkForce [ ];
+        };
+      };
+    };
   };
 
   testScript = ''
@@ -63,5 +124,13 @@
         mixedConf.systemctl("restart adguardhome.service")
         mixedConf.wait_for_unit("adguardhome.service")
         mixedConf.wait_for_open_port(3000)
+
+    with subtest("Testing successful DHCP start"):
+        dhcpConf.wait_for_unit("adguardhome.service")
+        client.wait_for_unit("network-online.target")
+        # Test IP assignment via DHCP
+        dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100")
+        # Test hostname resolution over DHCP-provided DNS
+        dhcpConf.wait_until_succeeds("ping -c 5 client.lan")
   '';
 }
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 5e846fc83d1aa..9a7f6807ffd58 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -253,6 +253,7 @@ in {
   etebase-server = handleTest ./etebase-server.nix {};
   etesync-dav = handleTest ./etesync-dav.nix {};
   evcc = handleTest ./evcc.nix {};
+  fakeroute = handleTest ./fakeroute.nix {};
   fancontrol = handleTest ./fancontrol.nix {};
   fcitx5 = handleTest ./fcitx5 {};
   fenics = handleTest ./fenics.nix {};
diff --git a/nixos/tests/fakeroute.nix b/nixos/tests/fakeroute.nix
new file mode 100644
index 0000000000000..37b174524ab81
--- /dev/null
+++ b/nixos/tests/fakeroute.nix
@@ -0,0 +1,22 @@
+import ./make-test-python.nix ({ lib, pkgs, ...} : {
+  name = "fakeroute";
+  meta.maintainers = with lib.maintainers; [ rnhmjoj ];
+
+  nodes.machine = { ... }: {
+    imports = [ ../modules/profiles/minimal.nix ];
+    services.fakeroute.enable = true;
+    services.fakeroute.route =
+      [ "216.102.187.130" "4.0.1.122"
+        "198.116.142.34" "63.199.8.242"
+      ];
+    environment.systemPackages = [ pkgs.traceroute ];
+  };
+
+  testScript =
+    ''
+      start_all()
+      machine.wait_for_unit("fakeroute.service")
+      machine.succeed("traceroute 127.0.0.1 | grep -q 216.102.187.130")
+    '';
+})
+
diff --git a/nixos/tests/nix-ld.nix b/nixos/tests/nix-ld.nix
index c62c0437e04ec..8733f5b0c3978 100644
--- a/nixos/tests/nix-ld.nix
+++ b/nixos/tests/nix-ld.nix
@@ -13,8 +13,5 @@ import ./make-test-python.nix ({ lib, pkgs, ...} :
   testScript = ''
     start_all()
     machine.succeed("hello")
-
-    # test fallback if NIX_LD is not set
-    machine.succeed("unset NIX_LD; unset NIX_LD_LIBRARY_PATH; hello")
  '';
 })
diff --git a/nixos/tests/public-inbox.nix b/nixos/tests/public-inbox.nix
index 784ef9e3dc28e..4d06d3e1738ee 100644
--- a/nixos/tests/public-inbox.nix
+++ b/nixos/tests/public-inbox.nix
@@ -223,5 +223,8 @@ in
     # require to use --all
     machine.succeed("curl -L https://machine.${domain}/inbox/repo1/repo1@root-1/raw | sudo -u public-inbox public-inbox-learn rm --all")
     machine.fail("curl -L https://machine.${domain}/inbox/repo1/repo1@root-1/T/#u | grep 'This is a testing mail.'")
+
+    # Compact the database
+    machine.succeed("sudo -u public-inbox public-inbox-compact --all")
   '';
 })