2016-11-16 18:24:26 +00:00
|
|
|
{{ $cfg := .Cfg }}{{ $healthzURI := .HealthzURI }}{{ $backends := .Backends }}
|
2016-02-22 00:13:08 +00:00
|
|
|
daemon off;
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
worker_processes {{ $cfg.WorkerProcesses }};
|
2016-02-22 00:13:08 +00:00
|
|
|
pid /run/nginx.pid;
|
2017-01-19 02:31:33 +00:00
|
|
|
{{ if ne .MaxOpenFiles 0 }}
|
|
|
|
worker_rlimit_nofile {{ .MaxOpenFiles }};
|
|
|
|
{{ end}}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
|
|
|
events {
|
2016-03-22 18:01:04 +00:00
|
|
|
multi_accept on;
|
2016-11-16 18:24:26 +00:00
|
|
|
worker_connections {{ $cfg.MaxWorkerConnections }};
|
2016-03-22 18:01:04 +00:00
|
|
|
use epoll;
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
http {
|
2016-06-17 22:26:08 +00:00
|
|
|
{{/* we use the value of the header X-Forwarded-For to be able to use the geo_ip module */}}
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.UseProxyProtocol }}
|
2016-12-12 13:23:45 +00:00
|
|
|
set_real_ip_from {{ $cfg.ProxyRealIPCIDR }};
|
2016-07-05 16:37:54 +00:00
|
|
|
real_ip_header proxy_protocol;
|
|
|
|
{{ else }}
|
2016-06-17 22:26:08 +00:00
|
|
|
real_ip_header X-Forwarded-For;
|
|
|
|
set_real_ip_from 0.0.0.0/0;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-07-05 16:37:54 +00:00
|
|
|
|
2016-06-17 22:26:08 +00:00
|
|
|
real_ip_recursive on;
|
|
|
|
|
2016-05-30 18:44:02 +00:00
|
|
|
{{/* databases used to determine the country depending on the client IP address */}}
|
|
|
|
{{/* http://nginx.org/en/docs/http/ngx_http_geoip_module.html */}}
|
|
|
|
{{/* this is require to calculate traffic for individual country using GeoIP in the status page */}}
|
|
|
|
geoip_country /etc/nginx/GeoIP.dat;
|
|
|
|
geoip_city /etc/nginx/GeoLiteCity.dat;
|
2016-06-17 22:26:08 +00:00
|
|
|
geoip_proxy_recursive on;
|
2016-05-30 18:44:02 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.EnableVtsStatus }}
|
|
|
|
vhost_traffic_status_zone shared:vhost_traffic_status:{{ $cfg.VtsStatusZoneSize }};
|
2016-05-30 18:44:02 +00:00
|
|
|
vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-06-17 22:26:08 +00:00
|
|
|
# lua section to return proper error codes when custom pages are used
|
2016-03-15 02:29:13 +00:00
|
|
|
lua_package_path '.?.lua;./etc/nginx/lua/?.lua;/etc/nginx/lua/vendor/lua-resty-http/lib/?.lua;';
|
2016-09-29 15:02:45 +00:00
|
|
|
init_by_lua_block {
|
2016-02-22 00:13:08 +00:00
|
|
|
require("error_page")
|
|
|
|
}
|
|
|
|
|
2016-03-22 18:01:04 +00:00
|
|
|
sendfile on;
|
|
|
|
aio threads;
|
|
|
|
tcp_nopush on;
|
|
|
|
tcp_nodelay on;
|
|
|
|
|
|
|
|
log_subrequest on;
|
|
|
|
|
|
|
|
reset_timedout_connection on;
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
keepalive_timeout {{ $cfg.KeepAlive }}s;
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-10 22:56:29 +00:00
|
|
|
types_hash_max_size 2048;
|
2016-11-16 18:24:26 +00:00
|
|
|
server_names_hash_max_size {{ $cfg.ServerNameHashMaxSize }};
|
|
|
|
server_names_hash_bucket_size {{ $cfg.ServerNameHashBucketSize }};
|
|
|
|
map_hash_bucket_size {{ $cfg.MapHashBucketSize }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
|
|
|
include /etc/nginx/mime.types;
|
2016-04-02 20:41:41 +00:00
|
|
|
default_type text/html;
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.UseGzip }}
|
2016-02-22 00:13:08 +00:00
|
|
|
gzip on;
|
|
|
|
gzip_comp_level 5;
|
|
|
|
gzip_http_version 1.1;
|
|
|
|
gzip_min_length 256;
|
2016-11-16 18:24:26 +00:00
|
|
|
gzip_types {{ $cfg.GzipTypes }};
|
2016-02-22 00:13:08 +00:00
|
|
|
gzip_proxied any;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2017-01-20 21:53:32 +00:00
|
|
|
server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
log_format upstreaminfo '{{ if $cfg.UseProxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - '
|
2016-11-10 22:56:29 +00:00
|
|
|
'[$proxy_add_x_forwarded_for] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" '
|
2016-09-18 14:50:42 +00:00
|
|
|
'$request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status';
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-06-18 22:04:07 +00:00
|
|
|
{{/* map urls that should not appear in access.log */}}
|
|
|
|
{{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}}
|
|
|
|
map $request $loggable {
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ range $reqUri := $cfg.SkipAccessLogURLs }}
|
2016-06-18 22:04:07 +00:00
|
|
|
{{ $reqUri }} 0;{{ end }}
|
|
|
|
default 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
access_log /var/log/nginx/access.log upstreaminfo if=$loggable;
|
2016-11-16 18:24:26 +00:00
|
|
|
error_log /var/log/nginx/error.log {{ $cfg.ErrorLogLevel }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-12-22 03:00:27 +00:00
|
|
|
{{ buildResolvers $cfg.Resolver }}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-09-29 21:42:46 +00:00
|
|
|
{{/* Whenever nginx proxies a request without a "Connection" header, the "Connection" header is set to "close" */}}
|
|
|
|
{{/* when making the target request. This means that you cannot simply use */}}
|
|
|
|
{{/* "proxy_set_header Connection $http_connection" for WebSocket support because in this case, the */}}
|
|
|
|
{{/* "Connection" header would be set to "" whenever the original request did not have a "Connection" header, */}}
|
|
|
|
{{/* which would mean no "Connection" header would be in the target request. Since this would deviate from */}}
|
|
|
|
{{/* normal nginx behavior we have to use this approach. */}}
|
|
|
|
# Retain the default nginx handling of requests without a "Connection" header
|
2016-02-22 00:13:08 +00:00
|
|
|
map $http_upgrade $connection_upgrade {
|
2016-11-16 18:24:26 +00:00
|
|
|
default upgrade;
|
|
|
|
'' close;
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# trust http_x_forwarded_proto headers correctly indicate ssl offloading
|
2016-03-26 21:25:51 +00:00
|
|
|
map $http_x_forwarded_proto $pass_access_scheme {
|
2016-11-16 18:24:26 +00:00
|
|
|
default $http_x_forwarded_proto;
|
|
|
|
'' $scheme;
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
2016-12-26 13:56:22 +00:00
|
|
|
map $http_x_forwarded_port $pass_server_port {
|
|
|
|
default $http_x_forwarded_port;
|
|
|
|
'' $server_port;
|
|
|
|
}
|
|
|
|
|
|
|
|
# map port 442 to 443 for header X-Forwarded-Port
|
|
|
|
map $pass_server_port $pass_port {
|
|
|
|
442 443;
|
|
|
|
default $pass_server_port;
|
|
|
|
}
|
|
|
|
|
2016-02-22 00:13:08 +00:00
|
|
|
# Map a response error watching the header Content-Type
|
|
|
|
map $http_accept $httpAccept {
|
|
|
|
default html;
|
|
|
|
application/json json;
|
|
|
|
application/xml xml;
|
|
|
|
text/plain text;
|
|
|
|
}
|
|
|
|
|
|
|
|
map $httpAccept $httpReturnType {
|
|
|
|
default text/html;
|
|
|
|
json application/json;
|
|
|
|
xml application/xml;
|
|
|
|
text text/plain;
|
|
|
|
}
|
|
|
|
|
|
|
|
server_name_in_redirect off;
|
2016-11-16 18:24:26 +00:00
|
|
|
port_in_redirect off;
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
ssl_protocols {{ $cfg.SSLProtocols }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
|
|
|
# turn on session caching to drastically improve performance
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.SSLSessionCache }}
|
|
|
|
ssl_session_cache builtin:1000 shared:SSL:{{ $cfg.SSLSessionCacheSize }};
|
|
|
|
ssl_session_timeout {{ $cfg.SSLSessionTimeout }};
|
2016-02-22 00:13:08 +00:00
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
# allow configuring ssl session tickets
|
2016-11-16 18:24:26 +00:00
|
|
|
ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
|
|
|
# slightly reduce the time-to-first-byte
|
2016-11-16 18:24:26 +00:00
|
|
|
ssl_buffer_size {{ $cfg.SSLBufferSize }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if not (empty $cfg.SSLCiphers) }}
|
2016-02-22 00:13:08 +00:00
|
|
|
# allow configuring custom ssl ciphers
|
2016-11-16 18:24:26 +00:00
|
|
|
ssl_ciphers '{{ $cfg.SSLCiphers }}';
|
2016-02-22 00:13:08 +00:00
|
|
|
ssl_prefer_server_ciphers on;
|
|
|
|
{{ end }}
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if not (empty $cfg.SSLDHParam) }}
|
2016-02-22 00:13:08 +00:00
|
|
|
# allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
|
2016-11-16 18:24:26 +00:00
|
|
|
ssl_dhparam {{ $cfg.SSLDHParam }};
|
2016-02-22 00:13:08 +00:00
|
|
|
{{ end }}
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if not $cfg.EnableDynamicTLSRecords }}
|
2016-06-18 21:03:27 +00:00
|
|
|
ssl_dyn_rec_size_lo 0;
|
|
|
|
{{ end }}
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if .CustomErrors }}
|
2016-03-15 15:31:39 +00:00
|
|
|
# Custom error pages
|
2016-02-22 00:13:08 +00:00
|
|
|
proxy_intercept_errors on;
|
2016-06-01 14:39:12 +00:00
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ range $errCode := $cfg.CustomHTTPErrors }}
|
2016-06-01 14:39:12 +00:00
|
|
|
error_page {{ $errCode }} = @custom_{{ $errCode }};{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
|
|
|
|
# In case of errors try the next upstream server before returning an error
|
2016-11-16 18:24:26 +00:00
|
|
|
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504{{ if $cfg.RetryNonIdempotent }} non_idempotent{{ end }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{range $name, $upstream := $backends}}
|
2016-03-15 15:31:39 +00:00
|
|
|
upstream {{$upstream.Name}} {
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.EnableStickySessions }}
|
2016-04-28 04:03:59 +00:00
|
|
|
sticky hash=sha1 httponly;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ else }}
|
2016-03-15 15:31:39 +00:00
|
|
|
least_conn;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-11-11 23:43:35 +00:00
|
|
|
{{ range $server := $upstream.Endpoints }}server {{ $server.Address }}:{{ $server.Port }} max_fails={{ $server.MaxFails }} fail_timeout={{ $server.FailTimeout }};
|
2016-04-28 04:03:59 +00:00
|
|
|
{{ end }}
|
2016-03-15 15:31:39 +00:00
|
|
|
}
|
2016-05-16 20:29:33 +00:00
|
|
|
{{ end }}
|
2016-03-15 15:31:39 +00:00
|
|
|
|
2016-05-27 21:03:54 +00:00
|
|
|
{{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}}
|
|
|
|
{{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}}
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ range $zone := (buildRateLimitZones .Servers) }}
|
2016-05-27 21:03:54 +00:00
|
|
|
{{ $zone }}
|
|
|
|
{{ end }}
|
|
|
|
|
2017-01-19 02:04:00 +00:00
|
|
|
{{ $backlogSize := .BacklogSize }}
|
2016-11-28 22:26:09 +00:00
|
|
|
{{ range $index, $server := .Servers }}
|
2016-03-15 02:29:13 +00:00
|
|
|
server {
|
2016-11-16 18:24:26 +00:00
|
|
|
server_name {{ $server.Hostname }};
|
2017-01-19 02:04:00 +00:00
|
|
|
listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $index 0 }} ipv6only=off{{end}}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}};
|
2016-12-22 13:03:58 +00:00
|
|
|
{{/* Listen on 442 because port 443 is used in the stream section */}}
|
2016-11-23 23:22:29 +00:00
|
|
|
{{ if not (empty $server.SSLCertificate) }}listen 442 {{ if $cfg.UseProxyProtocol }}proxy_protocol{{ end }} ssl {{ if $cfg.UseHTTP2 }}http2{{ end }};
|
2016-05-24 14:02:29 +00:00
|
|
|
{{/* comment PEM sha is required to detect changes in the generated configuration and force a reload */}}
|
2016-09-29 15:02:45 +00:00
|
|
|
# PEM sha: {{ $server.SSLPemChecksum }}
|
2016-11-10 22:56:29 +00:00
|
|
|
ssl_certificate {{ $server.SSLCertificate }};
|
|
|
|
ssl_certificate_key {{ $server.SSLCertificate }};
|
|
|
|
{{ end }}
|
2016-12-22 13:03:58 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if (and (not (empty $server.SSLCertificate)) $cfg.HSTS) }}
|
|
|
|
more_set_headers "Strict-Transport-Security: max-age={{ $cfg.HSTSMaxAge }}{{ if $cfg.HSTSIncludeSubdomains }}; includeSubDomains{{ end }}; preload";
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-04-02 20:41:41 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.EnableVtsStatus }}vhost_traffic_status_filter_by_set_key $geoip_country_code country::$server_name;{{ end }}
|
2016-05-30 18:44:02 +00:00
|
|
|
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ range $location := $server.Locations }}
|
2016-06-01 14:39:12 +00:00
|
|
|
{{ $path := buildLocation $location }}
|
2016-08-19 14:51:40 +00:00
|
|
|
{{ $authPath := buildAuthLocation $location }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
|
|
|
{{ if not (empty $location.CertificateAuth.CertFileName) }}
|
|
|
|
# PEM sha: {{ $location.CertificateAuth.PemSHA }}
|
|
|
|
ssl_client_certificate {{ $location.CertificateAuth.CAFileName }};
|
|
|
|
ssl_verify_client on;
|
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
{{ if not (empty $authPath) }}
|
2016-08-19 14:51:40 +00:00
|
|
|
location = {{ $authPath }} {
|
|
|
|
internal;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ if not $location.ExternalAuth.SendBody }}
|
2016-08-19 14:51:40 +00:00
|
|
|
proxy_pass_request_body off;
|
|
|
|
proxy_set_header Content-Length "";
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
|
|
|
{{ if not (empty $location.ExternalAuth.Method) }}
|
|
|
|
proxy_method {{ $location.ExternalAuth.Method }};
|
|
|
|
{{ end }}
|
2016-08-19 14:51:40 +00:00
|
|
|
proxy_set_header Host $host;
|
|
|
|
proxy_pass_request_headers on;
|
2016-11-10 22:56:29 +00:00
|
|
|
set $target {{ $location.ExternalAuth.URL }};
|
|
|
|
proxy_pass $target;
|
2016-08-19 14:51:40 +00:00
|
|
|
}
|
|
|
|
{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
2016-05-27 14:58:13 +00:00
|
|
|
location {{ $path }} {
|
2016-12-29 20:02:06 +00:00
|
|
|
{{ if isLocationAllowed $location }}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ if gt (len $location.Whitelist.CIDR) 0 }}
|
|
|
|
{{ range $ip := $location.Whitelist.CIDR }}
|
2016-06-06 18:31:40 +00:00
|
|
|
allow {{ $ip }};{{ end }}
|
|
|
|
deny all;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
{{ if not (empty $authPath) }}
|
2016-08-19 14:51:40 +00:00
|
|
|
# this location requires authentication
|
|
|
|
auth_request {{ $authPath }};
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if (and (not (empty $server.SSLCertificate)) $location.Redirect.SSLRedirect) }}
|
2016-06-05 14:19:55 +00:00
|
|
|
# enforce ssl on server side
|
|
|
|
if ($scheme = http) {
|
|
|
|
return 301 https://$host$request_uri;
|
|
|
|
}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-05-30 17:39:10 +00:00
|
|
|
{{/* if the location contains a rate limit annotation, create one */}}
|
|
|
|
{{ $limits := buildRateLimit $location }}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ range $limit := $limits }}
|
2016-05-30 17:39:10 +00:00
|
|
|
{{ $limit }}{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
|
|
|
{{ if $location.BasicDigestAuth.Secured }}
|
|
|
|
{{ if eq $location.BasicDigestAuth.Type "basic" }}
|
|
|
|
auth_basic "{{ $location.BasicDigestAuth.Realm }}";
|
|
|
|
auth_basic_user_file {{ $location.BasicDigestAuth.File }};
|
2016-05-31 16:22:04 +00:00
|
|
|
{{ else }}
|
2016-11-10 22:56:29 +00:00
|
|
|
auth_digest "{{ $location.BasicDigestAuth.Realm }}";
|
|
|
|
auth_digest_user_file {{ $location.BasicDigestAuth.File }};
|
|
|
|
{{ end }}
|
2016-07-18 02:02:02 +00:00
|
|
|
proxy_set_header Authorization "";
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
|
|
|
|
|
|
|
{{ if $location.EnableCORS }}
|
2016-09-22 18:00:09 +00:00
|
|
|
{{ template "CORS" }}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-12-22 13:03:58 +00:00
|
|
|
|
2017-01-20 21:53:32 +00:00
|
|
|
client_max_body_size "{{ $location.Proxy.BodySize }}";
|
|
|
|
|
2016-03-22 18:01:04 +00:00
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
|
|
|
# Pass Real IP
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
|
|
|
|
|
|
# Allow websocket connections
|
|
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
|
|
proxy_set_header Connection $connection_upgrade;
|
|
|
|
|
2016-03-29 23:30:44 +00:00
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
2016-03-22 18:01:04 +00:00
|
|
|
proxy_set_header X-Forwarded-Host $host;
|
2016-12-22 13:03:58 +00:00
|
|
|
proxy_set_header X-Forwarded-Port $pass_port;
|
2016-03-26 21:25:51 +00:00
|
|
|
proxy_set_header X-Forwarded-Proto $pass_access_scheme;
|
2016-03-22 18:01:04 +00:00
|
|
|
|
2016-07-20 13:55:46 +00:00
|
|
|
# mitigate HTTPoxy Vulnerability
|
|
|
|
# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
|
|
|
|
proxy_set_header Proxy "";
|
|
|
|
|
2016-11-10 22:56:29 +00:00
|
|
|
proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s;
|
|
|
|
proxy_send_timeout {{ $location.Proxy.SendTimeout }}s;
|
|
|
|
proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s;
|
2016-03-22 18:01:04 +00:00
|
|
|
|
|
|
|
proxy_redirect off;
|
|
|
|
proxy_buffering off;
|
2016-11-10 22:56:29 +00:00
|
|
|
proxy_buffer_size "{{ $location.Proxy.BufferSize }}";
|
2016-03-22 18:01:04 +00:00
|
|
|
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
|
2016-05-27 14:58:13 +00:00
|
|
|
{{/* rewrite only works if the content is not compressed */}}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ if $location.Redirect.AddBaseURL }}
|
2016-05-27 14:58:13 +00:00
|
|
|
proxy_set_header Accept-Encoding "";
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-05-27 14:58:13 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
set $proxy_upstream_name "{{ $location.Backend }}";
|
|
|
|
{{ buildProxyPass $backends $location }}
|
2016-12-29 20:02:06 +00:00
|
|
|
{{ else }}
|
|
|
|
#{{ $location.Denied }}
|
|
|
|
return 503;
|
|
|
|
{{ end }}
|
2016-03-15 15:31:39 +00:00
|
|
|
}
|
|
|
|
{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if eq $server.Hostname "_" }}
|
2016-09-16 21:23:52 +00:00
|
|
|
# health checks in cloud providers require the use of port 80
|
2016-11-16 18:24:26 +00:00
|
|
|
location {{ $healthzURI }} {
|
2016-09-16 21:23:52 +00:00
|
|
|
access_log off;
|
|
|
|
return 200;
|
|
|
|
}
|
|
|
|
|
2016-04-05 18:15:59 +00:00
|
|
|
# this is required to avoid error if nginx is being monitored
|
|
|
|
# with an external software (like sysdig)
|
|
|
|
location /nginx_status {
|
|
|
|
allow 127.0.0.1;
|
2016-12-29 20:02:06 +00:00
|
|
|
allow ::1;
|
2016-04-05 18:15:59 +00:00
|
|
|
deny all;
|
|
|
|
|
|
|
|
access_log off;
|
|
|
|
stub_status on;
|
|
|
|
}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-11-16 18:24:26 +00:00
|
|
|
|
2016-03-19 20:17:58 +00:00
|
|
|
{{ template "CUSTOM_ERRORS" $cfg }}
|
2016-03-15 15:31:39 +00:00
|
|
|
}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
2016-03-15 15:31:39 +00:00
|
|
|
{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
2016-07-21 15:40:47 +00:00
|
|
|
# default server, used for NGINX healthcheck and access to nginx stats
|
2016-02-22 00:13:08 +00:00
|
|
|
server {
|
2016-07-21 15:40:47 +00:00
|
|
|
# Use the port 18080 (random value just to avoid known ports) as default port for nginx.
|
|
|
|
# Changing this value requires a change in:
|
|
|
|
# https://github.com/kubernetes/contrib/blob/master/ingress/controllers/nginx/nginx/command.go#L104
|
2016-11-28 22:26:09 +00:00
|
|
|
listen [::]:18080 ipv6only=off default_server reuseport backlog={{ .BacklogSize }};
|
2016-02-22 00:13:08 +00:00
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
location {{ $healthzURI }} {
|
2016-02-22 00:13:08 +00:00
|
|
|
access_log off;
|
|
|
|
return 200;
|
|
|
|
}
|
2016-03-15 15:31:39 +00:00
|
|
|
|
2016-03-26 21:25:51 +00:00
|
|
|
location /nginx_status {
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.EnableVtsStatus }}
|
2016-03-26 21:25:51 +00:00
|
|
|
vhost_traffic_status_display;
|
|
|
|
vhost_traffic_status_display_format html;
|
|
|
|
{{ else }}
|
2016-03-22 18:01:04 +00:00
|
|
|
access_log off;
|
2016-02-22 00:13:08 +00:00
|
|
|
stub_status on;
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 01:39:17 +00:00
|
|
|
# this location is used to extract nginx metrics
|
|
|
|
# using prometheus.
|
|
|
|
# TODO: enable extraction for vts module.
|
|
|
|
location /internal_nginx_status {
|
|
|
|
allow 127.0.0.1;
|
2016-12-29 20:02:06 +00:00
|
|
|
allow ::1;
|
2016-11-29 01:39:17 +00:00
|
|
|
deny all;
|
|
|
|
|
|
|
|
access_log off;
|
|
|
|
stub_status on;
|
|
|
|
}
|
|
|
|
|
2016-02-22 00:13:08 +00:00
|
|
|
location / {
|
2016-09-29 15:02:45 +00:00
|
|
|
set $proxy_upstream_name "upstream-default-backend";
|
2016-03-19 20:17:58 +00:00
|
|
|
proxy_pass http://upstream-default-backend;
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ template "CUSTOM_ERRORS" $cfg }}
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
2016-03-16 14:12:45 +00:00
|
|
|
|
|
|
|
# default server for services without endpoints
|
|
|
|
server {
|
2016-03-19 23:29:29 +00:00
|
|
|
listen 8181;
|
2016-09-29 15:02:45 +00:00
|
|
|
set $proxy_upstream_name "-";
|
2016-03-16 14:12:45 +00:00
|
|
|
|
|
|
|
location / {
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if .CustomErrors }}
|
2016-03-16 14:12:45 +00:00
|
|
|
content_by_lua_block {
|
2016-03-19 20:17:58 +00:00
|
|
|
openURL(503)
|
2016-03-16 14:12:45 +00:00
|
|
|
}
|
2016-05-23 23:15:13 +00:00
|
|
|
{{ else }}
|
|
|
|
return 503;
|
|
|
|
{{ end }}
|
2016-09-29 15:02:45 +00:00
|
|
|
}
|
2016-09-29 19:01:09 +00:00
|
|
|
}
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stream {
|
2016-11-10 22:56:29 +00:00
|
|
|
# map FQDN that requires SSL passthrough
|
|
|
|
map $ssl_preread_server_name $stream_upstream {
|
2016-12-29 22:57:51 +00:00
|
|
|
{{ range $i, $passthrough := .PassthroughBackends }}
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ $passthrough.Hostname }} {{ $passthrough.Backend }};
|
2016-11-10 22:56:29 +00:00
|
|
|
{{ end }}
|
|
|
|
# send SSL traffic to this nginx in a different port
|
|
|
|
default nginx-ssl-backend;
|
|
|
|
}
|
|
|
|
|
2016-11-16 18:24:26 +00:00
|
|
|
log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$stream_upstream] $status $bytes_sent $bytes_received $session_time';
|
2016-11-10 22:56:29 +00:00
|
|
|
|
|
|
|
access_log /var/log/nginx/access.log log_stream;
|
|
|
|
error_log /var/log/nginx/error.log;
|
|
|
|
|
|
|
|
# configure default backend for SSL
|
|
|
|
upstream nginx-ssl-backend {
|
|
|
|
server 127.0.0.1:442;
|
|
|
|
}
|
|
|
|
|
2016-12-29 22:57:51 +00:00
|
|
|
{{ buildSSPassthroughUpstreams $backends .PassthroughBackends }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
|
|
|
server {
|
2016-11-28 22:26:09 +00:00
|
|
|
listen [::]:443 ipv6only=off;
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ if $cfg.UseProxyProtocol }}proxy_protocol on;{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
proxy_pass $stream_upstream;
|
|
|
|
ssl_preread on;
|
|
|
|
}
|
2017-01-09 00:31:16 +00:00
|
|
|
|
|
|
|
{{ buildStreamUpstreams "tcp" $backends .TCPBackends }}
|
|
|
|
|
|
|
|
{{ buildStreamUpstreams "udp" $backends .UDPBackends }}
|
|
|
|
|
|
|
|
# TCP services
|
|
|
|
{{ range $i, $tcpServer := .TCPBackends }}
|
|
|
|
server {
|
|
|
|
listen {{ $tcpServer.Path }};
|
|
|
|
proxy_pass tcp-{{ $tcpServer.Backend }};
|
|
|
|
}
|
|
|
|
{{ end }}
|
2016-11-10 22:56:29 +00:00
|
|
|
|
2017-01-09 00:31:16 +00:00
|
|
|
# UDP services
|
|
|
|
{{ range $i, $udpServer := .UDPBackends }}
|
|
|
|
server {
|
|
|
|
listen {{ $udpServer.Path }} udp;
|
|
|
|
proxy_responses 1;
|
|
|
|
proxy_pass udp-{{ $udpServer.Backend }};
|
|
|
|
}
|
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{{/* definition of templates to avoid repetitions */}}
|
|
|
|
{{ define "CUSTOM_ERRORS" }}
|
2016-11-16 18:24:26 +00:00
|
|
|
{{ range $errCode := .CustomHTTPErrors }}
|
2016-05-23 23:15:13 +00:00
|
|
|
location @custom_{{ $errCode }} {
|
2016-03-22 18:01:04 +00:00
|
|
|
internal;
|
2016-02-22 00:13:08 +00:00
|
|
|
content_by_lua_block {
|
2016-05-23 23:15:13 +00:00
|
|
|
openURL({{ $errCode }})
|
2016-02-22 00:13:08 +00:00
|
|
|
}
|
2016-05-23 23:15:13 +00:00
|
|
|
}
|
|
|
|
{{ end }}
|
2016-02-22 00:13:08 +00:00
|
|
|
{{ end }}
|
2016-09-22 18:00:09 +00:00
|
|
|
|
|
|
|
{{/* CORS support from https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}}
|
|
|
|
{{ define "CORS" }}
|
|
|
|
if ($request_method = 'OPTIONS') {
|
|
|
|
add_header 'Access-Control-Allow-Origin' '*';
|
|
|
|
#
|
|
|
|
# Om nom nom cookies
|
|
|
|
#
|
|
|
|
add_header 'Access-Control-Allow-Credentials' 'true';
|
|
|
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
|
|
|
#
|
|
|
|
# Custom headers and headers various browsers *should* be OK with but aren't
|
|
|
|
#
|
|
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
|
|
|
#
|
|
|
|
# Tell client that this pre-flight info is valid for 20 days
|
|
|
|
#
|
|
|
|
add_header 'Access-Control-Max-Age' 1728000;
|
|
|
|
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
|
|
|
add_header 'Content-Length' 0;
|
|
|
|
return 204;
|
|
|
|
}
|
|
|
|
if ($request_method = 'POST') {
|
|
|
|
add_header 'Access-Control-Allow-Origin' '*';
|
|
|
|
add_header 'Access-Control-Allow-Credentials' 'true';
|
|
|
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
|
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
|
|
|
}
|
|
|
|
if ($request_method = 'GET') {
|
|
|
|
add_header 'Access-Control-Allow-Origin' '*';
|
|
|
|
add_header 'Access-Control-Allow-Credentials' 'true';
|
|
|
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
|
|
|
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
|
|
|
}
|
|
|
|
{{ end }}
|