1 { config, lib, pkgs, ... }:
6 mkEnableOption mkIf mkOption types;
8 cfg = config.services.https-dns-proxy;
12 ips = [ "1.1.1.1" "1.0.0.1" ];
13 url = "https://cloudflare-dns.com/dns-query";
16 ips = [ "8.8.8.8" "8.8.4.4" ];
17 url = "https://dns.google/dns-query";
20 ips = [ "9.9.9.9" "149.112.112.112" ];
21 url = "https://dns.quad9.net/dns-query";
24 ips = [ "208.67.222.222" "208.67.220.220" ];
25 url = "https://doh.opendns.com/dns-query";
28 inherit (cfg.provider) ips url;
32 defaultProvider = "quad9";
35 concatStringsSep " " [
37 (concatStringsSep "," providers."${cfg.provider.kind}".ips)
39 providers."${cfg.provider.kind}".url
44 meta.maintainers = with lib.maintainers; [ peterhoeg ];
48 options.services.https-dns-proxy = {
49 enable = mkEnableOption "https-dns-proxy daemon";
52 description = "The address on which to listen";
54 default = "127.0.0.1";
58 description = "The port on which to listen";
66 The upstream provider to use or custom in case you do not trust any of
67 the predefined providers or just want to use your own.
69 The default is ${defaultProvider} and there are privacy and security
70 trade-offs when using any upstream provider. Please consider that
71 before using any of them.
73 Supported providers: ${concatStringsSep ", " (builtins.attrNames providers)}
75 If you pick the custom provider, you will need to provide the
76 bootstrap IP addresses as well as the resolver https URL.
78 type = types.enum (builtins.attrNames providers);
79 default = defaultProvider;
83 description = "The custom provider IPs";
84 type = types.listOf types.str;
88 description = "The custom provider URL";
93 preferIPv4 = mkOption {
95 https_dns_proxy will by default use IPv6 and fail if it is not available.
96 To play it safe, we choose IPv4.
102 extraArgs = mkOption {
103 description = "Additional arguments to pass to the process.";
104 type = types.listOf types.str;
109 ###### implementation
111 config = lib.mkIf cfg.enable {
112 systemd.services.https-dns-proxy = {
113 description = "DNS to DNS over HTTPS (DoH) proxy";
114 requires = [ "network.target" ];
115 after = [ "network.target" ];
116 wants = [ "nss-lookup.target" ];
117 before = [ "nss-lookup.target" ];
118 wantedBy = [ "multi-user.target" ];
119 serviceConfig = rec {
122 ProtectHome = "tmpfs";
123 ExecStart = lib.concatStringsSep " " (
125 (lib.getExe pkgs.https-dns-proxy)
126 "-a ${toString cfg.address}"
127 "-p ${toString cfg.port}"
131 ++ lib.optional cfg.preferIPv4 "-4"
134 Restart = "on-failure";