Skip to content

glibc‐nscd nsncd on NixOS

Florian Klink edited this page Oct 9, 2023 · 2 revisions

This assumes nsncd is running on your NixOS system as the nscd.service unit (the default on NixOS).

It then overwrites the location of the socket it binds to to /run/nsncd/socket (by bind-mounting /var/run/nscd`` and run/nscd` elsewhere).

It creates an additional glibc-nscd.service unit (assuming /etc/nscd.conf exists, as is the case on NixOS), and does the same trick to have glibc-nscd create its socket file at /run/nscd-glibc/socket.

It finally starts sockburp itself, having it listen on the "real" /run/nscd/socket socket, configuring it to send requests to and returning responses from nsncd, and using glibc-nscd as a comparison.

Packet dumps of all outliners are written to /var/lib/sockburb-nscd/diff.pcap.

In there, there's 3 "interfaces" to tell the requests apart, with the following interface names:

  • /run/nscd/socket containing the requests from userland
  • /run/nsncd/socket containing the responses from nsncd
  • /run/nscd-glibc/socket containing the responses from glibc-nscd
{ pkgs
, lib
, config
, ...
}:

let
  sockburp = pkgs.buildGoModule {
    pname = "sockburp";
    version = "0.0.0";
    src = pkgs.fetchFromGitHub {
      owner = "flokli";
      repo = "sockburp";
      rev = "11c83239809e2f26a91912bd37edaf8b81513221";
      hash = "sha256-r21WT5sXrsbmcJj9x/s5UyFF7d4Eao1NKGsOhXmK5Es=";
    };

    vendorHash = "sha256-DKQspvy86xUfa4W8AO2Q48UpuNQxAh/2u9ZyFZLgPSA=";
  };
in
{
  systemd.tmpfiles.rules = [
    "d /run/nsncd 0777 - - - -"
  ];
  systemd.services.nscd = {
    serviceConfig = {
      RuntimeDirectory = lib.mkForce "nsncd";
      BindPaths = [
        # Have nsncd create /run/nsncd/socket
        "/run/nsncd:/var/run/nscd"
        "/run/nsncd:/run/nscd"
      ];
    };
  };

  systemd.services.glibc-nscd = {
    wantedBy = [ "multi-user.target" ];
    description = "Name Service Cache Daemon (glibc)";
    environment = { LD_LIBRARY_PATH = config.system.nssModules.path; };
    serviceConfig = {
      ExecStart = "!@${pkgs.stdenv.cc.libc.bin}/bin/nscd nscd";
      Type = "forking";
      User = "nscd";
      Group = "nscd";
      RemoveIPC = true;
      PrivateTmp = true;
      NoNewPrivileges = true;
      RestrictSUIDSGID = true;
      ProtectSystem = "strict";
      ProtectHome = "read-only";
      RuntimeDirectory = "nscd-glibc";
      PIDFile = "/run/nscd-glibc/nscd.pid";
      Restart = "always";

      BindPaths = [
        # Have glibc-nsncd create /run/nscd-glibc/socket
        "/run/nscd-glibc:/var/run/nscd"
        "/run/nscd-glibc:/run/nscd"
      ];
    };
  };

  systemd.services.sockburp = {
    wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      ExecStart = "${sockburp}/bin/sockburp --log-level=debug --first-remote-address=/run/nsncd/socket --second-remote-address=/run/nscd-glibc/socket --pcap-path=%S/sockburp-nscd/diff.pcap /run/nscd/socket";
      Restart = "on-failure";
      RestartSec = "1";
      Type = "simple";
      StateDirectory = "sockburp-nscd";
    };
  };
}
Clone this wiki locally