make_sni.sh revision 00d6521b902bb0b381f3ffe7eff44f7978497e5c
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#!/bin/sh
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# Licensed to the Apache Software Foundation (ASF) under one or more
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# contributor license agreements. See the NOTICE file distributed with
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# this work for additional information regarding copyright ownership.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# The ASF licenses this file to You under the Apache License, Version 2.0
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# (the "License"); you may not use this file except in compliance with
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# the License. You may obtain a copy of the License at
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# http://www.apache.org/licenses/LICENSE-2.0
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering#
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering# Unless required by applicable law or agreed to in writing, software
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# distributed under the License is distributed on an "AS IS" BASIS,
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# See the License for the specific language governing permissions and
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# limitations under the License.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering# This script will populate a directory 'sni' with 3 sites, httpd.conf
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# and certificates as to facilitate testing of TLS server name
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering# indication support (RFC 4366) or SNI.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# $Id$
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
56ba3c78ae35065064c4289a0c8e22a81256af20Zbigniew Jędrzejewski-SzmekOPENSSL=${OPENSSL:-openssl}
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringDOMAIN=${DOMAIN:-my-sni-test.org}
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringDIR=${DIR:-$PWD/sni}
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringNAMES=${NAMES:-ape nut pear apple banana}
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringargs=`getopt fd:D: $*`
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringif [ $? != 0 ]; then
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo "Syntax: $0 [-f] [-d outdir] [-D domain ] [two or more vhost names ]"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo " -f Force overwriting of outdir (default is $DIR)"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo " -d dir Directory to create the SNI test server in (default is $DIR)"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo " -D domain Domain name to use for this test (default is $DOMAIN)"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo " [names] List of optional vhost names (default is $NAMES)"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo "Example:"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo " $0 -D SecureBlogsAreUs.com peter fred mary jane ardy"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering exit 1
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfi
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringset -- $args
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfor i
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringdo
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering case "$i"
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering in
94fb446e55babb713fb24850455627acf30d999bLennart Poettering -f)
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering FORCE=1
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering shift;;
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -d)
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering DIR=$2; shift
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering shift;;
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -D)
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering DOMAIN=$2; shift
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering shift;;
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering --)
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering shift; break;
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering esac
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringdone
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringif [ $# = 1 ]; then
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering echo "Aborted - just specifing one vhost makes no sense for SNI testing. Go wild !"
94fb446e55babb713fb24850455627acf30d999bLennart Poettering exit 1
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poetteringfi
94fb446e55babb713fb24850455627acf30d999bLennart Poettering
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poetteringif [ $# -gt 0 ]; then
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering NAMES=$*
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfi
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringif ! openssl version | grep -q OpenSSL; then
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo Aborted - your openssl is very old or misconfigured.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering exit 1
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfi
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringset `openssl version`
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringif test "0$2" \< "00.9"; then
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering echo Aborted - version of openssl too old, 0.9 or up required.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering exit 1
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfi
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
01448ff92d9549785242ffab453bf5bcde348c61Lennart Poetteringif test -d ${DIR} -a "x$FORCE" != "x1"; then
01448ff92d9549785242ffab453bf5bcde348c61Lennart Poettering echo Aborted - already an ${DIR} directory. Use the -f flag to overwrite.
01448ff92d9549785242ffab453bf5bcde348c61Lennart Poettering exit 1
01448ff92d9549785242ffab453bf5bcde348c61Lennart Poetteringfi
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poetteringmkdir -p ${DIR} || exit 1
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poetteringmkdir -p ${DIR}/ssl ${DIR}/htdocs ${DIR}/logs || exit 1
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering# Create a 'CA' - keep using different serial numbers
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering# as the browsers get upset if they see an identical
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering# serial with a different pub-key.
94fb446e55babb713fb24850455627acf30d999bLennart Poettering#
94fb446e55babb713fb24850455627acf30d999bLennart Poettering# Note that we're not relying on the 'v3_ca' section as
94fb446e55babb713fb24850455627acf30d999bLennart Poettering# in the default openssl.conf file - so the certificate
94fb446e55babb713fb24850455627acf30d999bLennart Poettering# will be without the basicConstraints = CA:true and
94fb446e55babb713fb24850455627acf30d999bLennart Poettering# keyUsage = cRLSign, keyCertSign values. This is fine
94fb446e55babb713fb24850455627acf30d999bLennart Poettering# for most browsers.
94fb446e55babb713fb24850455627acf30d999bLennart Poettering#
94fb446e55babb713fb24850455627acf30d999bLennart Poetteringserial=$$
94fb446e55babb713fb24850455627acf30d999bLennart Poetteringopenssl req -new -nodes -batch \
94fb446e55babb713fb24850455627acf30d999bLennart Poettering -x509 \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -days 10 -subj '/CN=Da Root/O=SNI testing/' -set_serial $serial \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -keyout ${DIR}/root.key -out ${DIR}/root.pem \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering || exit 2
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringecho '# To append to your hosts file' > ${DIR}/hosts
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringcat > ${DIR}/httpd-sni.conf << EOM
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# To append to your httpd.conf file'
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringListen 127.0.0.1:443
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringNameVirtualHost 127.0.0.1:443
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringLoadModule ssl_module modules/mod_ssl.so
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
50b1678aaba9d3c2be5115db34a822911d791b8cLennart PoetteringSSLRandomSeed startup builtin
bb31a4ac1997c189a344caf554f34c6aabc71aa7Thomas Hindoe Paaboel AndersenSSLRandomSeed connect builtin
50b1678aaba9d3c2be5115db34a822911d791b8cLennart Poettering
50b1678aaba9d3c2be5115db34a822911d791b8cLennart PoetteringLogLevel debug
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringTransferLog ${DIR}/logs/access_log
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringErrorLog ${DIR}/logs/error_log
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# You'll get a warning about this.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringSSLSessionCache none
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering<Directory />
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering Options None
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering AllowOverride None
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering Require all denied
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering</Directory>
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering<Directory "${DIR}/htdocs">
94fb446e55babb713fb24850455627acf30d999bLennart Poettering allow from all
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering Require all granted
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering</Directory>
9847946e12479b27d3ebfd024f00a6ac33ce73d3Lennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# This first entry is also the default for non SNI
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering# supporting clients.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering#
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringEOM
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart PoetteringINFO="and also the site you see when the browser does not support SNI."
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringfor n in ${NAMES}
0b3b020a178cf3b957fed627de13c895773995ecLennart Poetteringdo
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering FQDN=$n.$DOMAIN
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering serial=`expr $serial + 1`
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering # Create a certificate request for this host.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering #
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering openssl req -new -nodes -batch \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -days 9 -subj "/CN=$FQDN/O=SNI Testing/" \
cb07866b1b7c11e687a322d70dd9f9d73bbbe488Lennart Poettering -keyout ${DIR}/$n.key -out ${DIR}/$n.req -batch \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering || exit 3
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering # And get it signed by our root authority.
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering #
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering openssl x509 -text -req \
0b3b020a178cf3b957fed627de13c895773995ecLennart Poettering -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/error_log. When everything
is fine you will see 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)
for each vhost configured 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)
HOWEVER - 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 and/or you need to ensure that the
TLS Extensions are compiled into openssl with the 'enable-tlsext' flag. Once you have
recompiled or reinstalled OpenSSL with TLS Extensions you will have to recompile mod_ssl
to allow it to recognize SNI support.
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