Skip to content

Instantly share code, notes, and snippets.

@vdavez
Last active December 6, 2015 20:29
Show Gist options
  • Save vdavez/4ddfd952d1cc5551e068 to your computer and use it in GitHub Desktop.
Save vdavez/4ddfd952d1cc5551e068 to your computer and use it in GitHub Desktop.
beginning of a ssl-ready nginx deploy
#!/bin/bash
# This is a script to automatically load the nginx configuration
add-apt-repository ppa:nginx/stable
apt-get update
apt-get -y install nginx
cp local.conf /etc/nginx/conf.d/local.conf
mkdir /etc/nginx/ssl
cp ssl.rules /etc/nginx/ssl/ssl.rules
cp nginx.conf /etc/nginx/nginx.conf
IP_ADDRESS="$(ifconfig | egrep -o -m 1 'inet addr:[0-9|.]+' | egrep -o '[0-9|.]+')"
echo "Your server name, please?"
read SERVER_NAME
# Generate the Keys
openssl genrsa -aes256 -out /etc/nginx/ssl/keys/private.key 2048
# Note, this will ask you for your password twice.
openssl rsa -in /etc/nginx/ssl/keys/private.key -out /etc/nginx/ssl/keys/private-decrypted.key
# Note, this will ask for the password, too.
openssl req -new -sha256 -key /etc/nginx/ssl/keys/private-decrypted.key -out /etc/nginx/ssl/keys/$SERVER_NAME.csr
# Note, this will ask for...
# Country Name (2 letter code) [AU]:
# State or Province Name (full name) [Some-State]:
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:
# Organizational Unit Name (eg, section) []:
# Common Name (e.g. server FQDN or YOUR name) []:
# Email Address []:
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
openssl x509 -req -days 365 -in /etc/nginx/ssl/keys/$SERVER_NAME.csr -signkey /etc/nginx/ssl/keys/private.key -out /etc/nginx/ssl/keys/server.crt
# Will ask for the private key password again
openssl dhparam -outform pem -out /etc/nginx/ssl/dhparam2048.pem 2048
# Do some cleanup. Only leave the crt and the encrypted private key
rm /etc/nginx/ssl/keys/private-decrypted.key
rm /etc/nginx/ssl/keys/$SERVER_NAME.csr
sed -i "s/SERVER_NAME/$SERVER_NAME" /etc/nginx/conf.d/local.conf
sed -i "s/SSL_ROOT/$SSL_ROOT" /etc/nginx/ssl/ssl.rules
server {
listen 80;
server_name SERVER_NAME;
return 301 https://$host$request_uri;
}
# The 'spdy' at the end of the listen command below turns on SPDY support.
server {
listen 443 ssl spdy;
server_name SERVER_NAME;
# (You'll need to add your own commands to actually serve your website,
# like a root to static files, or a reverse proxy to an app process.)
location / {
proxy_pass http://localhost:5000/;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_max_temp_file_size 0;
proxy_connect_timeout 10;
proxy_send_timeout 30;
proxy_read_timeout 30;
}
# Path to certificate and private key.
# The .crt may omit the root CA cert, if it's a standard CA that ships with clients.
ssl_certificate /etc/nginx/ssl/keys/server.crt;
ssl_certificate_key /etc/nginx/ssl/keys/private.key;
include /etc/nginx/ssl/ssl.rules;
}
user nginx;
worker_processes 2;
pid /var/run/nginx.pid;
worker_rlimit_nofile 30000;
events {
worker_connections 1024;
}
http {
##
# Basic stuff
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
types {
text/plain log;
text/plain asc;
}
##
# Security
##
add_header X-Frame-Options DENY;
##
# Logging
##
log_format main '$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $request_time '
'$upstream_response_time $pipe';
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/rss+xml;
##
# Timeout variables (currently disabled)
##
# client_header_timeout 10m;
# client_body_timeout 10m;
# send_timeout 10m;
# client_max_body_size 250m;
# connection_pool_size 256;
# client_header_buffer_size 16k;
# large_client_header_buffers 4 32k;
# request_pool_size 16k;
##
# Virtual Host Configs
##
include /etc/nginx/vhosts/*.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';
# If you won't/can't turn on HTTPS for *all* subdomains, use this simpler version:
# add_header Strict-Transport-Security 'max-age=31536000';
# 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;
ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !MD5 !EXP !DSS !PSK !SRP !kECDH !CAMELLIA !RC4 !SEED';
# Cut out the old, broken, insecure SSLv2 and SSLv3 entirely.
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
# 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;
keepalive_timeout 70;
# Buffer size of 1400 bytes fits in one MTU.
# nginx 1.5.9+ ONLY
ssl_buffer_size 1400;
# SPDY header compression (0 for none, 9 for slow/heavy compression). Preferred is 6.
#
# BUT: header compression is flawed and vulnerable in SPDY versions 1 - 3.
# Disable with 0, until using a version of nginx with SPDY 4.
spdy_headers_comp 0;
# Now let's really get fancy, and pre-generate a 2048 bit random parameter
# for DH elliptic curves. If not created and specified, default is only 1024 bits.
#
# Generated by OpenSSL with the following command:
# openssl dhparam -outform pem -out dhparam2048.pem 2048
ssl_dhparam /etc/nginx/ssl/dhparam2048.pem;
# 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's public IPv4 DNS servers.
# nginx will use them to talk to the CA.
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10;
ssl_trusted_certificate ssl_trusted_certificate /path/to/all-certs-in-chain.crt;
@konklone
Copy link

Notes -

  • the ssl_trusted_certificate at the end needs to end up pointing to the full chain
  • you can skip the encryption/decryption step with key generation by not passing -aes256 to the command (no password input)
  • you should be able to provide arguments to the CSR command somehow to remove user input from the CSR generation process. The only necessary thing is the FQDN, which should be the domain name the cert is for -- and presumably you have one place in here already where the desired domain name is being input, that you could reuse for that.

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