oxipng: re-enable tests (#375349)
[NixPkgs.git] / nixos / modules / services / networking / doh-server.nix
blobbaa3e1844946f075bf2ccb500b2662f83f02109f
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
9   cfg = config.services.doh-server;
10   toml = pkgs.formats.toml { };
13   options.services.doh-server = {
14     enable = lib.mkEnableOption "DNS-over-HTTPS server";
16     package = lib.mkPackageOption pkgs "dns-over-https" { };
18     settings = lib.mkOption {
19       type = lib.types.submodule {
20         freeformType = toml.type;
21         options = {
23           listen = lib.mkOption {
24             type = lib.types.listOf lib.types.str;
25             default = [
26               "127.0.0.1:8053"
27               "[::1]:8053"
28             ];
29             example = [ ":443" ];
30             description = "HTTP listen address and port";
31           };
33           path = lib.mkOption {
34             type = lib.types.str;
35             default = "/dns-query";
36             example = "/dns-query";
37             description = "HTTP path for resolve application";
38           };
40           upstream = lib.mkOption {
41             type = lib.types.listOf lib.types.str;
42             default = [
43               "udp:1.1.1.1:53"
44               "udp:1.0.0.1:53"
45               "udp:8.8.8.8:53"
46               "udp:8.8.4.4:53"
47             ];
48             example = [ "udp:127.0.0.1:53" ];
49             description = ''
50               Upstream DNS resolver.
51               If multiple servers are specified, a random one will be chosen each time.
52               You can use "udp", "tcp" or "tcp-tls" for the type prefix.
53               For "udp", UDP will first be used, and switch to TCP when the server asks to or the response is too large.
54               For "tcp", only TCP will be used.
55               For "tcp-tls", DNS-over-TLS (RFC 7858) will be used to secure the upstream connection.
56             '';
57           };
59           timeout = lib.mkOption {
60             type = lib.types.int;
61             default = 10;
62             example = 15;
63             description = "Upstream timeout";
64           };
66           tries = lib.mkOption {
67             type = lib.types.int;
68             default = 3;
69             example = 5;
70             description = "Number of tries if upstream DNS fails";
71           };
73           verbose = lib.mkOption {
74             type = lib.types.bool;
75             default = false;
76             example = true;
77             description = "Enable logging";
78           };
80           log_guessed_client_ip = lib.mkOption {
81             type = lib.types.bool;
82             default = false;
83             example = true;
84             description = ''
85               Enable log IP from HTTPS-reverse proxy header: X-Forwarded-For or X-Real-IP
86               Note: http uri/useragent log cannot be controlled by this config
87             '';
88           };
90           ecs_allow_non_global_ip = lib.mkOption {
91             type = lib.types.bool;
92             default = false;
93             example = true;
94             description = ''
95               By default, non global IP addresses are never forwarded to upstream servers.
96               This is to prevent two things from happening:
97                 1. the upstream server knowing your private LAN addresses;
98                 2. the upstream server unable to provide geographically near results,
99                   or even fail to provide any result.
100               However, if you are deploying a split tunnel corporation network environment, or for any other reason you want to inhibit this behavior and allow local (eg RFC1918) address to be forwarded, change the following option to "true".
101             '';
102           };
104           ecs_use_precise_ip = lib.mkOption {
105             type = lib.types.bool;
106             default = false;
107             example = true;
108             description = ''
109               If ECS is added to the request, let the full IP address or cap it to 24 or 128 mask. This option is to be used only on private networks where knowledge of the terminal endpoint may be required for security purposes (eg. DNS Firewalling). Not a good option on the internet where IP address may be used to identify the user and not only the approximate location.
110             '';
111           };
112         };
113       };
114       default = { };
115       example = {
116         listen = [ ":8153" ];
117         upstream = [ "udp:127.0.0.1:53" ];
118       };
119       description = "Configuration of doh-server in toml. See example in https://github.com/m13253/dns-over-https/blob/master/doh-server/doh-server.conf";
120     };
122     useACMEHost = lib.mkOption {
123       type = lib.types.nullOr lib.types.str;
124       default = null;
125       example = "doh.example.com";
126       description = ''
127         A host of an existing Let's Encrypt certificate to use.
128         *Note that this option does not create any certificates, nor it does add subdomains to existing ones – you will need to create them manually using [](#opt-security.acme.certs).*
129       '';
130     };
132     configFile = lib.mkOption {
133       type = lib.types.path;
134       example = "/path/to/doh-server.conf";
135       description = ''
136         The config file for the doh-server.
137         Setting this option will override any configuration applied by the `settings` option.
138       '';
139     };
140   };
141   config = lib.mkIf cfg.enable {
142     services.doh-server.configFile = lib.mkDefault (toml.generate "doh-server.conf" cfg.settings);
143     services.doh-server.settings = lib.mkIf (cfg.useACMEHost != null) (
144       let
145         sslCertDir = config.security.acme.certs.${cfg.useACMEHost}.directory;
146       in
147       {
148         cert = "${sslCertDir}/cert.pem";
149         key = "${sslCertDir}/key.pem";
150       }
151     );
152     systemd.services.doh-server = {
153       description = "DNS-over-HTTPS Server";
154       documentation = [ "https://github.com/m13253/dns-over-https" ];
155       after = [
156         "network.target"
157       ] ++ lib.optional (cfg.useACMEHost != null) "acme-${cfg.useACMEHost}.service";
158       wants = lib.optional (cfg.useACMEHost != null) "acme-finished-${cfg.useACMEHost}.target";
159       wantedBy = [ "multi-user.target" ];
160       serviceConfig = {
161         AmbientCapabilities = "CAP_NET_BIND_SERVICE";
162         ExecStart = "${cfg.package}/bin/doh-server -conf ${cfg.configFile}";
163         LimitNOFILE = 1048576;
164         Restart = "always";
165         RestartSec = 3;
166         Type = "simple";
167         DynamicUser = true;
168         SupplementaryGroups = lib.optional (cfg.useACMEHost != null) "acme";
169       };
170     };
171   };
173   meta.maintainers = with lib.maintainers; [ DictXiong ];
174   meta.doc = ./doh-server.md;