From 749f4be1ef9b115c97fa717cc6068ab342c7650c Mon Sep 17 00:00:00 2001
From: Alan Pearce
Date: Tue, 12 Nov 2019 19:30:35 +0100
Subject: Configure nextdns usage via module
---
system/modules/darwin/kresd.nix | 45 ++++++++
system/modules/darwin/stubby.nix | 218 +++++++++++++++++++++++++++++++++++++++
2 files changed, 263 insertions(+)
create mode 100644 system/modules/darwin/kresd.nix
create mode 100644 system/modules/darwin/stubby.nix
(limited to 'system/modules/darwin')
diff --git a/system/modules/darwin/kresd.nix b/system/modules/darwin/kresd.nix
new file mode 100644
index 00000000..6bce8af1
--- /dev/null
+++ b/system/modules/darwin/kresd.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.kresd;
+ package = pkgs.knot-resolver;
+
+ configFile = pkgs.writeText "kresd.conf" cfg.extraConfig;
+in
+{
+ options = {
+ services.kresd.enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable knot-resolver daemon.";
+ };
+
+ services.kresd.extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration to be added to the generated configuration file.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ launchd.daemons.kresd = {
+ command = "${package}/bin/kresd -c ${configFile}";
+
+ serviceConfig = {
+ ProcessType = "Interactive";
+ # Sockets = {
+ # Listeners = {
+ # SockServiceName = "dns";
+ # SockFamily = "IPv4";
+ # };
+ # };
+ };
+ };
+
+ environment.systemPackages = [ package ];
+ };
+}
diff --git a/system/modules/darwin/stubby.nix b/system/modules/darwin/stubby.nix
new file mode 100644
index 00000000..b3b67755
--- /dev/null
+++ b/system/modules/darwin/stubby.nix
@@ -0,0 +1,218 @@
+{ config, lib, pkgs, ...}:
+
+with lib;
+
+let
+ cfg = config.services.stubby;
+ package = pkgs.stubby;
+
+ fallbacks = concatMapStringsSep "\n " (x: "- ${x}") cfg.fallbackProtocols;
+ listeners = concatMapStringsSep "\n " (x: "- ${x}") cfg.listenAddresses;
+
+ # By default, the recursive resolvers maintained by the getdns
+ # project itself are enabled. More information about both getdns's servers,
+ # as well as third party options for upstream resolvers, can be found here:
+ # https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers
+ #
+ # You can override these values by supplying a yaml-formatted array of your
+ # preferred upstream resolvers in the following format:
+ #
+ # 106 # - address_data: IPv4 or IPv6 address of the upstream
+ # port: Port for UDP/TCP (default is 53)
+ # tls_auth_name: Authentication domain name checked against the server
+ # certificate
+ # tls_pubkey_pinset: An SPKI pinset verified against the keys in the server
+ # certificate
+ # - digest: Only "sha256" is currently supported
+ # value: Base64 encoded value of the sha256 fingerprint of the public
+ # key
+ # tls_port: Port for TLS (default is 853)
+
+ defaultUpstream = ''
+ - address_data: 145.100.185.15
+ tls_auth_name: "dnsovertls.sinodun.com"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
+ - address_data: 145.100.185.16
+ tls_auth_name: "dnsovertls1.sinodun.com"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
+ - address_data: 185.49.141.37
+ tls_auth_name: "getdnsapi.net"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
+ - address_data: 2001:610:1:40ba:145:100:185:15
+ tls_auth_name: "dnsovertls.sinodun.com"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
+ - address_data: 2001:610:1:40ba:145:100:185:16
+ tls_auth_name: "dnsovertls1.sinodun.com"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
+ - address_data: 2a04:b900:0:100::38
+ tls_auth_name: "getdnsapi.net"
+ tls_pubkey_pinset:
+ - digest: "sha256"
+ value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
+ '';
+
+ # Resolution type is not changeable here because it is required per the
+ # stubby documentation:
+ #
+ # "resolution_type: Work in stub mode only (not recursive mode) - required for Stubby
+ # operation."
+ #
+ # https://dnsprivacy.org/wiki/display/DP/Configuring+Stubby
+
+ confFile = pkgs.writeText "stubby.yml" ''
+ resolution_type: GETDNS_RESOLUTION_STUB
+ dns_transport_list:
+ ${fallbacks}
+ tls_authentication: ${cfg.authenticationMode}
+ tls_query_padding_blocksize: ${toString cfg.queryPaddingBlocksize}
+ edns_client_subnet_private: ${if cfg.subnetPrivate then "1" else "0"}
+ idle_timeout: ${toString cfg.idleTimeout}
+ listen_addresses:
+ ${listeners}
+ round_robin_upstreams: ${if cfg.roundRobinUpstreams then "1" else "0"}
+ ${cfg.extraConfig}
+ upstream_recursive_servers:
+ ${cfg.upstreamServers}
+ '';
+in
+
+{
+ options = {
+ services.stubby = {
+
+ enable = mkEnableOption "Stubby DNS resolver";
+
+ fallbackProtocols = mkOption {
+ default = [ "GETDNS_TRANSPORT_TLS" ];
+ type = with types; listOf (enum [
+ "GETDNS_TRANSPORT_TLS"
+ "GETDNS_TRANSPORT_TCP"
+ "GETDNS_TRANSPORT_UDP"
+ ]);
+ description = ''
+ Ordered list composed of one or more transport protocols.
+ Strict mode should only use GETDNS_TRANSPORT_TLS.
+ Other options are GETDNS_TRANSPORT_UDP and
+ GETDNS_TRANSPORT_TCP.
+ '';
+ };
+
+ authenticationMode = mkOption {
+ default = "GETDNS_AUTHENTICATION_REQUIRED";
+ type = types.enum [
+ "GETDNS_AUTHENTICATION_REQUIRED"
+ "GETDNS_AUTHENTICATION_NONE"
+ ];
+ description = ''
+ Selects the Strict or Opportunistic usage profile.
+ For strict, set to GETDNS_AUTHENTICATION_REQUIRED.
+ for opportunistic, use GETDNS_AUTHENTICATION_NONE.
+ '';
+ };
+
+ queryPaddingBlocksize = mkOption {
+ default = 128;
+ type = types.int;
+ description = ''
+ EDNS0 option to pad the size of the DNS query to the given blocksize.
+ '';
+ };
+
+ subnetPrivate = mkOption {
+ default = true;
+ type = types.bool;
+ description = ''
+ EDNS0 option for ECS client privacy. Default is
+ true. If set, this option prevents the client
+ subnet from being sent to authoritative nameservers.
+ '';
+ };
+
+ idleTimeout = mkOption {
+ default = 10000;
+ type = types.int;
+ description = "EDNS0 option for keepalive idle timeout expressed in
+ milliseconds.";
+ };
+
+ listenAddresses = mkOption {
+ default = [ "127.0.0.1" "0::1" ];
+ type = with types; listOf str;
+ description = ''
+ Sets the listen address for the stubby daemon.
+ Uses port 53 by default.
+ Ise IP@port to specify a different port.
+ '';
+ };
+
+ roundRobinUpstreams = mkOption {
+ default = true;
+ type = types.bool;
+ description = ''
+ Instructs stubby to distribute queries across all available name
+ servers. Default is true. Set to
+ false in order to use the first available.
+ '';
+ };
+
+ upstreamServers = mkOption {
+ default = defaultUpstream;
+ type = types.lines;
+ description = ''
+ Replace default upstreams. See stubby
+ 1 for an
+ example of the entry formatting. In Strict mode, at least one of the
+ following settings must be supplied for each nameserver:
+ tls_auth_name or
+ tls_pubkey_pinset.
+ '';
+ };
+
+ debugLogging = mkOption {
+ default = false;
+ type = types.bool;
+ description = "Enable or disable debug level logging.";
+ };
+
+ extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Add additional configuration options. see
+ stubby1
+ for more options.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ launchd.daemons.stubby = {
+ command = "${package}/bin/stubby -C ${confFile} ${optionalString cfg.debugLogging "-l"}";
+
+ serviceConfig = {
+ ProcessType = "Interactive";
+ RunAtLoad = true;
+ KeepAlive = true;
+ # Sockets = {
+ # Listeners = {
+ # SockServiceName = "dns";
+ # SockFamily = "IPv4";
+ # };
+ # };
+ };
+ };
+
+ environment.systemPackages = [ package ];
+ };
+}
--
cgit 1.4.1