Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Configuring HTTPS + SPDY

Configuring nginx for SSL SNI vhosts

Gotchas

Remarks

server { # http -> https
listen 80;
#listen [::]:80;
server_name filip-prochazka.com *.filip-prochazka.com;
return 301 https://$host$request_uri;
}
server { # https://*.filip-prochazka.com -> https://filip-prochazka.com
listen 443 ssl spdy;
#listen [::]:443 ssl spdy;
server_name *.filip-prochazka.com;
# required: path to certificate and private key
ssl_certificate /usr/local/nginx/conf/.ssl/filip-prochazka.com.bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/.ssl/filip-prochazka.com-decrypted.key;
# required for OCSP stapling, if any of your vhosts don't have this line, you have to inactivate OCSP stapling in ssl.conf
ssl_trusted_certificate /usr/local/nginx/conf/.ssl/filip-prochazka.com.bundle+root.crt;
include hsts.conf;
return 301 https://filip-prochazka.com$request_uri;
}
server {
listen 443 ssl spdy;
#listen [::]:443 ssl spdy;
server_name filip-prochazka.com;
# required: path to certificate and private key
ssl_certificate /usr/local/nginx/conf/.ssl/filip-prochazka.com.bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/.ssl/filip-prochazka.com-decrypted.key;
# required for OCSP stapling, if any of your vhosts don't have this line, you have to inactivate OCSP stapling in ssl.conf
ssl_trusted_certificate /usr/local/nginx/conf/.ssl/filip-prochazka.com.bundle+root.crt;
root /var/www/hosts/filip-prochazka.com;
include hsts.conf;
include php.conf;
}
# HTTP Strict Transport Security: tells browsers to require https:// without first checking
# the http:// version for a redirect. Warning: it is difficult to change your mind.
#
# max-age: length of requirement in seconds (31536000 = 1 year)
# includeSubdomains: force SSL for *ALL* subdomains (remove if this is not what you want)
# preload: indicates you want browsers to ship with HSTS preloaded for your domain.
#
# Submit your domain for preloading in browsers at: https://hstspreload.appspot.com
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
# If you won't/can't turn on HTTPS for *all* subdomains, use this simpler version:
# add_header Strict-Transport-Security 'max-age=31536000' always;
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 37.157.192.28
netmask 255.255.255.0
gateway 37.157.192.1
iface eth0 inet6 static
address 2a02:2b88:2:1::e2a:1
netmask 64
gateway 2a02:2b88:2:1::1
server { # http -> https
listen 80;
#listen [::]:80;
server_name kdyby.org *.kdyby.org;
return 301 https://$host$request_uri;
}
server { # *.kdyby.org
listen 443 default ssl spdy;
#listen [::]:443 ipv6only=on ssl spdy;
server_name *.kdyby.org www.kdyby.org;
# required: path to certificate and private key
ssl_certificate /usr/local/nginx/conf/.ssl/kdyby.org.bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/.ssl/kdyby.org-decrypted.key;
# required for OCSP stapling, if any of your vhosts don't have this line, you have to inactivate OCSP stapling in ssl.conf
ssl_trusted_certificate /usr/local/nginx/conf/.ssl/kdyby.org.bundle+root.crt;
root /var/www/hosts/kdyby.org;
include hsts.conf;
include php.conf;
}
server { # help.kdyby.org
listen 443 ssl spdy;
#listen [::]:443 ssl spdy;
server_name help.kdyby.org;
# required: path to certificate and private key
ssl_certificate /usr/local/nginx/conf/.ssl/kdyby.org.bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/.ssl/kdyby.org-decrypted.key;
# required for OCSP stapling, if any of your vhosts don't have this line, you have to inactivate OCSP stapling in ssl.conf
ssl_trusted_certificate /usr/local/nginx/conf/.ssl/kdyby.org.bundle+root.crt;
root /var/www/hosts/help.kdyby.org;
include hsts.conf;
include php.conf;
}
http {
# Prefer certain ciphersuites, to enforce Forward Secrecy and avoid known vulnerabilities.
#
# Forces forward secrecy in all browsers and clients that can use TLS,
# but with a small exception (DES-CBC3-SHA) for IE8/XP users.
#
# Reference client: https://www.ssllabs.com/ssltest/analyze.html
ssl_prefer_server_ciphers on;
# Ciphers suggested by: https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
# Setup pre-generate a 2048 bit random parameter for DH elliptic curves.
# If not created and specified, default is only 1024 bits.
ssl_dhparam /usr/local/nginx/conf/.ssl/dhparam2048.pem;
# Cut out the old, broken, insecure SSLv2 and SSLv3 entirely.
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
# optional: turn on session resumption, using a 10 min cache shared across nginx processes
# as recommended by http://nginx.org/en/docs/http/configuring_https_servers.html
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# http://nginx.org/en/docs/http/configuring_https_servers.html#optimization
keepalive_timeout 70;
# Buffer size of 1400 bytes fits in one MTU.
# nginx 1.5.9+ ONLY
ssl_buffer_size 1400;
# OCSP stapling - means nginx will poll the CA for signed OCSP responses,
# and send them to clients so clients don't make their own OCSP calls.
# https://en.wikipedia.org/wiki/OCSP_stapling
#
# while the ssl_certificate above may omit the root cert if the CA is trusted,
# ssl_trusted_certificate below must point to a chain of **all** certs
# in the trust path - (your cert, intermediary certs, root cert)
#
# 8.8.8.8 and 8.8.4.4 below are Google public IPv4 DNS servers. nginx will use them to talk to the CA.
ssl_stapling on;
ssl_stapling_verify on;
# If you can, use DNS of your hosting company rather then Google
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10;
# ...
# the rest of the configuration
# includes of vhost configurations
}
index index.php index.html;
# logging into prepared socket from rsyslog, which then passes it directly to papertrail
# access_log syslog:server=unix:/var/log/nginx.sock verbose if=$loggable;
# error_log syslog:server=unix:/var/log/nginx.sock;
location / {
try_files $uri $uri/ /index.php?$args;
}
fastcgi_read_timeout 600;
client_body_in_file_only clean;
client_body_buffer_size 32K;
client_max_body_size 100M;
sendfile on;
send_timeout 1024s;
location ~ [^/]\.php(/|$) { # main block with PHP processing
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $uri =404;
}
location ~* \.(png|gif|jpg|jpeg|css|js|swf|ico|txt|bmp|pdf|doc|docx|ppt|pptx|zip)$ {
access_log off;
expires 30d;
}
location ~ /\.(ht|gitignore) { # deny access to .htaccess files, if Apache's document root concurs with nginx's one
deny all;
}
location ~ \.(neon|ini|log|yml)$ { # deny access to configuration files
deny all;
}
location = /robots.txt { access_log off; log_not_found off; }
location = /humans.txt { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
@fprochazka
Copy link
Author

Comments here do not create notifications, write me an email please, or comment at the article
https://filip-prochazka.com/blog/nginx-https-spdy-hsts-security.

The contact info is at https://filip-prochazka.com - thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment