Friday Oct 11, 2013

Configuring Server Name Indication (SNI) in Oracle Traffic Director 11.1.1.6 and 11.1.1.7

What is SNI ? It is explained very well in http://en.wikipedia.org/wiki/Server_Name_Indication

If your SSL server needs certificate(s) for different domains, you can choose one of the different options :
  • Use multiple certificates using SNI feature (configure server to return different certificates for different domains) - recommended
  • Use a single certificate with SubjectAltName Extension (one hostname in CN and other hostnames in SubjectAltName extension in the certificate)
  • Use a single certificate with wild card in subject (lets say certificate with "CN=*.*.oracle.com", so it will be valid for different domains) - not preferred
  • Notes

    • Unbound Virtual Server: <virtual-server> doesn't have <http-listener> as a sub element.
    • Bound Virtual Server: <virtual-server> has a <http-listener> sub element, it is said to be bound to that http listener.
    • To figure out which Virtual server is the Default Virtual Server for a listener, look at the Virtual Server name in <default-virtual-server> of <http-listener> in server.xml.

    How to configure SNI in Oracle Traffic Director

    In this blog I will cover the following

    Enable SSL on an HTTP listener and create a certificate for it. Create two Virtual Servers both bound to an HTTP listener. One of the Virtual Server contains a certificate and the other doesn't. Send SNI and non-SNI requests to those two Virtual Servers.

    Create and add certificate for the default Virtual Server(which could be unbound or bound) and add <host> element value of <host> of our Virtual Server which doesn't have a certificate. Send a SNI request to the virtual server which doesn't have a certificate, it returns certificate from the default virtual server.

    What we will find out  is

    • If SNI host is NOT sent by the browser in SSL Handshake, then the server sends the certificate from the http listener. --------- 1
    • else (i.e. if SNI host is sent by the browser in SSLHandshake)
      • If SNI Host sent by browser doesn't match with a <host> element in any of the bound Virtual server  - goto STEP 2
      • else (i.e. If SNI host sent by browser matches with <host> element of any bound Virtual Server)
        • If that Virtual Server has certificate,  the server sends the certificate from the Virtual Server. ----------- 2
        • else (that Virtual Server DOES NOT have a certificate) - goto STEP 2

    STEP 2: get the default Virtual Server for this http listener :

      • If the default virtual Server DOES NOT have a certificate, then the server sends the cert from the http listener ------- 3
      • else (i.e. If the default virtual Server has a certificate) then the server sends the cert from this default Virtual Server ------- 4

    Exercise for readers : If Virtual Server has certificate of only one Type either ECC or RSA,  but the http listener has two types of certs one each of ECC and RSA (this should not happen in ideal case), then the server will send Virtual Server's cert has OR http listener certificate depending on the cipher requested in SSL Handshake.

     Files  Contents
    sni-abc.req
    HEAD /index.html HTTP/1.1
    Host: abc
    Connection: close
     sni-anyhost.req HEAD /index.html HTTP/1.1
    Host: anyOtherValue
    Connection: close
     sni-nocertvs.req HEAD /index.html HTTP/1.1
    Host: www.nocertvs.com
    Connection: close

    TSTCLNT="tstclnt" is NSS tool to send SSL requests to the server.

    1. Install OTD

    2. Start the Origin Server

    3. Start OTD Admin Server

    4. Create self signed cert for the http listener with subject name "www.ls.com" (for easy identification) and nickname "Server-Cert"

    $INSTANCE_HOME/bin/tadm create-selfsigned-cert --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --server-name=www.ls.com --nickname=Server-Cert --key-type=rsa

    CLI201 Command 'create-selfsigned-cert' ran successfully

    5. Enable SSL and set this self signed cert with nickname "Server-Cert" in the http listener

    $INSTANCE_HOME/bin/tadm set-ssl-prop --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --http-listener=http-listener-1 enabled=true server-cert-nickname=Server-Cert

    CLI201 Command 'set-ssl-prop' ran successfully

    6. Create a Virtual Server VSabc with www.abc.com <host> in server.xml  and bind it to the http listener "http-listener-1"

    $INSTANCE_HOME/bin/tadm create-virtual-server --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --host-pattern=www.abc.com --http-listener-name=http-listener-1 --origin-server-pool-name=origin-server-pool-1 VSabc

    CLI201 Command 'create-virtual-server' ran successfully

    7. Create self signed cert for the Virtual Server with subject "www.abc.com" and nickname "abc"

    $INSTANCE_HOME/bin/tadm create-selfsigned-cert --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --server-name=www.abc.com --nickname=abc --key-type=rsa

    Command 'create-selfsigned-cert' ran successfully

    8. Set this certificate with nickname "abc" and subject "www.abc.com" in the Virtual Server "VSabc"

    $INSTANCE_HOME/bin/tadm set-virtual-server-prop --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --vs=VSabc server-cert-nickname=abc

    CLI201 Command 'set-virtual-server-prop' ran successfully

    9. Create a Virtual Server VSnocertvs with "www.nocertvs.com" <host> in server.xml

    $INSTANCE_HOME/bin/tadm create-virtual-server --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --host-pattern=www.nocertvs.com --http-listener-name=http-listener-1 --origin-server-pool-name=origin-server-pool-1 VSnocertvs

    CLI201 Command 'create-virtual-server' ran successfully

    10. Set the error log level to "finest" if you wish to see log messages are logged for SNI at all levels

    $INSTANCE_HOME/bin/tadm set-log-prop --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG log-level=finest

    CLI201 Command 'set-log-prop' ran successfully

    11. Deploy these changes

    $INSTANCE_HOME/bin/tadm deploy-config --force --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd $CONFIG

    CLI201 Command 'deploy-config' ran successfully

    12. Start the server instance

    $INSTANCE_HOME/bin/tadm start-instance --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG

    CLI204 Successfully started the server instance.

    Testing using tstclnt / Browser

    13. Just for testing add www.abc.com  and www.nocertvs.com entries in /etc/hosts.

    cat /etc/hosts | grep www.abc.com
    cat /etc/hosts | grep www.nocertvs.com

    Ideally your DNS server must resolve these hosts to the same IP address we are using in OTD http listener.

    14. Send a request via tstclnt with -a "www.abc.com"(sends this host in SSL handshake) and in request headers Host: "www.abc.com" - should get cert from the Virtual Server VSabc with subject  DN "CN=www.abc.com"

    $TSTCLNT -c y -h $HOST -d $INSTANCE_HOME/https-$CONFIG/config -n Server-Cert -o -p $TD_PORT -2 -a www.abc.com < $DEMO_DIR/sni-abc.req

    15. Send a request via tstclnt with -a "www.nocertvs.com"(sends this host in SSL handshake) and in request headers Host: "www.nocertvs.com" - should get cert from the http listener with subject DN "CN=www.ls.com" as Virtual Server VSnocertvs with <host> www.nocerts.com doesn't have any certs.

    $TSTCLNT -c y -h $HOST -d $INSTANCE_HOME/https-$CONFIG/config -n Server-Cert -o -p $TD_PORT -2 -a www.nocertvs.com < $DEMO_DIR/sni-nocertvs.req

    16. Send a NON SNI request via tstclnt i.e. WITHOUT any host in SSL Handshake - should get the cert from the http listener with subject DN "CN=www.ls.com"

    $TSTCLNT -c y -h $HOST -d $INSTANCE_HOME/https-$CONFIG/config -n Server-Cert -o -p $TD_PORT -2 < $DEMO_DIR/sni-anyhost.req

    Summary

    • If SNI host is NOT sent by the browser in SSL Handshake, then the cert is returned from http listener.
    • If SNI host is sent by the browser in SSLHandshake and it matches with <host> element in Virtual Server, cert is returned from that Virtual Server.
    • If SNI host is sent by the browser in SSLHandshake and it matches <host> element in Virtual Server which doesn't have any certificates, certificate is returned from that http listener. - This gets a bit more complicated with Default virtual servers, will discuss in the next section.

    Advanced - Default Virtual Server tests

    17. Stop the instance

    $INSTANCE_HOME/bin/tadm stop-instance --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG

    CLI205 Successfully stopped the server instance.

    18. Create self signed cert with subject "www.defaultvscert.com" for the Default Virtual Server (Virtual Server in <default-virtual-server> of http-listener in server.xml i.e. in our case it is Virtual server with vs name $CONFIG)

    $INSTANCE_HOME/bin/tadm create-selfsigned-cert --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --server-name=www.defaultvscert.com --nickname=defaultvscert --key-type=rsa

    CLI201 Command 'create-selfsigned-cert' ran successfully

    19. Set this certificate with subject "www.defaultvscert.com" in the Default Virtual Server (vs name $CONFIG)

    $INSTANCE_HOME/bin/tadm set-virtual-server-prop --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG --vs=$CONFIG server-cert-nickname=defaultvscert

    CLI201 Command 'set-virtual-server-prop' ran successfully

    20. Deploy the changes

    $INSTANCE_HOME/bin/tadm deploy-config --force --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd $CONFIG

    CLI201 Command 'deploy-config' ran successfully

    21. Start the instance

    $INSTANCE_HOME/bin/tadm start-instance --user=admin --port=$TD_ADMIN_PORT --password-file=$DEMO_DIR/admin.passwd --config=$CONFIG

    CLI204 Successfully started the server instance.

    22. Send a request via tstclnt with -a "www.nocertvs.com"(sends this host in SSL handshake) and in request headers Host: "www.nocertvs.com" - should get cert from default virtual server subject DN: CN=www.defaultvscert.com"

    $TSTCLNT -c y -h $HOST -d $INSTANCE_HOME/https-$CONFIG/config -n Server-Cert -o -p $TD_PORT -2 -a www.nocertvs.com < $DEMO_DIR/sni-nocertvs.req

    Summary

    If SNI host is sent by the browser in SSL Handshake,

    • look for every Virtual Server bound to that http listener if it has <host> element whose value matches with it,
      • if that VS has certs - return cert from this VS.
      • if that VS doesnt have any certs, then
        • get the default Virtual Server(default-virtual-server>) for this http listener(it may be bound or it may be unbound),
          • if default VS has a certificate - return cert from this default VS
          • else  - return the certificates form http listener.

    FLOW CHART OF SNI


Thursday Mar 31, 2011

SNI and bench marking tools - ab and siege

SNI and bench marking tools - ab and siege

I wanted to do some performance measurements on some SNI server using some too. I evaluated two tools.

1. "ab" (Apache HTTP server benchmarking tool)

So I have to build "ab" so that it takes HTTPS URL and not just HTTP URL and sends TLS SNI extension in SSL handshake.

1.1. Download OpenSSL and Apache source code

I downloaded OpenSSL source code (openssl-1.0.0d.tar) from http://www.openssl.org/source/ and Apache source code from http://httpd.apache.org/ (httpd-2.3.11-beta.tar and httpd-2.3.11-beta-deps.tar).

But I had to make the following two changes in Apache code.

1.2. Modify configure.in

$diff configure.in configure.in.ORIGINAL
611,614d610
< if test "$enable_ssl" != "no"; then
<   APR_ADDTO(DEFS, "-DAB_USE_SSL")
< fi
<

I took these changes from http://www.mail-archive.com/dev@httpd.apache.org/msg25661.html

1.3. Modify support/ab.c

First I tried  calling the function SSL_set_tlsext_host_name(c->ssl, host_field); but it gave undefined symbol error, so I used SSL_ctrl function instead.

$diff ab.c ab.c.orig
184d183
< #include <openssl/tls1.h> /\* for TLSEXT_NAMETYPE_host_name \*/
1182d1180
<
1244,1245d1241
<         SSL_ctrl(c->ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, host_field);
< 

1.4. Building and Installing OpenSSL and Apache

I built and installed OpenSSL and Apache as given in

http://www.linuxquestions.org/questions/linux-server-73/openssl-support-for-sni-and-tls-799387/#10


OpenSSL :

$./config --prefix=/usr/local --openssldir=/usr/local/openssl enable-tlsext shared
$make && make install


Apache :

$LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include/ ./configure --enable-so --enable-ssl --enable-rewrite --enable-unique-id --with-ssl=/usr/local/
$make && make install

1.5. Send a test request using "ab" and confirm using ssltap

Set LD_LIBRARY_PATH to the OpenSSL directory (containing libssl.so) :

    $export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH

Confirm that ab -help shows "http[s]" in the usage as shown below :

   $/usr/local/apache2/bin/ab -help

   Usage: ./ab [options] [http[s]://]hostname[:port]/path

Now send a single request and route it to the server using ssltap to confirm if "ab" is working fine :

$./ab -n 1 -c 1 -f TLS1 https://www.foo.com:1924/abc.html

ssltap output shows that the server name "www.foo.com"  was sent in SSL Handshake :


$ssltap -s -l -p 1924 foo.com:port

--> [
  (230 bytes of 225)
  SSLRecord { [Thu Mar 31 19:43:21 2011]
     type    = 22 (handshake)
     version = { 3,1 }
     length  = 225 (0xe1)
     handshake {
        type = 1 (client_hello)
        length = 221 (0x0000dd)
           ClientHelloV3 {
              client_version = {3, 1}
              random = {...}
              session ID = {
                  length = 0
                  contents = {...}
              }
              cipher_suites[46] = {

...             } ...             extensions[88] = {

 extension type server_name, length [16] = {

  0: 00 0e 00 00  ... 2e 63 6f 6d  | .....www.foo.com } ...


2. siege

Downloaded  siege-2.70.tar.gz from ftp://ftp.joedog.org/pub/siege/siege-2.70.tar.gz

$gunzip siege.tar.gz

$tar -xvf siege.tar

$cd siege-2.70

Make these code changes

$diff client.c client.c.orig
292c292
<     if (SSL_initialize(C, U->hostname)==FALSE) {
---
>     if (SSL_initialize(C)==FALSE) {

$diff ssl.h ssl.h.orig
52c52
< BOOLEAN SSL_initialize(CONN \*C, const char \*servername);
---
> BOOLEAN SSL_initialize(CONN \*C);

$diff ssl.c ssl.c.orig
43d42
< #include <tls1.h>
67c66
< SSL_initialize(CONN \*C, const char \*servername)
---
> SSL_initialize(CONN \*C)
137,138d135
<   SSL_ctrl(C->ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME,
<            TLSEXT_NAMETYPE_host_name, servername);

Build and install siege :

$./configure --with-ssl=/usr/local/


$make

$make install

$export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH

Run siege

$/usr/local/bin/siege -c 10 -t1M https://www.foo.com:3333/index.html

you can confirm that siege sent SNI TLS extension using ssltap.

3. References

About

Meena Vyas

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today