]> granicus.if.org Git - apache/blob - test/make_sni.sh
Clarify the text a little and use the vhost terminology.
[apache] / test / make_sni.sh
1 #!/bin/sh
2 #
3 # Licensed to the Apache Software Foundation (ASF) under one or more
4 # contributor license agreements.  See the NOTICE file distributed with
5 # this work for additional information regarding copyright ownership.
6 # The ASF licenses this file to You under the Apache License, Version 2.0
7 # (the "License"); you may not use this file except in compliance with
8 # the License.  You may obtain a copy of the License at
9 #
10 #     http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # This script will populate a directory 'sni' with 3 sites, httpd.conf
19 # and certificates as to facilitate testing of TLS server name 
20 # indication support (RFC 4366) or SNI.
21 #
22 # $Id$
23 #
24 OPENSSL=${OPENSSL:-openssl}
25 DOMAIN=${DOMAIN:-my-sni-test.org}
26 DIR=${DIR:-$PWD/sni}
27 NAMES=${NAMES:-ape nut pear apple banana}
28
29 args=`getopt fd:D: $*`
30 if [ $? != 0 ]; then
31     echo "Syntax: $0 [-f] [-d outdir] [-D domain ] [two or more vhost names ]"
32     echo "    -f        Force overwriting of outdir (default is $DIR)"
33     echo "    -d dir    Directory to create the SNI test server in (default is $DIR)"
34     echo "    -D domain Domain name to use for this test (default is $DOMAIN)"
35     echo "    [names]   List of optional vhost names (default is $NAMES)"
36     echo 
37     echo "Example:"
38     echo "    $0 -D SecureBlogsAreUs.com peter fred mary jane ardy"
39     echo 
40     exit 1
41 fi
42 set -- $args
43 for i
44 do
45     case "$i"
46     in
47         -f)
48             FORCE=1
49             shift;;
50         -d)
51             DIR=$2; shift
52             shift;;
53         -D)
54             DOMAIN=$2; shift
55             shift;;
56         --) 
57             shift; break;
58     esac
59 done
60
61 if [ $# = 1 ]; then
62     echo "Aborted - just specifing one vhost makes no sense for SNI testing. Go wild !"
63     exit 1
64 fi
65
66 if [ $# -gt 0 ]; then
67     NAMES=$*
68 fi
69
70 if ! openssl version | grep -q OpenSSL; then
71     echo Aborted - your openssl is very old or misconfigured.
72     exit 1
73 fi
74
75 set `openssl version`
76 if test "0$2" \< "00.9"; then
77     echo Aborted - version of openssl too old, 0.9 or up required.
78     exit 1 
79 fi
80
81 if test -d ${DIR} -a "x$FORCE" != "x1"; then
82     echo Aborted - already an ${DIR} directory. Use the -f flag to overwrite.
83     exit 1
84 fi
85
86 mkdir -p ${DIR} || exit 1
87 mkdir -p ${DIR}/ssl ${DIR}/htdocs ${DIR}/logs || exit 1
88         
89
90 # Create a 'CA' - keep using different serial numbers
91 # as the browsers get upset if they see an identical 
92 # serial with a different pub-key.
93 #
94 # Note that we're not relying on the 'v3_ca' section as
95 # in the default openssl.conf file - so the certificate
96 # will be without the basicConstraints = CA:true and
97 # keyUsage = cRLSign, keyCertSign values. This is fine
98 # for most browsers.
99 #
100 serial=$$
101 openssl req -new -nodes -batch \
102     -x509  \
103     -days 10 -subj '/CN=Da Root/O=SNI testing/' -set_serial $serial \
104     -keyout ${DIR}/root.key -out ${DIR}/root.pem  \
105     || exit 2
106
107
108 echo '# To append to your hosts file' > ${DIR}/hosts
109 cat > ${DIR}/httpd-sni.conf << EOM
110 # To append to your httpd.conf file'
111 Listen 127.0.0.1:443
112 NameVirtualHost 127.0.0.1:443
113
114 LoadModule ssl_module modules/mod_ssl.so
115
116 SSLRandomSeed startup builtin
117 SSLRandomSeed connect builtin
118
119 LogLevel debug
120 TransferLog ${DIR}/logs/access_log
121 ErrorLog ${DIR}/logs/error_log
122
123 # You'll get a warning about this.
124 #
125 SSLSessionCache none
126
127 <Directory />
128     Options None
129     AllowOverride None
130     Require all denied
131 </Directory>
132
133 <Directory "${DIR}/htdocs">
134     allow from all
135     Require all granted
136 </Directory>
137
138 # This first entry is also the default for non SNI
139 # supporting clients.
140 #
141 EOM
142
143 INFO="and also the site you see when the browser does not support SNI."
144
145 for n in ${NAMES}
146 do
147     dw  FQDN=$n.$DOMAIN
148     serial=`expr $serial + 1`
149
150     # Create a certificate request for this host.
151     #
152     openssl req -new -nodes -batch \
153         -days 9 -subj "/CN=$FQDN/O=SNI Testing/" \
154         -keyout ${DIR}/$n.key -out ${DIR}/$n.req -batch  \
155                 || exit 3
156
157     # And get it signed by our root authority.
158     #
159     openssl x509 -text -req \
160         -CA ${DIR}/root.pem -CAkey ${DIR}/root.key \
161         -set_serial $serial -in ${DIR}/$n.req -out ${DIR}/$n.pem \
162                 || exit 4
163
164         cat ${DIR}/$n.pem ${DIR}/$n.key > ${DIR}/ssl/$n.crt
165         rm ${DIR}/$n.req ${DIR}/$n.key ${DIR}/$n.pem
166
167         LST="$LST
168         https://$FQDN/index.html"
169
170         echo "127.0.0.1         $FQDN $n" >> ${DIR}/hosts
171
172     # Create and populate a docroot for this host.
173     #
174     mkdir -p ${DIR}/htdocs/$n || exit 1
175     echo We are $FQDN $INFO > ${DIR}/htdocs/$n/index.html || exit 1
176
177     # And change the info text - so that only the default/fallback site
178     # gets marked as such.
179     #
180     INFO="and you'd normally only see this site when there is proper SNI support."
181
182     # And create a configuration snipped.
183     #
184     cat >> ${DIR}/httpd-sni.conf << EOM
185 <VirtualHost 127.0.0.1:443>
186     SSLEngine On
187     ServerName $FQDN:443
188     DocumentRoot ${DIR}/htdocs/$n
189     SSLCertificateChainFile ${DIR}/root.pem
190     SSLCertificateFile ${DIR}/ssl/$n.crt
191     TransferLog ${DIR}/logs/access_$n
192 </VirtualHost>
193
194 EOM
195
196 done
197
198 cat << EOM
199 SNI Files generated
200 ===================
201
202 The directory ${DIR}/sni has been populated with the following
203
204 -       root.key|pem    Certificate authority root and key. (You could
205                         import the root.pem key into your browser to
206                         quell warnings about an unknown authority).
207
208 -       hosts           /etc/hosts file with fake entries for the hosts
209
210 -       htdocs          directory with one docroot for each domain,
211                         each with a small sample file.
212
213 -       ssl             directory with an ssl cert (signed by root)
214                         for each of the domains).
215
216 -       logs            logfiles, one for each domain and an
217                         access_log for any misses.
218
219 SNI Test
220 ========
221
222 A directory ${DIR}/sni has been created. Run an apache
223 server against it with
224
225     .../httpd -f ${DIR}/httpd-sni.conf
226
227 and keep an eye on ${DIR}/logs/... When everything 
228 is fine you will see an entries like:
229
230     Feb 11 16:12:26 2008] [debug] Init: 
231         SSL server IP/port overlap: ape.*:443 (httpd-sni.conf:24) vs. jane.*:443 (httpd-sni.conf:42)
232
233 for each vhost configured and a concluding warning:
234
235     [Mon Feb 11 16:12:26 2008] [warn] Init: 
236         Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)
237
238 HOWEVER - If you see an entry like
239
240     [Mon Feb 11 15:41:41 2008] [warn] Init: 
241         You should not use name-based virtual hosts in conjunction with SSL!!
242
243 then you are either using an OpenSSL which is too old and/or you need to ensure that the
244 TLS Extensions are compiled into openssl with the 'enable-tlsext' flag. Once you have
245 recompiled or reinstalled OpenSSL with TLS Extensions you will have to recompile mod_ssl
246 to allow it to recognize SNI support.
247
248 Meanwhile add 'hosts' to your c:\windows\system32\drivers\etc\hosts
249 or /etc/hosts file as to point the various URL's to your server:
250 $LST
251
252 and verify that each returns its own name (and an entry in its
253 own ${DIR}/logs) file).
254
255 EOM
256 exit 0