1# This file defines the options that can be used both for the Nginx
2# main server configuration, and for the virtual hosts. (The latter
3# has additional options that affect the web server as a whole, like
4# the user/group to run under.)
5
6{ config, lib, ... }:
7
8with lib;
9{
10 options = {
11 serverName = mkOption {
12 type = types.nullOr types.str;
13 default = null;
14 description = lib.mdDoc ''
15 Name of this virtual host. Defaults to attribute name in virtualHosts.
16 '';
17 example = "example.org";
18 };
19
20 serverAliases = mkOption {
21 type = types.listOf types.str;
22 default = [];
23 example = [ "www.example.org" "example.org" ];
24 description = lib.mdDoc ''
25 Additional names of virtual hosts served by this virtual host configuration.
26 '';
27 };
28
29 listen = mkOption {
30 type = with types; listOf (submodule { options = {
31 addr = mkOption { type = str; description = lib.mdDoc "IP address."; };
32 port = mkOption { type = port; description = lib.mdDoc "Port number."; default = 80; };
33 ssl = mkOption { type = bool; description = lib.mdDoc "Enable SSL."; default = false; };
34 extraParameters = mkOption { type = listOf str; description = lib.mdDoc "Extra parameters of this listen directive."; default = []; example = [ "backlog=1024" "deferred" ]; };
35 }; });
36 default = [];
37 example = [
38 { addr = "195.154.1.1"; port = 443; ssl = true; }
39 { addr = "192.154.1.1"; port = 80; }
40 ];
41 description = lib.mdDoc ''
42 Listen addresses and ports for this virtual host.
43 IPv6 addresses must be enclosed in square brackets.
44 Note: this option overrides `addSSL`
45 and `onlySSL`.
46
47 If you only want to set the addresses manually and not
48 the ports, take a look at `listenAddresses`
49 '';
50 };
51
52 listenAddresses = mkOption {
53 type = with types; listOf str;
54
55 description = lib.mdDoc ''
56 Listen addresses for this virtual host.
57 Compared to `listen` this only sets the addresses
58 and the ports are chosen automatically.
59
60 Note: This option overrides `enableIPv6`
61 '';
62 default = [];
63 example = [ "127.0.0.1" "[::1]" ];
64 };
65
66 enableACME = mkOption {
67 type = types.bool;
68 default = false;
69 description = lib.mdDoc ''
70 Whether to ask Let's Encrypt to sign a certificate for this vhost.
71 Alternately, you can use an existing certificate through {option}`useACMEHost`.
72 '';
73 };
74
75 useACMEHost = mkOption {
76 type = types.nullOr types.str;
77 default = null;
78 description = lib.mdDoc ''
79 A host of an existing Let's Encrypt certificate to use.
80 This is useful if you have many subdomains and want to avoid hitting the
81 [rate limit](https://letsencrypt.org/docs/rate-limits).
82 Alternately, you can generate a certificate through {option}`enableACME`.
83 *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).*
84 '';
85 };
86
87 acmeRoot = mkOption {
88 type = types.nullOr types.str;
89 default = "/var/lib/acme/acme-challenge";
90 description = lib.mdDoc ''
91 Directory for the ACME challenge, which is **public**. Don't put certs or keys in here.
92 Set to null to inherit from config.security.acme.
93 '';
94 };
95
96 acmeFallbackHost = mkOption {
97 type = types.nullOr types.str;
98 default = null;
99 description = lib.mdDoc ''
100 Host which to proxy requests to if ACME challenge is not found. Useful
101 if you want multiple hosts to be able to verify the same domain name.
102
103 With this option, you could request certificates for the present domain
104 with an ACME client that is running on another host, which you would
105 specify here.
106 '';
107 };
108
109 addSSL = mkOption {
110 type = types.bool;
111 default = false;
112 description = lib.mdDoc ''
113 Whether to enable HTTPS in addition to plain HTTP. This will set defaults for
114 `listen` to listen on all interfaces on the respective default
115 ports (80, 443).
116 '';
117 };
118
119 onlySSL = mkOption {
120 type = types.bool;
121 default = false;
122 description = lib.mdDoc ''
123 Whether to enable HTTPS and reject plain HTTP connections. This will set
124 defaults for `listen` to listen on all interfaces on port 443.
125 '';
126 };
127
128 enableSSL = mkOption {
129 type = types.bool;
130 visible = false;
131 default = false;
132 };
133
134 forceSSL = mkOption {
135 type = types.bool;
136 default = false;
137 description = lib.mdDoc ''
138 Whether to add a separate nginx server block that permanently redirects (301)
139 all plain HTTP traffic to HTTPS. This will set defaults for
140 `listen` to listen on all interfaces on the respective default
141 ports (80, 443), where the non-SSL listens are used for the redirect vhosts.
142 '';
143 };
144
145 rejectSSL = mkOption {
146 type = types.bool;
147 default = false;
148 description = lib.mdDoc ''
149 Whether to listen for and reject all HTTPS connections to this vhost. Useful in
150 [default](#opt-services.nginx.virtualHosts._name_.default)
151 server blocks to avoid serving the certificate for another vhost. Uses the
152 `ssl_reject_handshake` directive available in nginx versions
153 1.19.4 and above.
154 '';
155 };
156
157 kTLS = mkOption {
158 type = types.bool;
159 default = false;
160 description = lib.mdDoc ''
161 Whether to enable kTLS support.
162 Implementing TLS in the kernel (kTLS) improves performance by significantly
163 reducing the need for copying operations between user space and the kernel.
164 Required Nginx version 1.21.4 or later.
165 '';
166 };
167
168 sslCertificate = mkOption {
169 type = types.path;
170 example = "/var/host.cert";
171 description = lib.mdDoc "Path to server SSL certificate.";
172 };
173
174 sslCertificateKey = mkOption {
175 type = types.path;
176 example = "/var/host.key";
177 description = lib.mdDoc "Path to server SSL certificate key.";
178 };
179
180 sslTrustedCertificate = mkOption {
181 type = types.nullOr types.path;
182 default = null;
183 example = literalExpression ''"''${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"'';
184 description = lib.mdDoc "Path to root SSL certificate for stapling and client certificates.";
185 };
186
187 http2 = mkOption {
188 type = types.bool;
189 default = true;
190 description = lib.mdDoc ''
191 Whether to enable the HTTP/2 protocol.
192 Note that (as of writing) due to nginx's implementation, to disable
193 HTTP/2 you have to disable it on all vhosts that use a given
194 IP address / port.
195 If there is one server block configured to enable http2, then it is
196 enabled for all server blocks on this IP.
197 See https://stackoverflow.com/a/39466948/263061.
198 '';
199 };
200
201 http3 = mkOption {
202 type = types.bool;
203 default = true;
204 description = lib.mdDoc ''
205 Whether to enable the HTTP/3 protocol.
206 This requires using `pkgs.nginxQuic` package
207 which can be achieved by setting `services.nginx.package = pkgs.nginxQuic;`
208 and activate the QUIC transport protocol
209 `services.nginx.virtualHosts.<name>.quic = true;`.
210 Note that HTTP/3 support is experimental and
211 *not* yet recommended for production.
212 Read more at https://quic.nginx.org/
213 '';
214 };
215
216 http3_hq = mkOption {
217 type = types.bool;
218 default = false;
219 description = lib.mdDoc ''
220 Whether to enable the HTTP/0.9 protocol negotiation used in QUIC interoperability tests.
221 This requires using `pkgs.nginxQuic` package
222 which can be achieved by setting `services.nginx.package = pkgs.nginxQuic;`
223 and activate the QUIC transport protocol
224 `services.nginx.virtualHosts.<name>.quic = true;`.
225 Note that special application protocol support is experimental and
226 *not* yet recommended for production.
227 Read more at https://quic.nginx.org/
228 '';
229 };
230
231 quic = mkOption {
232 type = types.bool;
233 default = false;
234 description = lib.mdDoc ''
235 Whether to enable the QUIC transport protocol.
236 This requires using `pkgs.nginxQuic` package
237 which can be achieved by setting `services.nginx.package = pkgs.nginxQuic;`.
238 Note that QUIC support is experimental and
239 *not* yet recommended for production.
240 Read more at https://quic.nginx.org/
241 '';
242 };
243
244 reuseport = mkOption {
245 type = types.bool;
246 default = false;
247 description = lib.mdDoc ''
248 Create an individual listening socket .
249 It is required to specify only once on one of the hosts.
250 '';
251 };
252
253 root = mkOption {
254 type = types.nullOr types.path;
255 default = null;
256 example = "/data/webserver/docs";
257 description = lib.mdDoc ''
258 The path of the web root directory.
259 '';
260 };
261
262 default = mkOption {
263 type = types.bool;
264 default = false;
265 description = lib.mdDoc ''
266 Makes this vhost the default.
267 '';
268 };
269
270 extraConfig = mkOption {
271 type = types.lines;
272 default = "";
273 description = lib.mdDoc ''
274 These lines go to the end of the vhost verbatim.
275 '';
276 };
277
278 globalRedirect = mkOption {
279 type = types.nullOr types.str;
280 default = null;
281 example = "newserver.example.org";
282 description = lib.mdDoc ''
283 If set, all requests for this host are redirected permanently to
284 the given hostname.
285 '';
286 };
287
288 basicAuth = mkOption {
289 type = types.attrsOf types.str;
290 default = {};
291 example = literalExpression ''
292 {
293 user = "password";
294 };
295 '';
296 description = lib.mdDoc ''
297 Basic Auth protection for a vhost.
298
299 WARNING: This is implemented to store the password in plain text in the
300 Nix store.
301 '';
302 };
303
304 basicAuthFile = mkOption {
305 type = types.nullOr types.path;
306 default = null;
307 description = lib.mdDoc ''
308 Basic Auth password file for a vhost.
309 Can be created via: {command}`htpasswd -c <filename> <username>`.
310
311 WARNING: The generate file contains the users' passwords in a
312 non-cryptographically-securely hashed way.
313 '';
314 };
315
316 locations = mkOption {
317 type = types.attrsOf (types.submodule (import ./location-options.nix {
318 inherit lib config;
319 }));
320 default = {};
321 example = literalExpression ''
322 {
323 "/" = {
324 proxyPass = "http://localhost:3000";
325 };
326 };
327 '';
328 description = lib.mdDoc "Declarative location config";
329 };
330 };
331}