-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnginx.nix
115 lines (107 loc) · 3.63 KB
/
nginx.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
{
config,
lib,
...
}:
let
inherit (lib)
mkBefore
mkEnableOption
mkIf
mkOption
types
;
in
{
options.services.nginx = {
recommendedSetup = mkEnableOption "recommended setup parameters.";
recommendedSecurityHeaders = mkEnableOption "additional security headers by default in each location block. Can be overwritten in each location with `recommendedSecurityHeaders`.";
virtualHosts = mkOption {
type = types.attrsOf (
types.submodule {
options.locations = mkOption {
type = types.attrsOf (
types.submodule (submod: {
options = {
recommendedSecurityHeaders = mkOption {
type = types.bool;
default = config.services.nginx.recommendedSecurityHeaders;
description = "Whether to add additional security headers to this location.";
};
X-Frame-Options = mkOption {
type = types.str;
default = "DENY";
description = "The value to use for X-Frame-Options";
};
};
config = mkIf submod.config.recommendedSecurityHeaders {
extraConfig = mkBefore ''
# Enable HTTP Strict Transport Security (HSTS)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# Minimize information leaked to other domains
add_header Referrer-Policy "origin-when-cross-origin";
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options "${submod.config.X-Frame-Options}";
add_header X-Content-Type-Options "nosniff";
'';
};
})
);
};
}
);
};
};
config = mkIf (config.services.nginx.enable && config.services.nginx.recommendedSetup) {
age.secrets."dhparams.pem" = mkIf (config ? age) {
generator.script = "dhparams";
mode = "440";
group = "nginx";
};
networking.firewall.allowedTCPPorts = [
80
443
];
# QUIC
networking.firewall.allowedUDPPorts = [ 443 ];
# Sensible defaults for nginx
services.nginx = {
recommendedBrotliSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
recommendedSecurityHeaders = true;
# SSL config
sslCiphers = "EECDH+AESGCM:EDH+AESGCM:!aNULL";
sslDhparam = mkIf (config ? age) config.age.secrets."dhparams.pem".path;
commonHttpConfig = ''
log_format json_combined escape=json '{'
'"time": $msec,'
'"remote_addr":"$remote_addr",'
'"status":$status,'
'"method":"$request_method",'
'"host":"$host",'
'"uri":"$request_uri",'
'"request_size":$request_length,'
'"response_size":$body_bytes_sent,'
'"response_time":$request_time,'
'"referrer":"$http_referer",'
'"user_agent":"$http_user_agent"'
'}';
error_log syslog:server=unix:/dev/log,nohostname;
access_log syslog:server=unix:/dev/log,nohostname json_combined;
ssl_ecdh_curve secp384r1;
'';
# Default host that rejects everything.
# This is selected when no matching host is found for a request.
virtualHosts.dummy = {
default = true;
rejectSSL = true;
locations."/".extraConfig = ''
deny all;
'';
};
};
};
}