Skip to content

Instantly share code, notes, and snippets.

@inetbiz inetbiz/site.conf

forked from paskal/site.conf
Last active Mar 23, 2020
What would you like to do?
Nginx configuration for best security and modest performance. Full info on
#
# latest version on
# security test score:
# your nginx version might not have all directives included, test this configuration before using in production against your nginx:
# $ nginx -c /etc/nginx/nginx.conf -t
server {
# public key, contains your public key and class 1 certificate, to create:
# (example for startssl)
# $ (cat & wget -O - | tee -a /etc/nginx/ssl/domain.pem > /dev/null
ssl_certificate /etc/nginx/ssl/domain.pem;
# private key (decoded), decode encoded with RSA key with command:
# $ openssl rsa -in decoded.key -out domain.key
ssl_certificate_key /etc/nginx/ssl/domain.key;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
# to generate your dhparam.pem file, run in the terminal:
# $ openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# don't forget to set secure rights to these files:
# $ chmod 400 /etc/nginx/ssl/*
# make it bigger for more sessions, one megabyte for ~ 4000 session
ssl_session_cache shared:SSL:100m;
ssl_session_timeout 60m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ciphers are latest modern from (only place you can trust on web)
# working example:
ssl_ciphers '<paste intermediate ciphersuite here>';
ssl_prefer_server_ciphers on;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
# dns resolver, we're using Google IPv4 and IPv6 servers
resolver [2001:4860:4860::8888];
# verify chain of trust of OCSP response using Root CA and Intermediate certs, example for StartSSL:
# $ wget -O - | tee -a ca-certs.pem > /dev/null
ssl_trusted_certificate /etc/nginx/ssl/root_CA_cert_plus_intermediates;
# consider turning 'deferred' off on old versions of nginx if you occur any problems
listen 443 deferred spdy ssl;
listen [::]:443 deferred spdy ssl ipv6only=on;
root /var/local/www/example;
index index.html;
autoindex off;
charset utf-8;
#don't send the nginx version number in error pages and Server header
server_tokens off;
# enabling HSTS(HTTP Strict Transport Security)
add_header Strict-Transport-Security max-age=63072000; includeSubDomains; preload; always;
# enabling Public Key Pinning Extension for HTTP (HPKP)
# tool for checking and generating proper certificates:
# to generate use on of these:
# $ openssl rsa -in my-website.key -outform der -pubout | openssl dgst -sha256 -binary | base64
# $ openssl req -in my-website.csr -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
# $ openssl x509 -in my-website.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
add_header Public-Key-Pins 'pin-sha256="base64+info1="; max-age=31536000' always;
# config to don't allow the browser to render the page inside an frame or
# iframe and avoid clickjacking
# if you need to allow [i]frames, you can use SAMEORIGIN
# or set an uri with ALLOW-FROM uri
# warning, this option breaking some analitics tools
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, 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.
add_header X-XSS-Protection "1; mode=block";
location / {
# try_files might be dangerous, please read:
try_files $uri $uri/ =404;
# deny access to files, starting with dot (hidden) or ending with ~ (temp)
location ~ /\. {
access_log off;
log_not_found off;
deny all;
location ~ ~$ {
access_log off;
log_not_found off;
deny all;
# block of rules for static content
location ~ /{favicon.ico|favicon.png|robots.txt}$ {
access_log off;
log_not_found off;
expires 1y;
add_header Cache-Control public,max-age=259200;
location ~* \.(jpg|jpeg|png|gif|ico|css|js|mp3)$ {
expires 30d;
add_header Cache-Control public,max-age=259200;
server {
# catch all unsecure requests (both IPv4 and IPv6)
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
# this means, *
# permanently redirect client to https version of the site
return 301;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.