make_sni.sh revision c002c44ee5c7e7258f4ba5c162461c24a0c179c2
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#!/bin/sh
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# Licensed to the Apache Software Foundation (ASF) under one or more
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# contributor license agreements. See the NOTICE file distributed with
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# this work for additional information regarding copyright ownership.
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# The ASF licenses this file to You under the Apache License, Version 2.0
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# (the "License"); you may not use this file except in compliance with
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# the License. You may obtain a copy of the License at
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
5b5f6a35e757c7471b2965d2de3fc32cc6199700bnicholes# http://www.apache.org/licenses/LICENSE-2.0
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
909ce17e2bd0faef7b1c294f2307f009793fd493nd# Unless required by applicable law or agreed to in writing, software
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# distributed under the License is distributed on an "AS IS" BASIS,
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0ce5630695a7aa568811a9dd0aceedd685f040dend# See the License for the specific language governing permissions and
42af92a661a06b3cebc88d585aad75064a309d51nd# limitations under the License.
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# This script will populate a directory 'sni' with 3 sites, httpd.conf
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# and certificates as to facilitate testing of TLS server name
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# indication support (RFC 4366) or SNI.
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend# $Id$
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend#
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendOPENSSL=${OPENSSL:-openssl}
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendDOMAIN=${DOMAIN:-my-sni-test.org}
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendDIR=${DIR:-$PWD/sni}
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendNAMES=${NAMES:-ape nut pear apple banana}
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendargs=`getopt fd:D: $*`
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendif [ $? != 0 ]; then
05ede5110427cb9dc071cc671d5aaba5d3b88c79nd echo "Syntax: $0 [-f] [-d outdir] [-D domain ] [two or more server names ]"
e8b603fa9ccf7b17b11b42df6d8916fd97c2331dnd echo " -f Force overwriting of outdir (default is $DIR)"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo " -d dir Directory to create the SNI test server in (default is $DIR)"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo " -D domain Domain name to use for this test (default is $DOMAIN)"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo " [names] List of optional server names (default is $NAMES)"
d6ce05b6521a82cc93da69f7c2116c4a5bc54f8cjim echo
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo "Example:"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo " $0 -D SecureBlogsAreUs.com peter fred mary jane ardy"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend exit 1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendfi
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendset -- $args
03a4ff9ac4c9b8009249010e7c53bb86ff05915andfor i
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fenddo
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend case "$i"
7d15331eeb5429d7148d13d6fd914a641bf1c000pquerna in
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend -f)
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend FORCE=1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend shift;;
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend -d)
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend DIR=$2; shift
d2b809e5d72658bff23819d8b77f20e4939af541nd shift;;
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend -D)
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend DOMAIN=$2; shift
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend shift;;
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend --)
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend shift; break;
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend esac
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fenddone
6b0fe1f447ba35827cd5cf1d2a703bd8517f33ffmturk
6b0fe1f447ba35827cd5cf1d2a703bd8517f33ffmturkif [ $# = 1 ]; then
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo "Aborted - just specifing one servername makes no sense for SNI testing. Go wild !"
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend exit 1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendfi
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendif [ $# -gt 0 ]; then
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend NAMES=$*
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendfi
0ce5630695a7aa568811a9dd0aceedd685f040dend
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendif ! openssl version | grep -q OpenSSL; then
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo Aborted - your openssl is very old or misconfigured.
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend exit 1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendfi
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend
03c25fb6f628ac81f2ecb637d1e7502dcee783f3ndset `openssl version`
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendif test "0$2" \< "00.9"; then
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo Aborted - version of openssl too old, 0.9 or up required.
0ce5630695a7aa568811a9dd0aceedd685f040dend exit 1
7fa75a06a4fee19e995c069ee00310455d1452e1pquernafi
0ce5630695a7aa568811a9dd0aceedd685f040dend
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendif test -d ${DIR} -a "x$FORCE" != "x1"; then
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend echo Aborted - already an ${DIR} directory. Use the -f flag to overwrite.
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend exit 1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fendfi
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend
0ce5630695a7aa568811a9dd0aceedd685f040dendmkdir -p ${DIR} || exit 1
0ce5630695a7aa568811a9dd0aceedd685f040dendmkdir -p ${DIR}/ssl ${DIR}/htdocs ${DIR}/logs || exit 1
f73f2c2fae0ded6c8273c28d025ba8aa8136a0fend
# Create a 'CA' - keep using different serial numbers
# as the browsers get upset if they see an identical
# serial with a different pub-key.
#
# Note that we're not relying on the 'v3_ca' section as
# in the default openssl.conf file - so the certificate
# will be without the basicConstraints = CA:true and
# keyUsage = cRLSign, keyCertSign values. This is fine
# for most browsers.
#
serial=$$
openssl req -new -nodes -batch \
-x509 \
-days 10 -subj '/CN=Da Root/O=SNI testing/' -set_serial $serial \
-keyout ${DIR}/root.key -out ${DIR}/root.pem \
|| exit 2
echo '# To append to your hosts file' > ${DIR}/hosts
cat > ${DIR}/httpd-sni.conf << EOM
# To append to your httpd.conf file'
Listen 127.0.0.1:443
NameVirtualHost 127.0.0.1:443
LoadModule ssl_module modules/mod_ssl.so
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
LogLevel debug
TransferLog ${DIR}/logs/access_log
ErrorLog ${DIR}/logs/error_log
# You'll get a warning about this.
#
SSLSessionCache none
<Directory />
Options None
AllowOverride None
Require all denied
</Directory>
<Directory "${DIR}/htdocs">
allow from all
Require all granted
</Directory>
# This first entry is also the default for non SNI
# supporting clients.
#
EOM
INFO="and also the site you see when the browser does not support SNI."
for n in ${NAMES}
do
dw FQDN=$n.$DOMAIN
serial=`expr $serial + 1`
# Create a certificate request for this host.
#
openssl req -new -nodes -batch \
-days 9 -subj "/CN=$FQDN/O=SNI Testing/" \
-keyout ${DIR}/$n.key -out ${DIR}/$n.req -batch \
|| exit 3
# And get it signed by our root authority.
#
openssl x509 -text -req \
-CA ${DIR}/root.pem -CAkey ${DIR}/root.key \
-set_serial $serial -in ${DIR}/$n.req -out ${DIR}/$n.pem \
|| exit 4
cat ${DIR}/$n.pem ${DIR}/$n.key > ${DIR}/ssl/$n.crt
rm ${DIR}/$n.req ${DIR}/$n.key ${DIR}/$n.pem
LST="$LST
https://$FQDN/index.html"
echo "127.0.0.1 $FQDN $n" >> ${DIR}/hosts
# Create and populate a docroot for this host.
#
mkdir -p ${DIR}/htdocs/$n || exit 1
echo We are $FQDN $INFO > ${DIR}/htdocs/$n/index.html || exit 1
# And change the info text - so that only the default/fallback site
# gets marked as such.
#
INFO="and you'd normally only see this site when there is proper SNI support."
# And create a configuration snipped.
#
cat >> ${DIR}/httpd-sni.conf << EOM
<VirtualHost 127.0.0.1:443>
SSLEngine On
ServerName $FQDN:443
DocumentRoot ${DIR}/htdocs/$n
SSLCertificateChainFile ${DIR}/root.pem
SSLCertificateFile ${DIR}/ssl/$n.crt
TransferLog ${DIR}/logs/access_$n
</VirtualHost>
EOM
done
cat << EOM
SNI Files generated
===================
The directory ${DIR}/sni has been populated with the following
- root.key|pem Certificate authority root and key. (You could
import the root.pem key into your browser to
quell warnings about an unknown authority).
- hosts /etc/hosts file with fake entries for the hosts
- htdocs directory with one docroot for each domain,
each with a small sample file.
- ssl directory with an ssl cert (signed by root)
for each of the domains).
- logs logfiles, one for each domain and an
access_log for any misses.
SNI Test
========
A directory ${DIR}/sni has been created. Run an apache
server against it with
.../httpd -f ${DIR}/httpd-sni.conf
and keep an eye on ${DIR}/logs/... Note that you will see an entries
like
Feb 11 16:12:26 2008] [debug] Init:
SSL server IP/port overlap: ape.*:443 (httpd-sni.conf:24) vs. jane.*:443 (httpd-sni.conf:42)
and a concluding warning
[Mon Feb 11 16:12:26 2008] [warn] Init:
Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
If you see an entry like
[Mon Feb 11 15:41:41 2008] [warn] Init:
You should not use name-based virtual hosts in conjunction with SSL!!
then you are either using an OpenSSL which is too old, or you need to ensure that the
TLS Extensions are compiled into openssl with the 'enable-tlsext' flag.
Meanwhile add 'hosts' to your c:\windows\system32\drivers\etc\hosts
or /etc/hosts file as to point the various URL's to your server:
$LST
and verify that each returns its own name (and an entry in its
own ${DIR}/logs) file).
EOM
exit 0