···
1
+
{ config, lib, pkgs, ... }:
7
+
cfg = config.services.nginx;
9
+
defaultSSL = cfg.httpDefaultKey != null || cfg.httpDefaultCertificate != null;
11
+
validSSL = key: cert: cert != null && key != null || cert == null && key == null;
20
+
reverseProxies = mkOption {
21
+
type = types.attrsOf (types.submodule (
28
+
Exclude files and directories matching these patterns.
33
+
type = types.nullOr types.path;
36
+
Exclude files and directories matching these patterns.
40
+
certificate = mkOption {
41
+
type = types.nullOr types.path;
44
+
Exclude files and directories matching these patterns.
53
+
example = literalExample ''
55
+
"hydra.yourdomain.org" =
56
+
{ proxy = "localhost:3000";
57
+
key = "/etc/nixos/certs/hydra_key.key";
58
+
certificate = "/etc/nixos/certs/hydra_cert.crt";
64
+
A reverse proxy server configuration is created for every attribute.
65
+
The attribute name corresponds to the name the server is listening to,
66
+
and the proxy option defines the target to forward the requests to.
67
+
If a key and certificate are given, then the server is secured through
68
+
a SSL connection. Non-SSL requests on port 80 are automatically
69
+
re-directed to the SSL server on port 443.
73
+
httpDefaultKey = mkOption {
74
+
type = types.nullOr types.path;
76
+
example = "/etc/nixos/certs/defaut_key.key";
78
+
Key of SSL certificate for default server.
79
+
The default certificate is presented by the default server during
80
+
the SSL handshake when no specialized server configuration matches
82
+
A default SSL certificate is also helpful if browsers do not
83
+
support the TLS Server Name Indication extension (SNI, RFC 6066).
87
+
httpDefaultCertificate = mkOption {
88
+
type = types.nullOr types.path;
90
+
example = "/etc/nixos/certs/defaut_key.crt";
92
+
SSL certificate for default server.
93
+
The default certificate is presented by the default server during
94
+
the SSL handshake when no specialized server configuration matches
96
+
A default SSL certificate is also helpful if browsers do not
97
+
support the TLS Server Name Indication extension (SNI, RFC 6066).
106
+
config = mkIf (cfg.reverseProxies != {}) {
109
+
{ assertion = all id (mapAttrsToList (n: v: validSSL v.certificate v.key) cfg.reverseProxies);
111
+
One (or more) reverse proxy configurations specify only either
112
+
the key option or the certificate option. Both certificate
113
+
with associated key have to be configured to enable SSL for a
114
+
server configuration.
116
+
services.nginx.reverseProxies: ${toString cfg.reverseProxies}
119
+
{ assertion = validSSL cfg.httpDefaultCertificate cfg.httpDefaultKey;
121
+
The default server configuration specifies only either the key
122
+
option or the certificate option. Both httpDefaultCertificate
123
+
with associated httpDefaultKey have to be configured to enable
124
+
SSL for the default server configuration.
126
+
services.nginx.httpDefaultCertificate: ${toString cfg.httpDefaultCertificate}
128
+
services.nginx.httpDefaultKey : ${toString cfg.httpDefaultKey}
133
+
services.nginx.config = mkBefore ''
134
+
worker_processes 1;
135
+
error_log logs/error.log debug;
136
+
pid logs/nginx.pid;
138
+
worker_connections 1024;
142
+
services.nginx.httpConfig = mkBefore ''
143
+
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
144
+
'$status $body_bytes_sent "$http_referer" '
145
+
'"$http_user_agent" "$http_x_forwarded_for"';
146
+
access_log logs/access.log main;
149
+
keepalive_timeout 10;
152
+
${lib.optionalString defaultSSL ''
153
+
ssl_session_cache shared:SSL:10m;
154
+
ssl_session_timeout 10m;
155
+
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
156
+
ssl_ciphers HIGH:!aNULL:!MD5;
157
+
ssl_certificate ${cfg.httpDefaultCertificate};
158
+
ssl_certificate_key ${cfg.httpDefaultKey};
162
+
services.nginx.httpDefaultServer = mkBefore ''
163
+
# reject as default policy
165
+
listen 80 default_server;
166
+
listen [::]:80 default_server;
167
+
${lib.optionalString defaultSSL "listen 443 default_server ssl;"}
172
+
services.nginx.httpServers =
174
+
useSSL = certificate: key: certificate != null && key != null;
176
+
server = servername: proxy: certificate: key: useSSL: ''
178
+
server_name ${servername};
179
+
keepalive_timeout 70;
181
+
${if !useSSL then ''
186
+
ssl_session_cache shared:SSL:10m;
187
+
ssl_session_timeout 10m;
188
+
ssl_certificate ${certificate};
189
+
ssl_certificate_key ${key};
193
+
proxy_pass ${proxy};
195
+
### force timeouts if one of backend is dead ##
196
+
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
198
+
### Set headers ####
199
+
proxy_set_header Accept-Encoding "";
200
+
proxy_set_header Host $host;
201
+
proxy_set_header X-Real-IP $remote_addr;
202
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
204
+
${lib.optionalString useSSL ''
205
+
### Most PHP, Python, Rails, Java App can use this header ###
206
+
#proxy_set_header X-Forwarded-Proto https;##
208
+
proxy_set_header X-Forwarded-Proto $scheme;
209
+
add_header Front-End-Https on;
212
+
### By default we don't want to redirect it ####
213
+
proxy_redirect off;
214
+
proxy_buffering off;
218
+
${lib.optionalString useSSL ''
219
+
# redirect http to https
223
+
server_name ${servername};
224
+
return 301 https://$server_name$request_uri;
229
+
concatStrings (mapAttrsToList (n: v: server n v.proxy v.certificate v.key (useSSL v.proxy v.certificate)) cfg.reverseProxies);