Server Default Settings

In the example server defined earlier there is a include statement to load various settings, which every website should use for enhanced performance and security.

1 # Common Server Settings
2 include     server-conf.d/*.conf;

Note

Some web applications like ownCloud might provide their own settings which may duplicate or even conflict with some of the settings defined here. In this case only some of the configuration files might be included individually.

Since the order in which these configurations are applied does matter, the files are numbered.

The configuration options are explained in the files comments

Server Security

In the file /etc/nginx/server-conf.d/10_server-security.conf we set various security related settings which every website should include..

 1#
 2# Default Server Security and Access Restrictions
 3#
 4
 5#
 6# Limit allowed HTTP methods
 7#
 8# Available methods:
 9#  GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND,
10#  PROPPATCH, LOCK, UNLOCK, or PATCH.
11#
12# Note that Nginx never allows the TRACE method (hard-coded)
13#
14# Only allow GET, HEAD and POST requests.
15#location ~ / {
16#    limit_except GET POST OPTIONS {
17#        deny all;
18#    }
19#}
20
21# Prevent clients from accessing (hidden) files starting with a dot
22# (i.e .htaccess, .htpasswd). Access to `/.well-known/` is allowed.
23location ~* /\.(?!well-known\/) {
24  deny all;
25}
26
27#
28# Prevent clients from accessing backup/config/source files
29location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
30    deny all;
31}

Client Security

In the file /etc/nginx/server-conf.d/20_client-security.conf we set various security related settings which every website should include..

 1#
 2# Default Client Security Settings
 3# For protection against click-jacking, cross-site-request-forgery (CSRF) and
 4# cross-site-scripting (XSS) protection
 5#
 6
 7# Tell clients not to load scripts and stylesheets unless the server indicates
 8# the correct MIME type, as files incorrectly detected as scripts or stylesheets
 9# may lead to XSS attacks.
10add_header  X-Content-Type-Options 'nosniff' always;
11
12# Tell clients not to render pages inside frames or iframes to avoid click-jacking.
13add_header  X-Frame-Options 'DENY' always;
14
15# Tell client to only send the 'Referer' header for resources on this same site.
16#add_header  Referrer-Policy 'same-origin' always;
17
18# Tell clients to never ever send the 'Referer' header.
19add_header  Referrer-Policy 'no-referrer' always;
20
21# Enable the Cross-site scripting (XSS) filter built into recent browsers.
22# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
23add_header  X-XSS-Protection '1; mode=block' always;
24
25# Force the latest IE version
26add_header  X-UA-Compatible 'IE=Edge' always;

Error Pages

The file /etc/nginx/server-conf.d/50_error-pages.conf defines a fallback error page for every HTTP client error (error-4xx.html) and HTTP server error (http-5xx.html). Individual error pages for specific errors will be delivered to clients if they exist (i.e. error-404.html).

  1#
  2# Nginx Error Pages
  3#
  4
  5#
  6# HTTP Client Errors
  7#
  8
  9# 400 Bad Request
 10# 401 Unauthorized (RFC 7235)
 11# 402 Payment Required
 12# 403 Forbidden
 13# 404 Not Found
 14# 406 Not Acceptable
 15# 407 Proxy Authentication Required (RFC 7235)
 16# 408 Request Time-out
 17# 409 Conflict
 18# 410 Gone
 19# 411 Length Required
 20# 412 Precondition Failed (RFC 7232)
 21# 413 Payload Too Large (RFC 7231)
 22# 414 URI Too Long (RFC 7231)
 23# 415 Unsupported Media Type
 24# 416 Range Not Satisfiable (RFC 7233)
 25# 417 Expectation Failed
 26# 418 I'm a teapot (RFC 2324)
 27# 421 Misdirected Request (RFC 7540)
 28# 422 Unprocessable Entity (WebDAV; RFC 4918)
 29# 423 Locked (WebDAV; RFC 4918)
 30# 424 Failed Dependency (WebDAV; RFC 4918)
 31# 426 Upgrade Required
 32# 428 Precondition Required (RFC 6585)
 33# 431 Request Header Fields Too Large (RFC 6585)
 34# 444 No Response (Nginx)
 35# 449 Retried after appropriate action (MS Exchange)
 36# 450 Blocked by Windows Parental Controls (Microsoft)
 37# 451 Unavailable For Legal Reasons (Fahrenheit 451)
 38# 495 SSL Certificate Error (Nginx)
 39# 496 SSL Certificate Required (Nginx)
 40# 497 HTTP Request Sent to HTTPS Port (Nginx)
 41# 499 Client Closed Request (Nginx, unsupported)
 42
 43error_page
 44    400 401 402 403 404 406 407 408 409 410
 45    411 412 413 414 415 416 417 418 421 422
 46    423 424 426 428 431 444 449 450 451 495
 47    496 497
 48    @http_error_4xx;
 49location @http_error_4xx {
 50    root /usr/local/share/nginx/http/error;
 51    allow all;
 52    ssi on;
 53    try_files $uri /error-$status.html /error-4xx.html =400;
 54}
 55
 56#
 57# Client Errors who need special handling
 58# Send additional headers etc.
 59
 60# 405 Method Not Allowed
 61error_page 405 @http_error_405;
 62location @http_error_405 {
 63    root /usr/local/share/nginx/http/error;
 64    allow all;
 65    ssi on;
 66    add_header Access-Control-Allow-Methods "GET, HEAD, POST" always;
 67    try_files $uri /error-405.html =405;
 68}
 69
 70# 429 Too Many Requests (RFC 6585)
 71error_page 429 @http_error_429;
 72location @http_error_429 {
 73    root /usr/local/share/nginx/http/error;
 74    allow all;
 75    ssi on;
 76    set $ip_req_rate_limit 100;
 77    set $ip_conn_limit 512;
 78    add_header X-RateLimit-Limit "100r/s" always;
 79    add_header Retry-After: 300 always;
 80    try_files $uri /error-429.html =429;
 81}
 82
 83
 84#
 85# HTTP Server Errors
 86#
 87
 88# 500 Internal Server Error
 89# 501 Not Implemented
 90# 502 Bad Gateway
 91# 504 Gateway Time-out
 92# 505 HTTP Version Not Supported
 93# 506 Variant Also Negotiates (RFC 2295)
 94# 507 Insufficient Storage (WebDAV; RFC 4918)
 95# 508 Loop Detected (WebDAV; RFC 5842)
 96# 509 Bandwidth Limit Exceeded (Apache Web Server/cPanel)
 97# 510 Not Extended (RFC 2774)
 98# 511 Network Authentication Required (RFC 6585)
 99# 520 Unknown Error (Cloudflare)
100# 521 Web Server Is Down (Cloudflare)
101# 522 Connection Timed Out (Cloudflare)
102# 523 Origin Is Unreachable (Cloudflare)
103# 524 A Timeout Occurred (Cloudflare)
104# 525 SSL Handshake Failed (Cloudflare)
105# 526 Invalid SSL Certificate (Cloudflare)
106# 527 Railgun Error (Cloudflare)
107# 599 Network connect timeout error
108error_page
109    500 501 502 504 505 506 507 508 509 510
110    511 520 521 522 523 524 525 526 527 599
111    @http_error_5xx;
112location @http_error_5xx {
113    root /usr/local/share/nginx/http/error;
114    allow all;
115    ssi on;
116    try_files $uri /error-$status.html /error-5xx.html =500;
117}
118
119#
120# Server Errors who need special handling
121# Send additional headers etc.
122
123# 503 Service Unavailable
124error_page 503 @http_error_503;
125location @http_error_503 {
126    root /usr/local/share/nginx/http/error;
127    allow all;
128    ssi on;
129    add_header Retry-After: 1800 always;
130    try_files $uri /error-503.html =503;
131}
132
133#
134# Location for assets included in error page (css, js, fonts, etc.)
135location ^~ /http_assets {
136    alias /usr/local/share/nginx/http/assets;
137    allow all;
138}

No Transform

The file /etc/nginx/server-conf.d/70_no_transform.conf.

 1#
 2# Note:
 3#   If you are using `ngx_pagespeed`, the the `Cache-Control: no-transform`
 4#   response header will prevent `PageSpeed` from rewriting `HTML` files, and,
 5#   if `pagespeedDisableRewriteOnNoTransform off` is not used, also from
 6#   rewriting other resources.
 7#
 8# https://developers.google.com/speed/pagespeed/module/configuration#notransform
 9
10# Prevent mobile network providers from modifying your site
11add_header  Cache-Control 'no-transform' always;

Browser Cache

The cache of our visitors web browsers is the best place to improve the website performance for our visitors and reduce the load on our servers.

We use file /etc/nginx/server-defaults/80_client-cache-control.conf to control what and how long is cached by our visitors browser cache.

 1#
 2# Client Cache Control
 3#
 4
 5#
 6# Expire rules for static content
 7# Do not use a default expire rule with nginx unless a site is completely static
 8
 9# cache.appcache, your document html and data
10location ~* \.(?:manifest|appcache|html?|xml|json)$ {
11    expires -1;
12}
13
14# Feed
15location ~* \.(?:rss|atom)$ {
16    expires 1h;
17    add_header Cache-Control "public";
18}
19
20# Compressed Media: images, icons, video, audio, HTC
21location ~* \.(?:jpg|jpeg|gif|png|gz|svgz|mp3|mp4|ogg|ogv|webm|htc)$ {
22    gzip off;
23    expires 1M;
24    add_header Cache-Control "public";
25}
26
27# Uncompressed Media: images, icons, video, audio, HTC
28location ~* \.(?:ico|cur|svg|webm|htc|mid|midi|wav|bmp)$ {
29    expires 1M;
30    add_header Cache-Control "public";
31}
32
33# CSS and Javascript
34location ~* \.(?:css|js)$ {
35    expires 1y;
36    add_header Cache-Control "public";
37}
38
39# WebFonts
40# If you are NOT using cross-domain-fonts, uncomment the following directive
41location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
42    expires 1y;
43    add_header Cache-Control "public";
44    add_header  Access-Control-Allow-Origin "*" ;
45}
46
47# Compressed Archives
48location ~* \.(?:zip|tgz|gz|rar|bz2|deb|rar)$ {
49    gzip off;
50    expires 1M;
51    add_header Cache-Control "public";
52}
53
54# Uncompressed Archives
55location ~* \.(?:tar|exe)$ {
56    expires 1M;
57    add_header Cache-Control "public";
58}
59
60# Documents
61location ~* \.(?:doc|xls|pfd|ppt|rtf|rst|tex)$ {
62    expires 1M;
63    add_header Cache-Control "public";
64}
65
66#
67# Filename-based cache busting
68# Route all requests for /css/style.20120716.css to /css/style.css
69# github.com/h5bp/html5-boilerplate/wiki/cachebusting
70#location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
71#    try_files $uri $1.$2;
72#}