-
Notifications
You must be signed in to change notification settings - Fork 4
/
app-specific.conf
175 lines (148 loc) · 8.22 KB
/
app-specific.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# App-specific config file located at /etc/nginx/sites-available/app-name.conf
# References:
#
# https://github.com/dreamerslab/nodejs.production/blob/master/multi_instance/nginx/vhost.conf
# https://www.digitalocean.com/community/tutorials/how-to-deploy-a-meteor-js-application-on-ubuntu-14-04-with-nginx
# http://aws.amazon.com/articles/1233/
# https://gist.github.com/plentz/6737338
# http://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.pdf
# https://gist.github.com/mtigas/8601685
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# Set of upstream servers the reverse proxy. Define multiple servers here if
# setting up a horizontal-scaling load-balanced setup.
upstream app_upstream {
server 127.0.0.1:4000;
}
# SSL-terminating server and reverse proxy
#
# NOTE: file hierarchy conventions:
# Static assets /srv/opt/app-name
# Configuration files /etc/opt/app-name
# Log files /var/opt/app-name
# Application files /opt/app-name
server {
listen 443 ssl http2; # http2 replaces spdy in nginx >= 1.9.5 (switch if you have a lower version)
listen [::]:443 ssl http2;
server_name app-name.com www.app-name.com;
root /srv/opt/app-name;
index index.html;
charset utf-8;
# SSL Certificates
# Manually generated dhparam with:
# `openssl dhparam -out /etc/opt/app-name/certs/dhparam.pem 4096`
# NOTE: I like putting my application-related certs and keys in the
# /etc/opt/app-name/certs directory, along with a
# /etc/opt/app-name/certs/private directory (for private keys... duh). This
# gives me a quick and easy location to find these files and a format for
# applying different permissions for public versus private keys.
ssl on;
ssl_certificate /etc/nginx/ssl/certs/app-name.crt;
ssl_certificate_key /etc/nginx/ssl/private/app-name.key;
ssl_dhparam /etc/nginx/ssl/certs/dhparam4096.pem;
# Ciphers chosen for forward secrecy and compatibility. Only allow TLS 1.2.
# Check https://mozilla.github.io/server-side-tls/ssl-config-generator/ for
# configurations based on your versions of nginx and openssl
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
# Enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
# http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/certs/app-name.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
ssl_session_cache shared:SSL:5m;
ssl_session_timeout 5m;
ssl_session_tickets off; # requires nginx >= 1.5.9
# Some cache prevention stuff I picked up from Secure Drop's example config page:
# https://docs.securedrop.org/en/stable/deployment/landing_page.html
# NOTE: Don't use these options if you actually want to allow users to cache
# content for, you know, increased speed and performance.
# add_header Cache-Control "max-age=0, no-cache, no-store, must-revalidate";
# add_header Pragma no-cache;
# add_header Expires -1;
# This is only necessary if you are using Adobe Flash and/or PDF on your site.
# add_header X-Permitted-Cross-Domain-Policies "master-only";
# Config to enable HSTS(HTTP Strict Transport Security)
# https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
# To avoid SSL stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
# Prevent pages from being rendered in frame, iframe, or object to prevent
# click-jacking.
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
add_header X-Frame-Options "DENY";
# When serving user-supplied content, include a X-Content-Type-Options: nosniff
# header along with the Content-Type: header, to disable content-type sniffing
# on some browsers.
add_header X-Content-Type-Options "nosniff";
# This header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
# It's usually enabled by default anyway, so the role of this header is to re-enable the filter for
# this particular website if it was disabled by the user.
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
add_header X-XSS-Protection "1; mode=block";
# Prevent IE users from executing downloads in your site's context.
# http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx
add_header X-Download-Options "noopen";
# With Content Security Policy (CSP) enabled(and a browser that supports it(http://caniuse.com/#feat=contentsecuritypolicy),
# you can tell the browser that it can only download content from the domains you explicitly allow
# http://www.html5rocks.com/en/tutorials/security/content-security-policy/
# https://www.owasp.org/index.php/Content_Security_Policy
# more: http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful
# https://content-security-policy.com/
# https://developer.mozilla.org/en/docs/Web/Security/CSP/CSP_policy_directives
# http://lollyrock.com/articles/content-security-policy/
add_header Content-Security-Policy "default-src https:; script-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; object-src 'none'; frame-src 'none'";
# Specify when the browser will set a `Referer` header. In this case, don't.
# Adds some privacy protection for your users ;)
add_header Referrer-Policy "no-referrer";
# HPKP: HTTP Public Key Pinning (very very difficult to implement properly
# without exploding in your face; minor security benefits -- don't implement
# this unless you know why you need it)
# https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning
# https://raymii.org/s/articles/HTTP_Public_Key_Pinning_Extension_HPKP.html
# https://timtaubert.de/blog/2014/10/http-public-key-pinning-explained
# add_header Public-Key-Pins 'pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubDomains' always;
# Cache static files forever (requires renaming them if they change).
# I'm using a "rev" build task to rename files with contents' hash found in
# https://github.com/robmclarty/gulp-tasks
location ~* .(jpg|jpeg|png|gif|ico|css|js|woff|woff2|eot|svg|ttf|txt) {
access_log off;
log_not_found off;
expires max;
}
# Match /app* to the single page app at /app/index.html and let the app's
# router handle the uri.
location ~* ^/app(.*)$ {
try_files /app/index.html =404;
}
# Try serving static assets first, before passing to the app layer. Nginx can
# serve static files orders of magnitude faster than Nodejs can.
# This says "try finding a matching file, if that doesn't work, try finding
# a matching directory, finally if all else fails, pass to proxy" which in
# this case is a Nodejs app.
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites
location / {
try_files $uri @proxy;
}
# Pass requests for dynamic content to Nodejs application.
location @proxy {
# Turn off X-Powered-By header.
proxy_hide_header X-Powered-By;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Enable the following to support websocket requests (not necessary if not
# using websockets).
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade; # allow websockets
# proxy_set_header Connection 'upgrade';
# proxy_cache_bypass $http_upgrade;
# Don't need https when talking to Nodejs as Nginx is proxying SSL traffic
# and handling encryption itself, above the application layer.
# http://stackoverflow.com/questions/10375659/nginx-proxy-pass-node-ssl
proxy_pass http://app_upstream; # match `upstream` name defined above
proxy_redirect off;
}
}