mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-16 14:54:29 +01:00
Merge pull request #9103 from ts468/upstream.nginx
reverse_proxy module: helper to run nginx as reverse proxy
This commit is contained in:
commit
12d3de1caa
3 changed files with 263 additions and 2 deletions
|
@ -393,6 +393,7 @@
|
||||||
./services/web-servers/lighttpd/default.nix
|
./services/web-servers/lighttpd/default.nix
|
||||||
./services/web-servers/lighttpd/gitweb.nix
|
./services/web-servers/lighttpd/gitweb.nix
|
||||||
./services/web-servers/nginx/default.nix
|
./services/web-servers/nginx/default.nix
|
||||||
|
./services/web-servers/nginx/reverse_proxy.nix
|
||||||
./services/web-servers/phpfpm.nix
|
./services/web-servers/phpfpm.nix
|
||||||
./services/web-servers/shellinabox.nix
|
./services/web-servers/shellinabox.nix
|
||||||
./services/web-servers/tomcat.nix
|
./services/web-servers/tomcat.nix
|
||||||
|
|
|
@ -11,7 +11,9 @@ let
|
||||||
${cfg.config}
|
${cfg.config}
|
||||||
${optionalString (cfg.httpConfig != "") ''
|
${optionalString (cfg.httpConfig != "") ''
|
||||||
http {
|
http {
|
||||||
${cfg.httpConfig}
|
${cfg.httpConfig}
|
||||||
|
${cfg.httpServers}
|
||||||
|
${cfg.httpDefaultServer}
|
||||||
}
|
}
|
||||||
''}
|
''}
|
||||||
${cfg.appendConfig}
|
${cfg.appendConfig}
|
||||||
|
@ -60,7 +62,32 @@ in
|
||||||
httpConfig = mkOption {
|
httpConfig = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
description = "Configuration lines to be appended inside of the http {} block.";
|
description = ''
|
||||||
|
Configuration lines to be placed at the top inside of
|
||||||
|
the http {} block. The option is intended to be used for
|
||||||
|
the default configuration of the servers.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpServers = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Configuration lines to be placed inside of the http {}
|
||||||
|
block. The option is intended to be used for defining
|
||||||
|
individual servers.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpDefaultServer = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Configuration lines to be placed at the bottom inside of
|
||||||
|
the http {} block. The option is intended to be used for
|
||||||
|
setting up the default servers. The default server is used
|
||||||
|
if no previously specified server matches a request.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
stateDir = mkOption {
|
stateDir = mkOption {
|
||||||
|
|
233
nixos/modules/services/web-servers/nginx/reverse_proxy.nix
Normal file
233
nixos/modules/services/web-servers/nginx/reverse_proxy.nix
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.nginx;
|
||||||
|
|
||||||
|
defaultSSL = cfg.httpDefaultKey != null || cfg.httpDefaultCertificate != null;
|
||||||
|
|
||||||
|
validSSL = key: cert: cert != null && key != null || cert == null && key == null;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
|
||||||
|
reverseProxies = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule (
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
proxy = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Exclude files and directories matching these patterns.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Exclude files and directories matching these patterns.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
certificate = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Exclude files and directories matching these patterns.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
default = {};
|
||||||
|
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"hydra.yourdomain.org" =
|
||||||
|
{ proxy = "localhost:3000";
|
||||||
|
key = "/etc/nixos/certs/hydra_key.key";
|
||||||
|
certificate = "/etc/nixos/certs/hydra_cert.crt";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
description = ''
|
||||||
|
A reverse proxy server configuration is created for every attribute.
|
||||||
|
The attribute name corresponds to the name the server is listening to,
|
||||||
|
and the proxy option defines the target to forward the requests to.
|
||||||
|
If a key and certificate are given, then the server is secured through
|
||||||
|
a SSL connection. Non-SSL requests on port 80 are automatically
|
||||||
|
re-directed to the SSL server on port 443.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpDefaultKey = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/etc/nixos/certs/defaut_key.key";
|
||||||
|
description = ''
|
||||||
|
Key of SSL certificate for default server.
|
||||||
|
The default certificate is presented by the default server during
|
||||||
|
the SSL handshake when no specialized server configuration matches
|
||||||
|
a request.
|
||||||
|
A default SSL certificate is also helpful if browsers do not
|
||||||
|
support the TLS Server Name Indication extension (SNI, RFC 6066).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpDefaultCertificate = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/etc/nixos/certs/defaut_key.crt";
|
||||||
|
description = ''
|
||||||
|
SSL certificate for default server.
|
||||||
|
The default certificate is presented by the default server during
|
||||||
|
the SSL handshake when no specialized server configuration matches
|
||||||
|
a request.
|
||||||
|
A default SSL certificate is also helpful if browsers do not
|
||||||
|
support the TLS Server Name Indication extension (SNI, RFC 6066).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
config = mkIf (cfg.reverseProxies != {}) {
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{ assertion = all id (mapAttrsToList (n: v: validSSL v.certificate v.key) cfg.reverseProxies);
|
||||||
|
message = ''
|
||||||
|
One (or more) reverse proxy configurations specify only either
|
||||||
|
the key option or the certificate option. Both certificate
|
||||||
|
with associated key have to be configured to enable SSL for a
|
||||||
|
server configuration.
|
||||||
|
|
||||||
|
services.nginx.reverseProxies: ${toString cfg.reverseProxies}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{ assertion = validSSL cfg.httpDefaultCertificate cfg.httpDefaultKey;
|
||||||
|
message = ''
|
||||||
|
The default server configuration specifies only either the key
|
||||||
|
option or the certificate option. Both httpDefaultCertificate
|
||||||
|
with associated httpDefaultKey have to be configured to enable
|
||||||
|
SSL for the default server configuration.
|
||||||
|
|
||||||
|
services.nginx.httpDefaultCertificate: ${toString cfg.httpDefaultCertificate}
|
||||||
|
|
||||||
|
services.nginx.httpDefaultKey : ${toString cfg.httpDefaultKey}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.config = mkBefore ''
|
||||||
|
worker_processes 1;
|
||||||
|
error_log logs/error.log debug;
|
||||||
|
pid logs/nginx.pid;
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx.httpConfig = mkBefore ''
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
access_log logs/access.log main;
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
keepalive_timeout 10;
|
||||||
|
gzip on;
|
||||||
|
|
||||||
|
${lib.optionalString defaultSSL ''
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
ssl_certificate ${cfg.httpDefaultCertificate};
|
||||||
|
ssl_certificate_key ${cfg.httpDefaultKey};
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx.httpDefaultServer = mkBefore ''
|
||||||
|
# reject as default policy
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
${lib.optionalString defaultSSL "listen 443 default_server ssl;"}
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx.httpServers =
|
||||||
|
let
|
||||||
|
useSSL = certificate: key: certificate != null && key != null;
|
||||||
|
|
||||||
|
server = servername: proxy: certificate: key: useSSL: ''
|
||||||
|
server {
|
||||||
|
server_name ${servername};
|
||||||
|
keepalive_timeout 70;
|
||||||
|
|
||||||
|
${if !useSSL then ''
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
'' else ''
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
ssl_certificate ${certificate};
|
||||||
|
ssl_certificate_key ${key};
|
||||||
|
''}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass ${proxy};
|
||||||
|
|
||||||
|
### force timeouts if one of backend is dead ##
|
||||||
|
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||||
|
|
||||||
|
### Set headers ####
|
||||||
|
proxy_set_header Accept-Encoding "";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
|
||||||
|
${lib.optionalString useSSL ''
|
||||||
|
### Most PHP, Python, Rails, Java App can use this header ###
|
||||||
|
#proxy_set_header X-Forwarded-Proto https;##
|
||||||
|
#This is better##
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
add_header Front-End-Https on;
|
||||||
|
''}
|
||||||
|
|
||||||
|
### By default we don't want to redirect it ####
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${lib.optionalString useSSL ''
|
||||||
|
# redirect http to https
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name ${servername};
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
concatStrings (mapAttrsToList (n: v: server n v.proxy v.certificate v.key (useSSL v.proxy v.certificate)) cfg.reverseProxies);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue