#!/bin/bash # Generate nginx config and HTML for testing ciphers # Author: Peter Wu # # Tested with: nginx/1.4.2-4 openssl/1.0.1.e-3 # (as packaged on Arch Linux) # For the keys, see "notes.txt" on how to generate them. # # This script will parse the output of `openssl ciphers`, write the HTML to # /srv/http/ciphertest/index.html (can be changed below, $root and $html) and # output the nginx server config to stdout. Note that this file is only # generated when the $root directory exists. # # When testing in browser, be sure to import the RSA, DSA and EC certificates. # Tested with Firefox 23.0.1 and Chromium 29.0.1547.65 (both are linked to NSS # 3.15.1), but those support too few ciphers so I used `openssl s_client` or # `curl` instead. # # Motivations for the nginx config: # - Details are put in the server block (instead of the http block) such that it # can still be used with other sites in one nginx config. # - currently listens on localhost with an increasing port to avoid browsers to # fall back to TLS w/o SNI support and then messing up the results. Other # possible ways to solve this: # # * Use different IPv6 addresses (or IPv4, but unless you are using # localhost, you won't have access to a /26 subnet I guess) # * Create different certificates for each host, not using a wildcard. # # If you start from scratch, you can try something like: # # user http http; # pid pid; # error_log error_log info; # events { # worker_connections 768; # } # http { # # because I have a long domain name # server_names_hash_bucket_size 128; # server_names_hash_max_size 1024; # include ciphertest.conf; # } # # Notes about this nginx.conf: # - ciphertest.conf is assumed to be in the same prefix $prefix # - certs/ containing private keys and public keys are also assumed present # - Start with: nginx -p $prefix -c nginx.conf # # A final note, this script is overly complicated because Wireshark initially # had issues with TLSv1.2 (while the SSLv3 Firefox client parses fine). If you # are careful with matching ciphers to a DSA/RSA/EC certificate, you can also # use `openssl s_server` instead of nginx. #domain=ciphertest.lekensteyn.nl # ssl-enabled ip:port, may occur multiple times space-separated # PORT will be replaced for a number that increments for every test #listen=$domain:PORT domain=${1:-local.al.lekensteyn.nl} address=localhost listen="$address:4433 $address:PORT " portbase=4433 pkdir=certs/ rsa_prv=server.pem rsa_pub=server.crt dsa_prv=dsa.pem dsa_pub=dsa.crt #ecc_prv=ec.pem #ecc_pub=ec.crt ecc_prv=secp384r1.pem ecc_pub=secp384r1.crt dh_params=dhparams.pem root=/srv/http/ciphertest html="$root/index.html" get_ciphers() { # output: index (n1 << 8 | n2) name version auth line openssl ciphers -V | sort -n | awk -F'[ ,]+' '{ print ++i, $2, $3, $5, $6, substr($8, 4), $0 }' } htmlescape() { sed 's/&/&/g;s//\>/g' } # always generate file when root is present if [ -d "$root" ]; then cat > "$html" < Cipher suite test
$(openssl version -a | htmlescape)

Hide cipher suites:
EOF fi # Begin nginx config generator get_common() { local auth=$1 local port=${2:-$portbase} local crtfile keyfile dhpfile case $auth in RSA) crtfile=$rsa_pub keyfile=$rsa_prv ;; ECDH) # Note: NSS does not support all cipher suites from OpenSSL, but OpenSSL # cannot work with ECDH-RSA using th below certificates. crtfile=$ecc_pub keyfile=$ecc_prv #dhpfile=$dh_params ;; DSS) crtfile=$dsa_pub keyfile=$dsa_prv ;; ECDSA) crtfile=$ecc_pub keyfile=$ecc_prv #dhpfile=$dh_params ;; PSK) #echo "Unknown Au=$auth - using RSA" >&2 crtfile=$rsa_pub keyfile=$rsa_prv ;; *) echo "Unknown Au=$auth - using RSA" >&2 crtfile=$rsa_pub keyfile=$rsa_prv ;; esac local listens l listens=$(echo ${listen//PORT/$port} | tr ' ' '\n' | sort -u | tr '\n' ' ') for l in $listens; do echo " listen $l ssl;" done cat <document.domain='$domain'"; } } EOF done cat <