Skip to content

Instantly share code, notes, and snippets.

@kennwhite
Last active August 29, 2015 14:06
Show Gist options
  • Save kennwhite/25183c3f05266ee0ad7f to your computer and use it in GitHub Desktop.
Save kennwhite/25183c3f05266ee0ad7f to your computer and use it in GitHub Desktop.
CentOS, Red Hat, Amazon Linux nginx config: A+ SSL Labs rating w/ strong legacy compatibility
# Strong nginx config for SSL Labs rating A as of 3-2015
# Broad legacy compatibility including IE8, Android 2.3+, openssl 0.9.8 clients
# Blocks most bot scan IP probes.
#
# *** Assumes: _HOSTNAME_ is replaced ***
# *** Assumes: Diffie-Hellman parameters have been generated (see: dhparam below)
#
# Includes OCSP stapling, HSTS Strict Transport security,
# session resumption, legacy backwards compatibility (XP, Android 2.3-4.3)
#
# Requires nginx 1.6+ See: http://nginx.org/en/linux_packages.html, e.g.:
# $ rpm -ivh http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm
# $ yum install nginx
#
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
root /usr/share/nginx/_HOSTNAME_;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
server_tokens off;
server_names_hash_bucket_size 64;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Required for some CAs with Intermediate trust chains
# ssl_trusted_certificate /etc/nginx/ssl/AddTrustExternalCARoot.crt;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# Generate: openssl dhparam 2048 -out /etc/nginx/ssl/dhparam.pem
# Session Resumption
ssl_session_timeout 20m;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:20m;
# Enable OCSP stapling (req. nginx v 1.3.7+)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
# For additional CORS DENY, ALLOW, SAMEORIGIN, etc. options see: http://enable-cors.org/
add_header X-Frame-Options DENY;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
#
# Cipher suites enabled below. Here's the rationale:
#
# *TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# Android 4.4.2, Chrome 39 OSX, FF 31.3 ESR Win7, FF 34 OSX, IE 11 Win 10
# Java 8b132, OpenSSL 1.0.1h, Yahoo crawler, Yandex
# ^-- HTTP/2-compatible [AEAD]
#
# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
# IE 11 Win7-8.1, IE 11 Win Phone 8.1, Safari 6 IOS 6.0.1, Safari 7 IOS 7.1
# Safari 8 IOS 8, Safari 7 OSX 10.9
#
# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
# Android 4.0 - 4.4.2, Bing crawler, Google crawler, IE7 Vista, IE 8-10 Win7
# IE Mobile 10 Win Phone 8.0, Java 7u25, Safari 5.1 OS 10.6.8
# Safari 6, 10.8.4
# ^-- strong, but lacks authentication (AEAD)
#
# TLS_RSA_WITH_AES_128_CBC_SHA
# Java 6, Android 2.3.x, OpenSSL 0.9.8y [DEPRECATED - included for legacy API/mobile support]
# ^-- removed from TLS 1.3 & HTTP/2 standards, lacks Forward Secrecy & authentication (AEAD)
#
# TLS_RSA_WITH_3DES_EDE_CBC_SHA
# IE 8/XP [DEPRECATED - ONLY add (to end) of ssl_ciphers list for legacy IE8/XP support]
# ^-- STRONGLY discouraged unless IE8 on XP is absolutely required
ssl_ciphers "ECDHE_RSA_AES128_GCM_SHA256 ECDHE_RSA_AES128_CBC_SHA256 ECDHE_RSA_AES_128_CBC_SHA RSA_AES_128_CBC_SHA";
client_max_body_size 16M;
# Block IP-based bot/scanner requests (ie, GETs lacking a domain/hostname)
server {
listen 80 default_server;
return 444;
}
server {
listen 443 ssl;
return 444;
}
server {
listen 80;
server_name _HOSTNAME_;
return 301 https://_HOSTNAME_;
}
server {
listen 443 ssl;
server_name _HOSTNAME_;
# Enable Strict Transport Security (HSTS) (SSL-only)
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
}
}
@therealmik
Copy link

Re resolver: I was looking through the resolver code and it uses 16 bits of random(3) for the ident and a single port to send requests. I raised this with nginx, and the response was:

Yes, the resolver in nginx isn't expected to be used in hostile
environments. Rather, it's to be used to talk to a real local DNS
server in a non-blocking way.

Which is reasonable - they wanted a workaround for the system resolver libraries blocking, but it also means that using it other than localhost (especially on an internet-facing interface) is a risk that shouldn't be encouraged.

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