Global HTTP Settings

Following are the global HTTP server settings loaded from the /etc/nginx/http-conf.d/ directory.

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

The configuration options are explained in the files comments

TCP Options

The file /etc/nginx/http-conf.d/10_tcp-options.conf contains optimizations on the TCP/IP network level.

 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
#
# Nginx TCP network configuration
#

# Speed up file transfers by using sendfile() instead of read() and write().
# Default: off;
sendfile on;

# When set to a non-zero value, limits the amount of data that can be
# transferred in a single sendfile() call. Without the limit, one fast
# connection may seize the worker process entirely.
# Default: 0;
#sendfile_max_chunk  0;

# Increase throughput by sending full TCP packets with sendfile().
# Enables or disables the use of the TCP_CORK socket option on Linux.
# The options are enabled only when sendfile is used.
# Enabling the option allows sending the response header and the beginning of a
# file in one packet and sending a file in full packets.
# Default: off
tcp_nopush on;

# Enables or disables the use of the TCP_NODELAY option. The option is enabled
# only when a connection is transitioned into the keep-alive state.
# Allows to send out small stuff more quickly and conserving resources.
# Default: on
#tcp_nodelay on;

# Number and size of the buffers used for reading a response from a disk.
# # Set a large buffer ONLY if you set 'sendfile' to `off`
# Default: 1 32k;
#output_buffers 1 512k;

# Enable resetting timed out connections, thus freeing up RAM.
# TCP RST is sent to the client. Not valid for keep-alive connections.
# Default: Off;
reset_timedout_connection on;

HTTPS Options

The file /etc/nginx/http-conf.d/20_https-options.conf for global SSL/TLS settings.

 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
#
# TLS - Transport Layer Security (SSL)
#
# nginx/1.11.6
# OpenSSL 1.0.2g  1 Mar 2016


# Specifies the enabled ciphers. The ciphers are specified in the format
# understood by the OpenSSL library.
# Default: ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers
	'kEECDH+aECDSA+CHACHA20:kEECDH+aRSA+CHACHA20:kEDH+aRSA+CHACHA20:kEECDH+aECDSA+AESGCM:kEECDH+aRSA+AESGCM:kEDH+aRSA+AESGCM:kEECDH+aECDSA+AES:kEECDH+aRSA+AES:kEDH+aRSA+AES:-AESCCM:-AES256:+SHA1';

#
# Diffie-Hellman ephemeral key exchange parameters
# Specifies a file with DH parameters for DHE ciphers.
# Should be at least the size of the public RSA key
# Default: <not set>
ssl_dhparam /etc/ssl/dhparams/dh_4096.pem;

#
# The curve used for Elliptic Curve encryption.
# Specifies a curve for ECDHE ciphers.
# Default: ssl_ecdh_curve auto;
ssl_ecdh_curve secp384r1;

#
# Specifies that server ciphers should be preferred over client ciphers when
# using the SSLv3 and TLS protocols.
# Default: ssl_prefer_server_ciphers off;
ssl_prefer_server_ciphers on;

#
# Enables (or disables) the specified protocols.
# Don't use SSLv2 and SSLv3
# Default: ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

#
# Enables or disables session resumption through TLS session tickets (RFC5077).
# Default: ssl_session_tickets on;
#ssl_session_tickets on;

#
#   Optimize SSL by caching session parameters. This cuts down on
#   the number of expensive SSL handshakes. The handshake is the most
#   CPU-intensive operation, and by default it is re-negotiated on every
#   new/parallel connection.
#

# Time during which a client may reuse a cached TLS session without re-
# negotiation.
# Default:  ssl_session_timeout 5m;
ssl_session_timeout 1d;

#
# Further optimization can be achieved by raising keepalive_timeout.
# Time during which a client connection will stay open on the server side.
# The optional second parameter sets a value in the “Keep-Alive: timeout=time”
# response header field.
#
# Set in configuration file 20_limits.conf

Limits

The file /etc/nginx/http-conf.d/20_limits.conf can be used to set various network related limitations, like number of allowed connections per IP address or various buffer sizes. At this time we limit connections only and stick with Nginx default values for the rest.

  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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#
# Various Nginx Server Run-Time Limits
#

#
# Buffer Limits
#

# Buffer size for reading client request header,
# before the large_client_header_buffers is used.
# Default 1k
#client_header_buffer_size 1k;

# Maximum number and size allowed large client request headers,
# before a 414 (Request-URI Too Large) error is returned to the client.
#large_client_header_buffers 4 8k; # 32k total size

# Buffer size for reading client request bodies without saving to disk.
# Default: 16k
client_body_buffer_size   32k;

# Maximum allowed size of the client request body,
# before a 413 (Request Entity Too Large) error is returned to the client.
# Default: 1m
#client_max_body_size      1m;

# Sets the maximum size of chunks into which the response body is sliced. A too
# low value results in higher overhead. A too high value impairs prioritization
# due to HOL blocking (http://en.wikipedia.org/wiki/Head-of-line_blocking).
# Default: 8k
#http2_chunk_size 8k;

# Sets the size of the per worker input buffer.
# Default: 256k
#http2_recv_buffer_size 256k;


#
# Timeouts
#

# Maximum time between packets the client can pause when sending nginx any data
# Default: 60s
client_body_timeout 4s;

# Maximum time the client has to send the entire header to nginx
# Default: 60s
client_header_timeout 4s;

# Timeout which a single keep-alive client connection will stay open.
# Set this to the same as set 'ssl_session_timeout' to reduce the number of
# needed TLS handshakes. Second number sets what is sent to clients.
# Default: 75s
keepalive_timeout 1d 1d;

# Timeout for sending response to clients, before the connection is closed.
# Default: 60s
send_timeout 24s;

# Sets the timeout of inactivity after which the connection is closed.
# Default: 3m;
#http2_idle_timeout 3m;

# Sets the timeout for expecting more data from the client, after which the
# connection is closed.
# Default: 30s
#http2_recv_timeout 30s;


#
# Request Rate Limits
#

# Limit the rate of requests an IP can make over a certain time.
# Returns 503 (Service Temporarily Unavailable) error if clients sends to many
# requests too quickly.
# Default: none
limit_req_zone $binary_remote_addr zone=ip_req:10m rate=1000r/s;
limit_req_zone $server_name zone=server_req:10m rate=1000r/s;

# Sets the status code to return in response to rejected requests.
# Default: 503
limit_req_status 429;

# Enforce
limit_req zone=ip_req burst=50 nodelay;
limit_req zone=server_req burst=100;


#
# Response Rate Limits
#

# Rate of response transmission to a client in bytes per second (per request).
# Default: 0 (unlimited)
#limit_rate 0;

# Initial amount of data sent at an unlimited rate, before response rate
# limiting starts.
# Default: 0 (unlimited)
#limit_rate_after 0;


#
# Connection Limits
#

# Define zone for storing session states. Handles 16,000 sessions per MB
# Returns 503 (Service Temporarily Unavailable) error if storage is exhausted.
limit_conn_zone $binary_remote_addr zone=ip_conn:10m;

# Max. number of simultaneous connections per session (IP address)
limit_conn ip_conn 512;

# Logging level used for connection-limits ( info | notice | warn | error).
# Default: Error;
#limit_conn_log_level Error;

# Sets the status code to return in response to rejected requests.
# Default: 503 (Service Unavailable);
limit_conn_status 429; # (429 Too Many Requests)

# Max. requests through one keep-alive connection before it will be closed.
# Default: 100
#keepalive_requests       50;

# Allow a single range header for resumed downloads only.
# Stops large range header DoS attacks
# Default: unlimited
#max_ranges                1;

# Enables or disables adding comments to responses for MSIE clients with status
# greater than 400 to increase the response size to 512 bytes.
# Default: on
#msie_padding              off;

# Sets the maximum number of concurrent HTTP/2 streams in a connection.
# Default: 128
#http2_max_concurrent_streams 128;

Character-Sets and MIME-Types

The file /etc/nginx/http-conf.d/30_charsets.conf.

 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
#
# Nginx default MIME-types and character sets configuration
#

 # Define the MIME types for files.
include         mime.types;
default_type    application/octet-stream;

# Update charset_types due to updated mime.types
charset_types   text/xml
                text/plain
                text/vnd.wap.wml
                application/x-javascript
                application/rss+xml
                text/css
                application/javascript
                application/json;

# Adds the specified character set to the “Content-Type” response header field.
# Default: off
charset         utf-8;

# Defines the source character set of a response.
# Default: none
source_charset  utf-8;

HTTP Server Security

We group settings who affect the global HTTP server security in the file /etc/nginx/http-conf.d/30_http-server-security.conf.

 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
#
# Global HTTP Server Security and Access Restriction Settings
#

# Don't allow access to directory listing if there is no index document.
# Default: Off
#autoindex off;

# Don't send the Nginx version number in error pages and server header
# Default: on
server_tokens off;

# Set our own server token
more_set_headers	'Server: CERN/3.0 libwww/2.17'
#more_set_headers	'Server: NCSA HTTPd 1.5.2a';
#more_set_headers	'Server: Netscape-Enterprise/3.5.1';
#more_set_headers	'Server: Apache/1.3.0 (Unix) PHP/3.0 ';
#more_set_headers	'Server: Microsoft-IIS/6.0';

# Controls whether header fields with invalid names should be ignored. Valid
# names are composed of English letters, digits, hyphens, and possibly
# underscores (as controlled by the underscores_in_headers directive).
# Default: on
#ignore_invalid_headers on;

# Enables or disables the use of underscores in client request header fields.
# When the use of underscores is disabled, request header fields whose names
# contain underscores are marked as invalid and become subject to the
# 'ignore_invalid_headers' directive.
# Default: off
#underscores_in_headers off;

There will be more security settings in the individual virtual hosts later on.

Logging

Format

This sets the pretty much standard log format for websites.

Note that we don’t set what will be logged here in any way, but only how and where. More on this will follow later on.

File: /etc/nginx/http-conf.d/40_log-format.conf.

1
2
3
4
5
6
#
# Nginx Logging Configuration
#
log_format  main    '$remote_addr [$host] $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

Don’t Log Anything

File: /etc/nginx/http-conf.d/50_no-log.conf.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#
# Nginx Logging Configuration
#
# For debugging, include the following file in the server {} or location {} temporarely.
#   include log-debug.conf;
# and reload the nginx configuration (sudo sevice nginx reload):

# By default we do not log access
access_log off;
log_not_found off;
log_subrequest off;

# Default error log file
# Error log levels:
#   debug | info | notice | warn | error | crit | alert | emerg
#error_log  /dev/null emerg;
error_log /var/log/nginx/error.log crit;

Compression

Brötli Compression

The file /etc/nginx/http-conf.d/60_compression_brotli.conf.

 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
#
# Brötli Compression
#

# Enables or disables checking of the existence of pre-compressed files with.br
# extension. With the always value, pre-compressed file is used in all cases,
# without checking if the client supports it.
# Default: off
#brotli_static off;

# Enables or disables on-the-fly compression of responses.
# Default: off
brotli on;

# Enables on-the-fly compression of responses for the specified MIME types in
# addition to text/html. The special value * matches any MIME type. Responses
# with the text/html MIME type are always compressed.
# Default: text/html
brotli_types
	application/atom+xml
	application/javascript
	application/json
	application/rss+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/xml
	font/opentype
	image/svg+xml
	image/x-icon
	text/css
	text/plain
	text/x-component;

# Sets the number and size of buffers used to compress a response. By default,
# the buffer size is equal to one memory page. This is either 4k or 8k,
# depending on a platform.
# Default: 16 8k
#brotli_buffers 16 8k;

# Sets Brotli quality (compression) level. Acceptable values are in the range
# from 0 to 11.
# Default: 6
# brotli_comp_level 6;

# Sets Brotli window size. Acceptable values are
#   1k, 2k, 4k, 8k, 16k, 32k, 64k, 128k, 256k, 512k,
#   1m, 2m, 4m, 8m and 16m.
# Default: 512k
#brotli_window 512k;

# Sets the minimum length of a response that will be compressed. The length is
# determined only from the Content-Length response header field.
# Default: 20
#brotli_min_length 20

GZip Compression

The file /etc/nginx/http-conf.d/60_compression_gzip.conf.

  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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#
# Compression
#
# The ngx_http_gzip_module module is a filter that compresses responses using
# the “gzip” method. This often helps to reduce the size of transmitted data by
# half or even more.

# Enables or disables gzipping of responses.
# Default: off;
gzip on;

# Sets the number and size of buffers used to compress a response. By default,
# the buffer size is equal to one memory page. This is either 4K or 8K,
# depending on a platform.
# Default 32bit (i386): 32 4k
# Default 64bit (x64): 16 8k;
#gzip_buffers 16 8k;

# Sets a gzip compression level of a response. Acceptable values are in the
# range from 1 to 9.
# Default: 1
gzip_comp_level 5;

# Disables gzipping of responses for requests with “User-Agent” header fields
# matching any of the specified regular expressions.
# Default: <not set>
#gzip_disable msie6;

# Sets the minimum length of a response that will be gzipped. The length is
# determined only from the “Content-Length” response header field.
# Default: 20
#gzip_min_length 256;

# Sets the minimum HTTP version of a request required to compress a response.
# Default: 1.1
#gzip_http_version 1.1;

# Enables or disables gzipping of responses for proxied requests depending on
# the request and response.
# Default: off;
gzip_proxied any;

# Enables gzipping of responses for the specified MIME types in addition to
# “text/html”. The special value “*” matches any MIME type (0.8.29). Responses
# with the “text/html” type are always compressed.
# Default: text/html
gzip_types
    application/atom+xml
    application/javascript
    application/json
    application/rss+xml#
# Gzip Compression
#
# The ngx_http_gzip_module module is a filter that compresses responses using
# the “gzip” method. This often helps to reduce the size of transmitted data by
# half or even more.

# Enables or disables gzipping of responses.
# Default: off
gzip on;

# Sets the number and size of buffers used to compress a response. By default,
# the buffer size is equal to one memory page. This is either 4K or 8K,
# depending on a platform.
# Default: 16 8k;
#gzip_buffers 16 8k;

# Sets a gzip compression level of a response. Acceptable values are in the
# range from 1 to 9.
# 5 is a perfect compromise between size and cpu usage, offering about
# 75% reduction for most ascii files (almost identical to level 9).
# Default: 1;
gzip_comp_level 5;

# Disables gzipping of responses for requests with “User-Agent” header fields
# matching any of the specified regular expressions.
#
# The special mask “msie6” (0.7.12) corresponds to the regular expression “MSIE
# [4-6]\.”, but works faster. Starting from version 0.8.11, “MSIE 6.0; ... SV1”
# is excluded from this mask.
# Default: <unset>
 gzip_disable 'msie6';

#  Sets the minimum length of a response that will be gzipped. The length is
#  determined only from the “Content-Length” response header field.
#
# Don't compress anything that's already small and unlikely to shrink much
# if at all (the default is 20 bytes, which is bad as that usually leads to
# larger files after gzipping).
# Default: 20
#gzip_min_length 256;

# Sets the minimum HTTP version of a request required to compress a response.
# Default: 1.1
#gzip_http_version 1.1;

# Enables or disables gzipping of responses for proxied requests depending on
# the request and response. The fact that the request is proxied is determined
# by the presence of the “Via” request header field. The directive accepts
# multiple parameters:
#    off | expired | no-cache | no-store | private | no_last_modified |
#    no_etag | auth | any
#
# Compress data even for clients that are connecting to us via proxies,
# identified by the "Via" header (required for CloudFront).
# Default: off
gzip_proxied any;

# Enables gzipping of responses for the specified MIME types in addition to
# “text/html”. The special value “*” matches any MIME type.
# Responses with the “text/html” type are always compressed.
#
# Compress all output labeled with one of the following MIME-types.
# text/html is always compressed by HttpGzipModule
# Default: text/html;
gzip_types
    application/atom+xml
    application/javascript
    application/json
    application/rss+xml
    application/vnd.ms-fontobject
    application/x-font-ttf
    application/x-web-app-manifest+json
    application/xhtml+xml
    application/xml
    font/opentype
    image/svg+xml
    image/x-icon
    text/css
    text/plain
    text/x-component;

# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
gzip_vary on;

# This should be turned on if you are going to have pre-compressed copies
# (.gz) of static files available. If not it should be left off as it will
# cause extra I/O for the check. It is best if you enable this in a location{}
# block for a specific directory, or on an individual server{} level.
#gzip_static on;

    application/vnd.ms-fontobject
    application/x-font-ttf
    application/x-web-app-manifest+json
    application/xhtml+xml
    application/xml
    font/opentype
    image/svg+xml
    image/x-icon
    text/css
    text/plain
    text/x-component;

# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
gzip_vary on;

Open Files Cache

In the file /etc/nginx/http-conf.d/60_open-file-cache.conf we set how Nginx can cache files it has opened already to save disk operations while serving requests.

Configures a cache that can store:

  • open file descriptors, their sizes and modification times;

  • information on existence of directories;

  • file lookup errors, such as “file not found”, “no permission”, and so on.

 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
#
# Nginx Open Files Cache Configuration
#

# This tells Nginx to cache open file handles, "not found" errors, meta-data
# about files and their permissions, etc.
#
# The upside of this is that Nginx can immediately begin sending data when a
# popular file is requested, and will also know to immediately send a 404 if a
# file is missing on disk, and so on.
#
# However, it also means that the server won't react immediately to changes on
# disk, which may be undesirable.
#
# Production servers with stable file collections will definitely want to enable
# the cache.
#

# Maximum number of cached elements, before least used (LRU) element is removed;
# Time after which unused elements are removed from the cache (default 60s).
# Default: off;
open_file_cache         max=10000 inactive=30m;

# Also cache file lookup errors like "file not found".
# Default: off;
open_file_cache_errors  on;

# Number of times any item has to be accessed to remain in the cache as active.
# Default: 1;
#open_file_cache_min_uses  1;

# Sets a time after which open_file_cache elements should be re-validated.
# Default: 60s
open_file_cache_valid   30m;

PHP Backend

The file /etc/nginx/http-conf.d/70_php-backend.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#
# PHP FastCGI Process Manager (FPM)
#
upstream php-backend {

    # Unix Socket to PHP 7 FPM server
    server unix:/run/php/php7.0-fpm.sock;
}

# Number and size of the buffers used for reading a response from the
# FastCGI server.
# Default: 8 8k (1 system memory page size)
fastcgi_buffers 128 8k; # 1 MB total

FastCGI Cache

The file /etc/nginx/http-conf.d/90_fastcgi_cache.conf

 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
#
# fastcgi_cache Zones
# To be included outside outside of any "server" context.

# FastCGI cache settings for WordPress
fastcgi_cache_path
    /var/cache/nginx/wordpress_temp
    levels=1:2
    keys_zone=WORDPRESS:250m
    inactive=3M
    max_size=275m;

# FastCGI cache settings for ownCloud
# use to cache ownCloud gallery thumbnails
# https://doc.owncloud.org/server/8.2/admin_manual/configuration_server/performance_tuning/webserver_tips.html#nginx-caching-owncloud-gallery-thumbnails
fastcgi_cache_path
    /var/cache/nginx/owncloud_temp
    levels=1:2
    keys_zone=OWNCLOUD:100m
    inactive=60m;

# FastCGI cache settings for Wallabag
fastcgi_cache_path
    /var/cache/nginx/wallabag_temp
    levels=1:2
    keys_zone=WALLABAG:250m
    inactive=3M
    max_size=275m;

Tor Exit Nodes

The file /etc/nginx/http-conf.d/90_tor-exits-map.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#
# Define map of currently active Tor Exit Nodes
#

map_hash_max_size 4096;
map_hash_bucket_size 128;
map $remote_addr $isTorExitNode {

    default false;
    include tor-exit-nodes.map;
}

Default Server

The file /etc/nginx/conf.g/default.conf is installed with Nginx and usually serves a test page to show that the installation has been successful and the server is working.

However this should be changed immediately to something more useful and secure.

First I like to rename it to make its purpose easier recognizable:

$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/http-conf.d/99_default-site.conf

Then edit /etc/nginx/http-conf.d/99_default-server.conf as follows:

 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
#
# Default Server catch all requests ...
#  ... without hostname
#  ... with a numeric IP-Address as hostname
#  ... to any hostname not defined elsewhere
#

# Don't send HSTS and HKP headers, respect other/later servers on this dynamic
# address which do not have TLS/SSL enabled.
server {

    # IPv4 private address
    # Port-forwarded connections from firewall-router
    listen      192.0.2.10:80 deferred default_server bind;
    listen      192.0.2.10:443 ssl http2 deferred default_server bind;

    # Enable stapling of online certificate status protocol (OCSP) response
    include     ocsp-stapling.conf;

    # TLS certificate of signing CA (validate OCSP repsonse when stapling)
    ssl_trusted_certificate /etc/dehydrated/certs/default_server/chain.pem;

    # OCSP staping repsonse file (pre-generated)
    ssl_stapling_file       /etc/dehydrated/certs/default_server/ocsp_response.der;

    # TLS certificate (chained) and key
    ssl_certificate         /etc/dehydrated/certs/default_server/fullchain.pem;
    ssl_certificate_key     /etc/dehydrated/certs/default_server/privkey.pem;

    # TLS session cache (type:name:size)
    ssl_session_cache       shared:default_server:10m;

    # TLS session ticket key
    ssl_session_ticket_key  /etc/nginx/tls_session_keys/default_server.1.key;
    ssl_session_ticket_key  /etc/nginx/tls_session_keys/default_server.2.key;
    ssl_session_ticket_key  /etc/nginx/tls_session_keys/default_server.3.key;

    # Public Documents Root
    root        /var/www/default_site/public_html/;

    # Allow access for Let's Encrypt to domain validation tokens
    location /.well-known/acme-challenge {
        allow all;
    }

    location / {

        # Return nothing and close connection (useful against malware).
        return 444;
    }

    # Path, format, and configuration for buffered log writes
    access_log  /var/log/nginx/default-access.log main;
    log_not_found off;
    log_subrequest off;

}

This “website” has only one purpose. Immediately closing any connections made to it. Whatever is connecting to your IP address with HTTP or HTTPS, but does not know the name of any website actually hosted here (like www.example.net) can safely be assumed to be either a malicious bot or a script kiddie probing for security holes.

The certificate and key defined here, need not to be valid, as normal clients will never connect here.