Virtual Web Servers

Websites are defined in as “Servers” in Nginx and stored as configuration files in the directory /etc/nginx/servers-available.

They are not loaded automatically. To activate a server a symbolic link in the directory /etc/nginx/servers-enabled is created (See the main configuration file nginx.conf).

The only notable exception (the default server defined in /etc/nginx/http-conf.d/99_default-server.conf is always loaded).

Example Static Website

Along the way trough this documentation we will define many more websites for different purposes with a variating degree of complexity.

For the sake of a clear example, lets show a simple static website who just serves HTML documents from the directory /var/www/example.net/public_html/.

  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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#
# example.net Basic Static Website Example
#

# Unsecured HTTP Site and Aliases - Redirect to proper HTTPS Site
server {

    server_name example.net www.example.net;

    # IPv6 public global address
    listen      [2001:db8::11]:80 deferred;

    # IPv4 private local address
    listen      192.0.2.11:80 deferred;

    # IPv4 private address (Port-forwarded from NAT firewall/router)
    listen      192.0.2.10:80;

    # Redirect Tor Clients to our Tor Hidden Service
    if ($isTorExitNode = "true") {
        return  301 http://1234567890abcdef.onion$request_uri;
    }

    # Redirect to HTTPS on proper hostname
    return      301 https://$server_name$request_uri;
}

# Secured HTTPS Alias Servers - Redirect to proper HTTPS Server
server {

    server_name www.example.net;

    # IPv6 public global address
    listen      [2001:db8::11]:443 ssl http2;

    # IPv4 private local address
    listen      192.0.2.11:443 ssl http2;

    # IPv4 private address (Port-forwarded from NAT firewall/router)
    listen      192.0.2.10:443 ssl http2;

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

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

    # TLS certificate of signing CA (to validate OCSP response when stapling)
    ssl_trusted_certificate /etc/dehydrated/certs/example.net/chain.pem;

    # OCSP stapling response file (pre-generated)
    ssl_stapling_file       /etc/dehydrated/certs/example.net/ocsp_response.der;

    # TLS session cache (type:name:size)
    ssl_session_cache       shared:www.example.net:10m;

    # TLS session ticket keys (rotated every 8 hours, for 24 hours max.)
    ssl_session_ticket_key  tls_session_keys/www.example.net.1.key;
    ssl_session_ticket_key  tls_session_keys/www.example.net.2.key;
    ssl_session_ticket_key  tls_session_keys/www.example.net.3.key;

    # Strict Transport Security (HSTS)
    include     hsts.conf;

    # Redirect Tor Clients to our Tor Hidden Service
    if ($isTorExitNode = "true") {
        return  301 http://1234567890abcdef.onion$request_uri;
    }

    # Redirect to HTTPS on proper hostname
    return      301 https://example.net$request_uri;

}

# Secured HTTPS Server
server {

    server_name example.net;

    # IPv6 public global address
    listen      [2001:db8::11]:443 ssl http2 deferred;

    # IPv4 private local address
    listen      192.0.2.11:443 ssl http2 deferred;

    # IPv4 private address (Port-forwarded from NAT firewall/router)
    listen      192.0.2.10:443 ssl http2;

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

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

    # TLS certificate of signing CA (to validate OCSP response when stapling)
    ssl_trusted_certificate /etc/dehydrated/certs/example.net/chain.pem;

    # OCSP stapling response file (pre-generated)
    ssl_stapling_file       /etc/dehydrated/certs/example.net/ocsp_response.der;

    # TLS session cache (type:name:size)
    ssl_session_cache       shared:example.net:10m;

    # TLS session ticket keys (rotated every 8 hours, for 24 hours max.)
    ssl_session_ticket_key  tls_session_keys/example.net.1.key;
    ssl_session_ticket_key  tls_session_keys/example.net.2.key;
    ssl_session_ticket_key  tls_session_keys/example.net.3.key;

    # Strict Transport Security (HSTS)
    include     hsts.conf;

    # Content Security Policy (CSP) (line-breaks for readability, don't include them)
    add_header  Content-Security-Policy
        "default-src 'none';
         script-src 'none';
         style-src 'none';
         img-src 'none';
         font-src 'none';
         connect-src 'none';
         media-src 'none';
         object-src 'none';
         child-src 'none';
         worker-src 'none';
         frame-ancestors 'none';
         form-action 'none';
         upgrade-insecure-requests;
         block-all-mixed-content;
         reflected-xss block;
         base-uri https://example.net/;
         manifest-src 'none';
         referrer no-referrer; "
        always;

    # Redirect Tor Clients to our Tor Hidden Service
    if ($isTorExitNode = "true") {
        return  301 http://1234567890abcdef.onion$request_uri;
    }

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

    # Servers Public Documents Root
    root        /var/www/example.net/public_html;
}

# Tor Hidden Service
server {

    server_name 1234567890abcdef.onion;

    # IPv4 local address (forwarded from Tor hidden service)
    listen      127.0.0.11:80 deferred;

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

    # Content Security Policy (CSP) (line-breaks for readability, don't include them)
    add_header  Content-Security-Policy
        "default-src 'none';
         script-src 'none';
         style-src 'none';
         img-src 'none';
         font-src 'none';
         connect-src 'none';
         media-src 'none';
         object-src 'none';
         child-src 'none';
         worker-src 'none';
         frame-ancestors 'none';
         form-action 'none';
         reflected-xss block;
         base-uri http://1234567890abcdef.onion/;
         manifest-src 'none';
         referrer no-referrer; "
        always;

    # Servers Public Documents Root
    root        /var/www/example.net/public_html;
}

TLS Session Tickets Keys

Every server needs its own set of TLS session keys. The session keys are to be rotated every 12 hours, but remain valid for 36 hours.

As one might guess, we need a cron job.

tbd;