Unverified Commit fadd3fef authored by Florian Klink's avatar Florian Klink Committed by GitHub
Browse files

Merge pull request #304322 from ElvishJerricco/sd-s1-resolved

nixos/systemd-stage-1: Support resolved
parents 8da1a55e bfdba4d0
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -128,10 +128,14 @@ in
        contents."/etc/dbus-1".source = pkgs.makeDBusConf {
          inherit (cfg) apparmor;
          suidHelper = "/bin/false";
          serviceDirectories = [ pkgs.dbus ];
          serviceDirectories = [ pkgs.dbus config.boot.initrd.systemd.package ];
        };
        packages = [ pkgs.dbus ];
        storePaths = [ "${pkgs.dbus}/bin/dbus-daemon" ];
        storePaths = [
          "${pkgs.dbus}/bin/dbus-daemon"
          "${config.boot.initrd.systemd.package}/share/dbus-1/system-services"
          "${config.boot.initrd.systemd.package}/share/dbus-1/system.d"
        ];
        targets.sockets.wants = [ "dbus.socket" ];
      };
    })
+92 −51
Original line number Diff line number Diff line
@@ -7,6 +7,20 @@ let
  dnsmasqResolve = config.services.dnsmasq.enable &&
                   config.services.dnsmasq.resolveLocalQueries;

  resolvedConf = ''
    [Resolve]
    ${optionalString (config.networking.nameservers != [])
      "DNS=${concatStringsSep " " config.networking.nameservers}"}
    ${optionalString (cfg.fallbackDns != null)
      "FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
    ${optionalString (cfg.domains != [])
      "Domains=${concatStringsSep " " cfg.domains}"}
    LLMNR=${cfg.llmnr}
    DNSSEC=${cfg.dnssec}
    DNSOverTLS=${cfg.dnsovertls}
    ${config.services.resolved.extraConfig}
  '';

in
{

@@ -126,9 +140,19 @@ in
      '';
    };

    boot.initrd.services.resolved.enable = mkOption {
      default = config.boot.initrd.systemd.network.enable;
      defaultText = "config.boot.initrd.systemd.network.enable";
      description = ''
        Whether to enable resolved for stage 1 networking.
        Uses the toplevel 'services.resolved' options for 'resolved.conf'
      '';
    };

  };

  config = mkIf cfg.enable {
  config = mkMerge [
    (mkIf cfg.enable {

      assertions = [
        { assertion = !config.networking.useHostResolvConf;
@@ -148,25 +172,13 @@ in
      ];

      systemd.services.systemd-resolved = {
      wantedBy = [ "multi-user.target" ];
        wantedBy = [ "sysinit.target" ];
        aliases = [ "dbus-org.freedesktop.resolve1.service" ];
        restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
      };

      environment.etc = {
      "systemd/resolved.conf".text = ''
        [Resolve]
        ${optionalString (config.networking.nameservers != [])
          "DNS=${concatStringsSep " " config.networking.nameservers}"}
        ${optionalString (cfg.fallbackDns != null)
          "FallbackDNS=${concatStringsSep " " cfg.fallbackDns}"}
        ${optionalString (cfg.domains != [])
          "Domains=${concatStringsSep " " cfg.domains}"}
        LLMNR=${cfg.llmnr}
        DNSSEC=${cfg.dnssec}
        DNSOverTLS=${cfg.dnsovertls}
        ${config.services.resolved.extraConfig}
      '';
        "systemd/resolved.conf".text = resolvedConf;

        # symlink the dynamic stub resolver of resolv.conf as recommended by upstream:
        # https://www.freedesktop.org/software/systemd/man/systemd-resolved.html#/etc/resolv.conf
@@ -180,6 +192,35 @@ in

      networking.resolvconf.package = pkgs.systemd;

    })

    (mkIf config.boot.initrd.services.resolved.enable {

      assertions = [
        {
          assertion = config.boot.initrd.systemd.enable;
          message = "'boot.initrd.services.resolved.enable' can only be enabled with systemd stage 1.";
        }
      ];

      boot.initrd.systemd = {
        contents = {
          "/etc/tmpfiles.d/resolv.conf".text =
            "L /etc/resolv.conf - - - - /run/systemd/resolve/stub-resolv.conf";
          "/etc/systemd/resolved.conf".text = resolvedConf;
        };

        additionalUpstreamUnits = ["systemd-resolved.service"];
        users.systemd-resolve = {};
        groups.systemd-resolve = {};
        storePaths = ["${config.boot.initrd.systemd.package}/lib/systemd/systemd-resolved"];
        services.systemd-resolved = {
          wantedBy = ["sysinit.target"];
          aliases = [ "dbus-org.freedesktop.resolve1.service" ];
        };
      };

    })
  ];

}
+1 −0
Original line number Diff line number Diff line
@@ -930,6 +930,7 @@ in {
  systemd-oomd = handleTest ./systemd-oomd.nix {};
  systemd-portabled = handleTest ./systemd-portabled.nix {};
  systemd-repart = handleTest ./systemd-repart.nix {};
  systemd-resolved = handleTest ./systemd-resolved.nix {};
  systemd-shutdown = handleTest ./systemd-shutdown.nix {};
  systemd-sysupdate = runTest ./systemd-sysupdate.nix;
  systemd-sysusers-mutable = runTest ./systemd-sysusers-mutable.nix;
+75 −0
Original line number Diff line number Diff line
import ./make-test-python.nix ({ pkgs, lib, ... }: {
  name = "systemd-resolved";
  meta.maintainers = [ lib.maintainers.elvishjerricco ];

  nodes.server = { lib, config, ... }: let
    exampleZone = pkgs.writeTextDir "example.com.zone" ''
      @ SOA ns.example.com. noc.example.com. 2019031301 86400 7200 3600000 172800
      @       A       ${(lib.head config.networking.interfaces.eth1.ipv4.addresses).address}
      @       AAAA    ${(lib.head config.networking.interfaces.eth1.ipv6.addresses).address}
    '';
  in {
    networking.firewall.enable = false;
    networking.useDHCP = false;

    networking.interfaces.eth1.ipv6.addresses = lib.mkForce [
      { address = "fd00::1"; prefixLength = 64; }
    ];

    services.knot = {
      enable = true;
      settings = {
        server.listen = [
          "0.0.0.0@53"
          "::@53"
        ];
        template.default.storage = exampleZone;
        zone."example.com".file = "example.com.zone";
      };
    };
  };

  nodes.client = { nodes, ... }: let
    inherit (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses) address;
  in {
    networking.nameservers = [ address ];
    networking.interfaces.eth1.ipv6.addresses = lib.mkForce [
      { address = "fd00::2"; prefixLength = 64; }
    ];
    services.resolved.enable = true;
    services.resolved.fallbackDns = [ ];
    networking.useNetworkd = true;
    networking.useDHCP = false;
    systemd.network.networks."40-eth0".enable = false;

    testing.initrdBackdoor = true;
    boot.initrd = {
      systemd.enable = true;
      systemd.initrdBin = [ pkgs.iputils ];
      network.enable = true;
      services.resolved.enable = true;
    };
  };

  testScript = { nodes, ... }: let
    address4 = (lib.head nodes.server.networking.interfaces.eth1.ipv4.addresses).address;
    address6 = (lib.head nodes.server.networking.interfaces.eth1.ipv6.addresses).address;
  in ''
    start_all()
    server.wait_for_unit("multi-user.target")

    def test_client():
        query = client.succeed("resolvectl query example.com")
        assert "${address4}" in query
        assert "${address6}" in query
        client.succeed("ping -4 -c 1 example.com")
        client.succeed("ping -6 -c 1 example.com")

    client.wait_for_unit("initrd.target")
    test_client()
    client.switch_root()

    client.wait_for_unit("multi-user.target")
    test_client()
  '';
})