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


Tuesday Nov 06, 2012

Interesting articles and blogs on SPARC T4

Interesting articles and blogs on SPARC T4 processor

I have consolidated all the interesting information I could get on SPARC T4 processor and its hardware cryptographic capabilities.  Hope its useful.

1. Advantages of SPARC T4 processor

Most important points in this T4 announcement are :

"The SPARC T4 processor was designed from the ground up for high speed security and has a cryptographic stream processing unit (SPU) integrated directly into each processor core. These accelerators support 16 industry standard security ciphers and enable high speed encryption at rates 3 to 5 times that of competing processors. By integrating encryption capabilities directly inside the instruction pipeline, the SPARC T4 processor eliminates the performance and cost barriers typically associated with secure computing and makes it possible to deliver high security levels without impacting the user experience."

Data Sheet has more details on these :

"New on-chip Encryption Instruction Accelerators with direct non-privileged support for 16 industry-standard cryptographic algorithms plus random number generation in each of the eight cores: AES, Camellia, CRC32c, DES, 3DES, DH, DSA, ECC, Kasumi, MD5, RSA, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512"

I ran "isainfo -v" command on Solaris 11 Sparc T4-1 system. It shows the new instructions as expected :

$ isainfo -v
64-bit sparcv9 applications
crc32c cbcond pause mont mpmul sha512 sha256 sha1 md5 camellia kasumi des aes ima hpc vis3 fmaf asi_blk_init vis2 vis popc
32-bit sparc applications
  crc32c cbcond pause mont mpmul sha512 sha256 sha1 md5 camellia kasumi des aes ima hpc vis3 fmaf asi_blk_init vis2 vis popc v8plus div32 mul32

2. Dan Anderson's Blog have some interesting points about how these can be used :

"New T4 crypto instructions include: aes_kexpand0, aes_kexpand1, aes_kexpand2, 
aes_eround01, aes_eround23, aes_eround01_l, aes_eround_23_l, aes_dround01, aes_dround23, aes_dround01_l, aes_dround_23_l.


Having SPARC T4 hardware crypto instructions is all well and good, but how do we access it ?

The software is available with Solaris 11 and is used automatically if you are running Solaris a SPARC T4.  It is used internally in the kernel through kernel crypto modules. It is available in user space through the PKCS#11 library."

3. Dan Anderson's Blog on Where's the Crypto Libraries?

Although this was written in 2009 but still is very useful

"Here's a brief tour of the major crypto libraries shown in the digraph:
  • The libpkcs11 library contains the PKCS#11 API (C_\*() functions, such as C_Initialize()).
  • That in turn calls library pkcs11_softtoken or pkcs11_kernel, for userland or kernel crypto providers. The latter is used mostly for hardware-assisted cryptography (such as n2cp for Niagara2 SPARC processors), as that is performed more efficiently in kernel space with the "kCF" module (Kernel Crypto Framework). Additionally, for Solaris 10, strong crypto algorithms were split off in separate libraries, pkcs11_softtoken_extra
  • libcryptoutil contains low-level utility functions to help implement cryptography.
  • libsoftcrypto (OpenSolaris and Solaris Nevada only) implements several symmetric-key crypto algorithms in software, such as AES, RC4, and DES3, and the bignum library (used for RSA).
  • libmd implements MD5, SHA, and SHA2 message digest algorithms"

4. Dan Anderson's Blog on  How to tell if SPARC T4 crypto is being used?

5. Difference in T3 and T4

Diagram in this blog is good and self explanatory.

Jeff's blog also highlights the differences 

"The T4 servers have improved crypto acceleration, described at https://blogs.oracle.com/DanX/entry/sparc_t4_openssl_engine. It is "just built in" so administrators no longer have to assign crypto accelerator units to domains - it "just happens". Every physical or virtual CPU on a SPARC-T4 has full access to hardware based crypto acceleration at all times. .... For completeness sake, it's worth noting that the T4 adds more crypto algorithms, and accelerates Camellia, CRC32c, and more SHA-x."

6. About performance counters

In this blog, performance counters are explained :

  • "Note that unlike T3 and before, T4 crypto doesn't require kernel modules like ncp or n2cp, there is no visibility of crypto hardware with kstats or cryptoadm.
  • T4 does provide hardware counters for crypto operations. You can see these using cpustat: cpustat -c pic0=Instr_FGU_crypto 5
  • You can check the general crypto support of the hardware and OS with the command "isainfo -v".
  • Since T4 crypto's implementation now allows direct userland access, there are no "crypto units" visible to cryptoadm.  "

For more details refer Martin's blog as well.

7. How to turn off  SPARC T4 or Intel AES-NI crypto acceleration

 I found this interesting blog from Darren about how to turn off  SPARC T4 or Intel AES-NI crypto acceleration.

"One of the new Solaris 11 features of the linker/loader is the ability to have a single ELF object that has multiple different implementations of the same functions that are selected at runtime based on the capabilities of the machine. The alternate to this is having the application coded to call getisax(2) system call and make the choice itself. We use this functionality of the linker/loader when we build the userland libraries for the Solaris Cryptographic Framework (specifically libmd.so and libsoftcrypto.so)

The Solaris linker/loader allows control of a lot of its functionality via environment variables, we can use that to control the version of the cryptographic functions we run. To do this we simply export the LD_HWCAP environment variable with values that tell ld.so.1 to not select the HWCAP section matching certain features even if isainfo says they are present. This will work for consumers of the Solaris Cryptographic Framework that use the Solaris PKCS#11 libraries or use libmd.so interfaces directly. For SPARC T4 : export LD_HWCAP="-aes -des -md5 -sha256 -sha512 -mont -mpul" .. For Intel systems with AES-NI support: export LD_HWCAP="-aes""

Note that LD_HWCAP is explained in http://docs.oracle.com/cd/E23823_01/html/816-5165/ld.so.1-1.html

"LD_HWCAP, LD_HWCAP_32, and LD_HWCAP_64 -  Identifies an alternative hardware capabilities value... A “-” prefix results in the capabilities that follow being removed from the alternative capabilities."

8. Whitepaper on High Performance Security For Oracle Database and Fusion Middleware Applications using SPARC T4

This whitepaper on "High Performance Security For Oracle Database and Fusion Middleware Applications using SPARC T4 explains more details. It has DTrace scripts which may come in handy :

"To ensure the hardware-assisted cryptographic acceleration is configured to use and working with the security scenarios, it is recommended to use the following Solaris DTrace script. "

#!/usr/sbin/dtrace -s

pid$target::*rsa*:entry,

pid$target::*yf*:entry

{

    @ops[probemod, probefunc] = count();

}

tick-1sec

{

    printa(@ops);

    trunc(@ops);

}

Note that I have slightly modified the D Script to have *rsa* and to make it work for both Solaris 10 and 11  as per recommendations from Chi-Chang Lin.

For Solaris 11, the T4 optimization is implemented in libsoftcrypto.so while it is in pkcs11_softtoken_extra.so for Solaris 10. So just add these two probes for Solaris 10 :

9. References

Friday Mar 02, 2012

Using tshark to debug SSL connections

Jyri had explained in his blog how to use ssldump to debug SSL connections. We can also use tshark. On my Linux server, tshark is installed in /usr/sbin/tshark.

Support team guys need these steps for finding out what is happening. First try to reproduce the problem in a test environment with self-signed certificate and follow the steps given in this blog.

I started Oracle iPlanet Web Server 7.0 instance on IP lets say 11.111.111.111 and port 15000.

Exporting Private Key from NSS DB

In NSS Database, I have a Server Certificate named "Server-Cert" as shown below.

$ cd <WS_install-root>/https-<instance>/config

$ ../../bin/certutil -L -d .

Certificate Nickname                         Trust Attributes
                                             SSL,S/MIME,JAR/XPI
Server-Cert                                     u,u,u

First use pk12util to extract server certificate and its key into a file "server.keycert".

$ ../../bin/pk12util -o server.keycert -n "Server-Cert" -d .

Enter Password or Pin for "NSS Certificate DB": nssdbpassword


Enter password for PKCS12 file: pkcs12password
Re-enter password: pkcs12password


pk12util: PKCS12 EXPORT SUCCESSFUL


then I use openssl to get just the RSA private key

$ openssl pkcs12 -nodes -in server.keycert -out key.pem -nocerts -nodes
Enter Import Password: pkcs12password
MAC verified OK 

$ rm server.keycert

If you look at the file, its contents are like :

$ cat key.pem
Bag Attributes
    friendlyName: Server-Cert
    localKeyID: ...
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

Edit the file key.pem manually and remove the first 4 lines.

Now the file starts with line "-----BEGIN RSA PRIVATE KEY-----" and end with "-----END RSA PRIVATE KEY-----"

Note that we should be very careful with this key as its not so safe to leave it unprotected.

You can protect it by another password if you like.

I would prefer if wireshark can take NSS DB or Oracle Wallets as input directly.

Running tshark

Now as root run tshark

$ /usr/sbin/tshark -o "ssl.desegment_ssl_records: TRUE" \

-o "ssl.desegment_ssl_application_data: TRUE" \

-o "ssl.keys_list:11.111.111.111,15000,http,key.pem" \

-o "ssl.debug_file:ssldebug.log" \

-f "tcp port 15000" \

-R "ssl" \

-V -x 2>&1 | tee tshark.log

when I had not given IP address in ssl.key_list, it wasn't associating key to some of my connections.

Note that 
I used capture filter "tcp port 15000" and display filter "ssl". 
I used -V to show more verbose output and 
I also used -x to get both hex and ASCII dumps. 

You can try your own options.

Now send a request through a browser to https://11.111.111.1111:15000/index.html, close the browser and after a while, press control c on the window where tshark is running and kill it.

Delete the private key file key.pem.

ssldebug.log should have a message that says key was loaded successfully

$ grep -i "private key" ssldebug.log

Private key imported: KeyID ...
ssl_init private key file key.pem successfully loaded

Note that ssldebug.log MUST NOT contain any error messages about key not being used etc.

Now look at tshark.log, look for "Secure Socket Layer" sections one such section is shown below :

Secure Socket Layer
  SSL Record Layer: Handshake Protocol: Client Hello
      Content Type: Handshake (22)
      Version: TLS 1.0 (0x0301)
      Length: 168
      Handshake Protocol: Client Hello
          Handshake Type: Client Hello (1)
          Length: 164
          Version: TLS 1.0 (0x0301)
          Random
              gmt_unix_time: Mar  2, 2012 00:01:26.000000000
              random_bytes: .......

          Session ID Length: 0
          Cipher Suites Length: 72
          Cipher Suites (36 suites)
            Cipher Suite: Unknown (0x00ff)
            Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
            Cipher Suite: TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088)
...


In the end you can see SSL data being decrypted :

Decrypted SSL data (1 bytes):

0000  48                                                H

 Decrypted SSL data (225 bytes):

0000  54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d 0a   TTP/1.1 200 OK..
...
0040  46 72 69 2c 20 30 32 20 4d 61 72 20 32 30 31 32   Fri, 02 Mar 2012
0050  20 30 39 3a 31 32 3a 32 38 20 47 4d 54 0d 0a 4c    09:12:28 GMT..L
0060  61 73 74 2d 6d 6f 64 69 66 69 65 64 3a 20 57 65   ast-modified: We
0070  64 2c 20 32 39 20 46 65 62 20 32 30 31 32 20 31   d, 29 Feb 2012 1
0080  31 3a 33 38 3a 31 39 20 47 4d 54 0d 0a 43 6f 6e   1:38:19 GMT..Con
0090  74 65 6e 74 2d 6c 65 6e 67 74 68 3a 20 31 39 0d   tent-length: 19.
00a0  0a 45 74 61 67 3a 20 22 31 33 2d 34 66 34 65 30   .Etag: "13-4f4e0
00b0  65 32 62 22 0d 0a 41 63 63 65 70 74 2d 72 61 6e   e2b"..Accept-ran
00c0  67 65 73 3a 20 62 79 74 65 73 0d 0a 0d 0a 54 68   ges: bytes....Th
00d0  69 73 20 69 73 20 69 6e 64 65 78 2e 68 74 6d 6c   is is index.html
00e0  0a                                                .

This log shows different stages of SSL

$grep "Handshake Protocol" tshark.log

    Handshake Protocol: Client Hello
    Handshake Protocol: Server Hello
    Handshake Protocol: Certificate
    Handshake Protocol: Server Hello Done
    Handshake Protocol: Client Key Exchange
    Handshake Protocol: Finished
    Handshake Protocol: Finished

Exporting Private Key from Wallet

If your product uses Oracle wallet instead of NSS DB, to extract the key and certificate from the Wallet you can use openssl command as shown below

$openssl pkcs12 -in ewallet.p12 -passin pass:walletpassword -out ewallet.txt -nodes

MAC verified OK

If you look at this file it has  "-----BEGIN RSA PRIVATE KEY-----" and "-----END RSA PRIVATE KEY-----".

$cat ewallet.txt


Bag Attributes
    localKeyID: ...
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----

...
-----END RSA PRIVATE KEY-----


Bag Attributes
    localKeyID: ...
subject=/C=US/CN=*.oracle.com
issuer=/C=US/CN=root
-----BEGIN CERTIFICATE-----

...

-----END CERTIFICATE-----

...

Edit this file and copy only the lines starting with " -----BEGIN RSA PRIVATE KEY-----" and ending with " -----END RSA PRIVATE KEY-----" into a new file key.pem. Rest of the steps remain the same.

I wanted to check if we are getting "close notify" in a connection, I saw in the presentation

http://www.powershow.com/view/29ec1-OWNkM/SSL_Troubleshooting_with_Wireshark_and_Tshark_flash_ppt_presentation

useful commands to get a particular field in tshark:

$tshark -G fields | fgrep "ssl." and hence used
$tshark -R "ssl.alert_message"

References

  1. http://wiki.wireshark.org/SSL
  2. https://forums.oracle.com/forums/thread.jspa?threadID=830575
  3. http://www.powershow.com/view/29ec1-OWNkM/SSL_Troubleshooting_with_Wireshark_and_Tshark_flash_ppt_presentation

Friday Sep 18, 2009

Two WAY SSL in Sun Web Server 7.0 reverse proxy server and origin server

Two Way SSL in Oracle iPlanet Web Server 7.0 reverse proxy server and origin server

Origin Server <--- HTTPS ---> Reverse Proxy Server <--- HTTPS ---> client/Browser

There are various SSL and non SSL configurations we can have for Reverse Proxy and Origin Servers

  1. Origin Server <--- HTTP ---> Reverse Proxy Server <--- HTTP ---> client/Browser
  2. Origin Server <-- HTTP ---> Reverse Proxy Server <-- HTTPS --> client/Browser i.e. Reverse proxy SSL termination End point
  3. Origin Server <-- HTTPS ---> Reverse Proxy Server <-- HTTP --> client/Browser
  4. Origin Server <-- HTTPS ---> Reverse Proxy Server <-- HTTPS --> client/Browser

In this blog I will try out SCENARIO 4 - with and without enabling client-auth in reverse proxy server and origin server instance, with and without ssl-client-config SAF.

For this I have setup two Oracle iPlanet Web Server 7.0 update 9 instances.

One acting as a reverse proxy (instance name rps) and the other origin server(instance name origs) that serves the request.


This blog is split into the following four sub parts

Enable SSL on both Origin Server and Reverse Proxy Server AND
  1. no client authentication anywhere - Origin Server sends its Server certificate to Reverse Proxy Server.
  2. enable client-auth on Reverse Proxy Server - client/browser sends its certificate to Reverse Proxy Server AND Origin Server sends its certificate to Reverse Proxy server.
  3. enable client-auth on Origin Server, set ssl-client-config SAF on Reverse Proxy Server(OPTIONAL) - Origin Server and Reverse Proxy Server both send their certificates to each other.
  4. enable client-auth on Origin Server and Reverse Proxy Servers, set ssl-client-config SAF on Reverse Proxy Server(OPTIONAL) - client/browser sends its certificate to Reverse Proxy Server AND Origin Server and Reverse Proxy Server send certificates to each other.


1. Enable SSL on both Origin Server and Reverse Proxy Server, no client authentication anywhere - Origin Server sends its Server certificate to Reverse Proxy Server.

1.1 Install Server Certificate in Reverse Proxy Server instance

I created self signed certificate in reverse proxy server. You can use Admin Server CLI to create a self-signed certificate

wadm>create-selfsigned-cert --config=rps

--server-name=www.rps.com --nickname=Server-Cert-RP

wadm>deploy-config rps

Or you can use certutil followed by pull-config

$cd <reverse-proxy-install-dir>/https-rps/config
$../../bin/certutil -N -d . (if DBs do not exist already)
$../../bin/certutil -S -d . -n Server-Cert-RP 
          -s "CN=www.rps.com" -x -t "CT,CT,CT"

Verify it with certutil :

$../../bin/certutil -L -d <reverse-proxy-install-dir>/https-rps/config
Certificate Nickname                       Trust Attributes
                                           SSL,S/MIME,JAR/XPI
Server-Cert-RP                             CTu,Cu,Cu

1.2 Install Server Certificate in Origin Server instance

I created self signed certificate in origin server. You can use Admin Server CLI to create a self signed certificate

wadm>create-selfsigned-cert --config=origs

--server-name=www.origs.com --nickname=Server-Cert-OS

wadm>deploy-config origs

Or you can use certutil followed by pull-config

$cd <origin-server-install-dir>/https-rps/config
$../../bin/certutil -N -d . (if DBs do not exist already)
$../../bin/certutil -S -d . -n Server-Cert-OS 
     -s "CN=www.origs.com" -x -t "CT,CT,CT"

Verify it with certutil that the certificate exists :

$../../bin/certutil -L -d <origin-server-install-dir>/https-origs/config
Certificate Nickname                       Trust Attributes
                                           SSL,S/MIME,JAR/XPI
Server-Cert-OS                             CTu,Cu,Cu

1.3 Changes made in Reverse Proxy Web Server Instance

1.3.1 Run create-reverse-proxy CLI from Administration server

wadm>create-reverse-proxy --config rps --vs rps --uri-prefix=/ 
    --server=https://www.origs.com:4444

\*obj.conf gets modified as shown below :

<Object name="default">
AuthTrans fn="match-browser" browser="\*MSIE\*" ssl-unclean-shutdown="true"
NameTrans fn="map" from="/" name="reverse-proxy-/" to="/"
...
</Object>
<Object ppath="\*">
Service fn="proxy-retrieve" method="\*"
</Object>
<Object name="reverse-proxy-/">
Route fn="set-origin-server" server="https://www.origs.com:4444"
</Object>

In obj.conf I have configured reverse proxy in such a way that all requests are redirected to origin server.

In real world situation you can if you want redirect only certain requests depending on your requirements.

1.3.2 Enable SSL in http-listener, set the server certificate nickname (if its different from "Server-Cert"). 

You can use Admin Server CLI to do these steps.

Enable SSL for this listener, set the server certificate nickname and deploy config

wadm> set-ssl-prop --config=rps --http-listener=http-listener-1

server-cert-nickname=Server-Cert-RP enabled=true

wadm>deploy-config rps

server.xml should get modified to look like

<http-listener>
    <name>http-listener-1</name>
    <port>3333</port>
    <server-name>www.rps.com</server-name>
    <default-virtual-server-name>rps</default-virtual-server-name>
   <ssl>
   <server-cert-nickname>Server-Cert-RP</server-cert-nickname>
   </ssl>
</http-listener>

1.4 Changes made in Origin Server Web Server Instance

1.4.1 Enable SSL in http-listener, set server certificate nickname (if its different from "Server-Cert") .

You can use Admin Server CLI to do these steps.
Enable SSL for this listener and set the server certificate nickname and deploy config.

wadm> set-ssl-prop --config=origs --http-listener=http-listener-1

      server-cert-nickname=Server-Cert-OS enabled=true

wadm> deploy-config origs

server.xml should get modified to look like

<http-listener>    
    <name>http-listener-1</name>  
    <port>4444</port>
    <server-name>www.origs.com</server-name>
    <ssl>
        <server-cert-nickname>Server-Cert-OS</server-cert-nickname>
    </ssl>
    <default-virtual-server-name>origs</default-virtual-server-name>
</http-listener>

1.4.2 Create a test.html file in origin server :

$cat ../docs/test.html 
This is test.html

1.5 Export Origin Server CA certificate and import it into Reverse Proxy Server NSS DBs

$../../bin/certutil -L -d https-origs/config -n Server-Cert-OS -a | tee /tmp/os.cert

$../../bin/certutil -A -n Server-Cert-OS -a -i /tmp/os.cert -d https-rps/config -t "CT,CT,CT"

Reverse Proxy Server should have two certificates

$../../bin/certutil -L -d .                
Certificate Nickname               Trust Attributes
                                   SSL,S/MIME,JAR/XPI

ServerCertRP                       CTu,Cu,Cu
ServerCertOS                       CT,C,C

1.6 Send a request through browser to Reverse Proxy Server test.html.

Origin should serve the request. You can see the request is being served from origin server.

We can check the entries in both the access logs of reverse proxy server and origin server to confirm.

Note that browser may give a warning that this reverse proxy server is not issued by a valid CA.

That's ok because its a self signed certificate.

If you install a certificate from trusted CAs this message will not come up.

1.7 Attach ssltap to confirm the SSL communication

I have attached ssltap in between origin server and reverse proxy server

$ssltap -l -p 1924 -s origs:4444
    Connection #1 [Mon Nov  8 13:46:48 2010]
    Connected to origs:4444

--> [ (client to server)        
    recordLen = 75 bytes
    (75 bytes of 75)
    [Mon Nov  8 13:46:48 2010] [ssl2]  ClientHelloV2 {
               version = {0x03, 0x01}
               cipher-specs-length = 48 (0x30)
               sid-length = 0 (0x00)
               challenge-length = 16 (0x10)
               cipher-suites = { 
                    (0x010080) SSL2/RSA/RC4-128/MD5
                    (0x030080) SSL2/RSA/RC2CBC128/MD5
                    (0x0700c0) SSL2/RSA/3DES192EDE-CBC/MD5
                    (0x060040) SSL2/RSA/DES56-CBC/MD5
                    (0x020080) SSL2/RSA/RC4-40/MD5
                    (0x040080) SSL2/RSA/RC2CBC40/MD5
                    (0x000004) SSL3/RSA/RC4-128/MD5
                    (0x00feff) SSL3/RSA-FIPS/3DESEDE-CBC/SHA
                    (0x00000a) SSL3/RSA/3DES192EDE-CBC/SHA
                    (0x00fefe) SSL3/RSA-FIPS/DES-CBC/SHA
                    (0x000009) SSL3/RSA/DES56-CBC/SHA
                    (0x000064) TLS/RSA-EXPORT1024/RC4-56/SHA
                    (0x000062) TLS/RSA-EXPORT1024/DES56-CBC/SHA
                    (0x000003) SSL3/RSA/RC4-40/MD5
                    (0x000006) SSL3/RSA/RC2CBC40/MD5
                    (0x0000ff) ????/????????/?????????/???
                    }
               session-id = { }
               challenge = { 0x4fad 0xcb84 0x9b5a 0x07a1 ... }
    }
    ]

<-- [ (server to client)
    (518 bytes of 513)
    SSLRecord { [Mon Nov  8 13:46:48 2010]
       type    = 22 (handshake)
       version = { 3,1 }
       length  = 513 (0x201)
       handshake {
          type = 2 (server_hello)
          length = 77 (0x00004d)
             ServerHello {
                server_version = {3, 1}
                random = {...}
                session ID = {
                    length = 32
                    contents = {...}
                }
                cipher_suite = (0x0004) SSL3/RSA/RC4-128/MD5
                compression method = (00) NULL
                extensions[5] = {
                  extension type 65281, length [1] = {
                    0: 00         | .
                  }
                }
             }
          type = 11 (certificate)
          length = 424 (0x0001a8)
             CertificateChain {
                chainlength = 421 (0x01a5)
                Certificate {
                   size = 418 (0x01a2)
                   data = { saved in file 'cert.001' }
                }
             }
          type = 14 (server_hello_done)
          length = 0 (0x000000)
       }
    }
    ]
    ...    
As you can see Origin Server sent one certificate cert.001 to Client(Reverse Proxy Server).
$openssl x509 -in cert.001 -text -inform DER

Certificate:
    Data: 
        Version: 3 (0x2) 
        ...
        Signature Algorithm: sha1WithRSAEncryption 
        Issuer: CN=www.origs.com 
        Validity 
            Not Before: Nov  8 08:09:20 2010 GMT
            Not After : Feb  8 08:09:20 2011 GMT
        Subject: CN=www.origs.com
       ...         

2. Enable SSL on both Origin Server and Reverse Proxy Server, enable client-auth on Reverse Proxy Server - client/browser sends its certificate to Reverse Proxy Server AND Origin Server sends its certificate to Reverse Proxy server.

Follow all the steps as step 1.

2.1 Enable client authentication on reverse proxy server 

Just change the step # 1.4.1, set client authentication as "required" also:

wadm> set-ssl-prop --config=rps --http-listener=http-listener-1 
      server-cert-nickname=Server-Cert-RP enabled=true 
      client-auth=required
server.xml of reverse proxy server should get modified to look like
<http-listener>   ...  
 <ssl> 
     <server-cert-nickname>Server-Cert-RP</server-cert-nickname>
     <client-auth>required</client-auth>
 </ssl>
</http-listener>

2.2 Test Client I used to send request to reverse proxy server

I used "tstclnt which is bundled with NSS-NSPR binaries in bin directory.

Created a test request file

$cat > sslreq.dat
GET /test.html HTTP/1.0\^M  
\^M

Create a client certificate and import it s CA as trusted CA (flag "C") in Reverse Proxy Instance NSS DBs. For faster results, I created client certificate in Reverse Proxy NSS DB itself

$../bin/certutil -S -d https-rps/config -n ClientCert -s "CN=alpha" -x -t "CT,CT,CT"

Sent request to the reverse proxy server.



$tstclnt -h www.rps.com -p 3333  -n ClientCert 
         -d https-rps/config -c n -v -o -f < sslreq.dat 
...    
tstclnt: SSL version 3.1 using 128-bit RC4 with 160-bit SHA1 MAC    
tstclnt: Server Auth: 1024-bit RSA, Key Exchange: 1024-bit RSA    
subject DN: CN=www.rps.com 
issuer  DN: CN=www.rps.com
...
HTTP/1.1 200 OK
...    
This is test.html
...

You can see the request is being served from origin server. I have used in this test client cipher "n" which is SSL3 RSA WITH RC4 128 SHA.

I can see that cipher at the time of server startup when run in <log-level>finest</log-level>.

You can verify that the ssltap output between origin Server and Reverse Proxy Server of this is same as section #1.


3. Enable SSL on both Origin Server and Reverse Proxy Server, enable client-auth on Origin Server, set ssl-client-config SAF on Reverse Proxy Server(OPTIONAL) - Origin Server and Reverse Proxy Server both send their certificates to each other.

About ssl-client-config SAF

Refer http://docs.sun.com/app/docs/doc/821-1827/gdhqy?l=en&a=view

By default reverse proxy server doesn't send the certificate to the origin server.

To send the Reverse Proxy Server certificate to the Origin Server, use "ssl-client-config" SAF and set "client-cert-nickname" parameter that takes the nickname of the client certificate to present to the Origin Server.

Follow all the steps as section 1.

3.1 OPTIONAL : Add ssl-client-config SAF in obj.conf of Reverse Proxy Server - to set the nickname of the certificate it will send to Origin Server

Modify obj.conf to have ssl-client-config SAF
ObjectType fn="ssl-client-config" client-cert-nickname="Server-Cert-RP"

Reverse Proxy Server will send any appropriate certificate it can find if this SAF ssl-client-config is not present.

3.2 Enable client-auth on Origin Server in which case Reverse Proxy Server will send certificate to Origin Server

Just change the step #s 1.4.1 and set client authentication as "required" or "optional" on Origin Server :

wadm> set-ssl-prop --config=origs --http-listener=http-listener-1
                server-cert-nickname=Server-Cert-OS enabled=true 
                client-auth=required

server.xml of origin server should get modified to look like

<http-listener>

...

 <ssl><server-cert-nickname>Server-Cert-OS</server-cert-nickname>

<client-auth>required</client-auth> </ssl>

</http-listener>

3.3 Export Reverse Proxy Server CA certificate and import it into Origin Server NSS DB

$../../bin/certutil -L -d https-rps/config -n Server-Cert-RP -a | tee /tmp/rp.cert

$../../bin/certutil -A -n Server-Cert-RP -a -i /tmp/rp.cert -d https-origs/config -t "CT,CT,CT"

Origin Server also should now have two certificates :

$../../bin/certutil -L -d .                
Certificate Nickname          Trust Attributes
                              SSL,S/MIME,JAR/XPI

ServerCertOS                  CTu,Cu,Cu
ServerCertRP                  CT,C,C

3.4 Send a test request and attach ssltap to see what's going on

Now send a request through the browser. It should serve the page.

Using ssltap we confirm that two certificates are being sent.

In this case, Client is reverse proxy server and server is origin server.

$ssltap -p 1924 -l -s origs:4444
Connection #1 [Mon Nov  8 16:26:07 2010]
Connected to origs:4444
--> [ (client to server)
recordLen = 75 bytes
(75 bytes of 75)
 [Mon Nov  8 16:26:07 2010] [ssl2]  ClientHelloV2 {
           version = {0x03, 0x01}
           cipher-specs-length = 48 (0x30)
           sid-length = 0 (0x00)
           challenge-length = 16 (0x10)
           cipher-suites = { 
                (0x010080) SSL2/RSA/RC4-128/MD5
                (0x030080) SSL2/RSA/RC2CBC128/MD5
                (0x0700c0) SSL2/RSA/3DES192EDE-CBC/MD5
                (0x060040) SSL2/RSA/DES56-CBC/MD5
                (0x020080) SSL2/RSA/RC4-40/MD5
                (0x040080) SSL2/RSA/RC2CBC40/MD5
                (0x000004) SSL3/RSA/RC4-128/MD5
                (0x00feff) SSL3/RSA-FIPS/3DESEDE-CBC/SHA
                (0x00000a) SSL3/RSA/3DES192EDE-CBC/SHA
                (0x00fefe) SSL3/RSA-FIPS/DES-CBC/SHA
                (0x000009) SSL3/RSA/DES56-CBC/SHA
                (0x000064) TLS/RSA-EXPORT1024/RC4-56/SHA
                (0x000062) TLS/RSA-EXPORT1024/DES56-CBC/SHA
                (0x000003) SSL3/RSA/RC4-40/MD5
                (0x000006) SSL3/RSA/RC2CBC40/MD5
                (0x0000ff) ????/????????/?????????/???
                }
           session-id = { }
           challenge = { 0xe793 0x10b4 0xf9b2 0x826d 0... }
}
]
<-- [ (server to client)
(577 bytes of 572)
SSLRecord { [Mon Nov  8 16:26:07 2010]
   type    = 22 (handshake)
   version = { 3,1 }
   length  = 572 (0x23c)
   handshake {
      type = 2 (server_hello)
      length = 77 (0x00004d)
         ServerHello {
            server_version = {3, 1}
            random = {...}
            session ID = {
                length = 32
                contents = {...}
            }
            cipher_suite = (0x0004) SSL3/RSA/RC4-128/MD5
            compression method = (00) NULL
            extensions[5] = {
              extension type 65281, length [1] = {
               0: 00            | .
              }
            }
         }
      type = 11 (certificate)
      length = 424 (0x0001a8)
         CertificateChain {
            chainlength = 421 (0x01a5)
            Certificate {
               size = 418 (0x01a2)
               data = { saved in file 'cert.001' }
            }
         }
      type = 13 (certificate_request)
      length = 55 (0x000037)
         CertificateRequest {
            certificate types[3] = { 01 02 40 }
            certificate_authorities[49] = {
   CN=www.rps.com
   CN=www.origs.com
            }
         }
      type = 14 (server_hello_done)
      length = 0 (0x000000)
   }
}
]
--> [ (client to server)
(750 bytes of 702, with 43 left over)
SSLRecord { [Mon Nov  8 16:26:07 2010]
   type    = 22 (handshake)
   version = { 3,1 }
   length  = 702 (0x2be)
   handshake {
      type = 11 (certificate)
      length = 430 (0x0001ae)
         CertificateChain {
            chainlength = 427 (0x01ab)
            Certificate {
               size = 424 (0x01a8)
               data = { saved in file 'cert.002' }
            }
         }
      type = 16 (client_key_exchange)
      length = 130 (0x000082)
         ClientKeyExchange {
            message = {...}
         }
      type = 15 (certificate_verify)
      length = 130 (0x000082)
   }
}
(750 bytes of 1, with 37 left over)
SSLRecord { [Mon Nov  8 16:26:07 2010]
   type    = 20 (change_cipher_spec)
   version = { 3,1 }
   length  = 1 (0x1)
}
(750 bytes of 32)
SSLRecord { [Mon Nov  8 16:26:07 2010]
   type    = 22 (handshake)
   version = { 3,1 }
   length  = 32 (0x20)
            < encrypted >
}
]
...

This shows that :

  • origin server sends the certificate(cert.001) to the reverse proxy server and
  • reverse proxy sends the certificate(cert.002) to the origin server. 
  • Origin Server sent certificate cert.001(Server-Cert-OS) to Client(Reverse Proxy).
  • and Client(Reverse Proxy Server) sent certificate cert.002(Server-Cert-RP) to Origin Server.

$openssl x509 -in cert.001 -text -inform DER Certificate: Data: 

   Version: 3 (0x2) ...     Signature Algorithm: sha1WithRSAEncryption     Issuer: CN=www.origs.com     Validity         Not Before: Nov  8 08:09:20 2010 GMT         Not After : Feb  8 08:09:20 2011 GMT     Subject: CN=www.origs.com

...

$openssl x509 -in cert.002 -text -inform DER Certificate: Data: Version: 3 (0x2) ...

Signature Algorithm: sha1WithRSAEncryption Issuer: CN=www.rps.com Validity Not Before: Nov 8 08:09:50 2010 GMT Not After : Feb 8 08:09:50 2011 GMT Subject: CN=www.rps.com

... 


4. Enable SSL on both Origin Server and Reverse Proxy Server, enable client-auth on Origin Server and Reverse Proxy Servers, set ssl-client-config SAF on Reverse Proxy Server(OPTIONAL) - client/browser sends its certificate to Reverse Proxy Server AND Origin Server and Reverse Proxy Server send certificates to each other


Follow all the steps as step 1.

4.1 Enable client-auth on reverse proxy server 

Just change the step # 1.4.1, set client authentication as "required" also:

wadm> set-ssl-prop --config=rps --http-listener=http-listener-1 
      server-cert-nickname=Server-Cert-RP enabled=true 
      client-auth=required
server.xml of reverse proxy server should get modified to look like
<http-listener>   ...  
 <ssl> 
     <server-cert-nickname>Server-Cert-RP</server-cert-nickname>
     <client-auth>required</client-auth>
 </ssl>
</http-listener>

4.2  OPTIONAL : Add ssl-client-config SAF in obj.conf of Reverse Proxy Server - to set the nickname of the certificate it will send to Origin Server

 Modify obj.conf to have ssl-client-config SAF 

...
ObjectType fn="ssl-client-config" client-cert-nickname="Server-Cert-RP"
...

Reverse Proxy Server will send any appropriate certificate it can find if this SAF ssl-client-config is not present. 


4.3  Enable client-auth on Origin Server in which case Reverse Proxy Server will send  certificate to Origin Server

Just change the step #s 1.4.1 and set client authentication as "required" or "optional" on Origin Server :

wadm> set-ssl-prop --config=origs --http-listener=http-listener-1
                server-cert-nickname=Server-Cert-OS enabled=true 
                client-auth=required

server.xml of origin server should get modified to look like

<http-listener>

...

 <ssl><server-cert-nickname>Server-Cert-OS</server-cert-nickname>

<client-auth>required</client-auth> </ssl>

</http-listener>

4.4  Export Reverse Proxy Server CA certificate and import it into Origin Server NSS DBs

$../../bin/certutil -L -d https-rps/config -n Server-Cert-RP -a | tee /tmp/rp.cert

$../../bin/certutil -A -n Server-Cert-RP -a -i /tmp/rp.cert -d https-origs/config -t "CT,CT,CT"

Verify that Origin Server also should now have two certificates

$../../bin/certutil -L -d .                
Certificate Nickname          Trust Attributes
                              SSL,S/MIME,JAR/XPI

ServerCertOS                  CTu,Cu,Cu
ServerCertRP                  CT,C,C

4.5 OPTIONAL : Changing Log Settings in server.xml :

I have also modified access log format both in Reverse Proxy and in Origin Server
<access-log>
...    
    <format>
    %Ses->client.ip% "%Req->reqpb.clf-request%"
    %Req->srvhdrs.clf-status% %Req->srvhdrs.content-length% 
    %Ses->client.cipher% %Req->vars.auth-cert% 
    %Req->headers.proxy-auth-cert%
    </format>
</access-log>

Note the contents in between <format></format> should be in one line

I have put it in 2 lines so that its easy to see.

4.6 : Test Client used to send Request to Reverse Proxy Server

I used "tstclnt" which is bundled with NSS-NSPR binaries in bin directory. Created a test request file
$cat > sslreq.dat
GET /test.html HTTP/1.0\^M  
\^M

Create a client certificate and import it s CA as trusted CA (flag "C") in Reverse Proxy Instance NSS DBs.

For faster results, I created client certificate in Reverse Proxy NSS DB itself

$./bin/certutil -S -d https-rps/config -n ClientCert -s "CN=alpha" -x -t "CT,CT,CT"

Now send a request to the Reverse Proxy Server

$tstclnt -h www.rps.com -p 3333  -n ClientCert 
         -d https-rps/config -c n -v -o -f < sslreq.dat 
...    
tstclnt: SSL version 3.1 using 128-bit RC4 with 160-bit SHA1 MAC    
tstclnt: Server Auth: 1024-bit RSA, Key Exchange: 1024-bit RSA    
subject DN: CN=www.rps.com 
issuer  DN: CN=www.rps.com
...
HTTP/1.1 200 OK
...    
This is test.html
...

You can see the request is being served from origin server. I have used in this test client cipher "n" which is SSL3 RSA WITH RC4 128 SHA.

I can see that at the time of server startup when run in <log-level>finest</log-level>.

You can use other ciphers as well.

Access log of Reverse Proxy Web Server shows ONE certificate in auth-cert vars pblock

$cat ../logs/access
format=%Ses->client.ip% "%Req->reqpb.clf-request%" 
%Req->srvhdrs.clf-status% %Req->srvhdrs.content-length%  
%Ses->client.cipher% 
%Req->vars.auth-cert%
%Req->headers.proxy-auth-cert% 
xxx.xxx.xxx.xxx "GET /test.html HTTP/1.0" 
200 18
RC4

MIIBmDCCAQGgAwIBAgIFAJKp8cowDQYJKoZIhvcNAQEFBQAwEDEOMAwGA1UEAxMF
...
RiyrKq9SuMfqI8b++8613QMSJYwdVCFi1DrDGw==

-

Note cipher is RC4.

You can verify that in Reverse Proxy Server instance, the certificate in pblock vars->auth-cert is the Client Certificate.

$certutil -L -d https-rps/config -n ClientCert -a
-----BEGIN CERTIFICATE-----
MIIBmDCCAQGgAwIBAgIFAJKp8cowDQYJKoZIhvcNAQEFBQAwEDEOMAwGA1UEAxMF

...

RiyrKq9SuMfqI8b++8613QMSJYwdVCFi1DrDGw==
-----END CERTIFICATE-----

Access log of origin server  shows one certificate in vars->auth-cert and ONE certificate in Headers pblock in proxy-auth-cert:

$cat ../logs/access
format=%Ses->client.ip% "%Req->reqpb.clf-request%"
%Req->srvhdrs.clf-status% %Req->srvhdrs.content-length%
%Ses->client.cipher%
%Req->vars.auth-cert%
%Req->headers.proxy-auth-cert% 
xxx.xxx.xxx.xxx "GET /test.html HTTP/1.1" 
200 18
RC4 

MIIBpDCCAQ2gAwIBAgIFAJKQxLEwDQYJKoZIhvcNAQEFBQAwFjEUMBIGA1UEAxML
...
L0wNBvqTkA7a4nagsj0UFRCUxfL1AjMRDJp6v7BGQRBcx2nrvgb+Bg== 

MIIBmDCCAQGgAwIBAgIFAJKp8cowDQYJKoZIhvcNAQEFBQAwEDEOMAwGA1UEAxMF
...
RiyrKq9SuMfqI8b++8613QMSJYwdVCFi1DrDGw==

You can verify that in the Origin Server instance,

the certificate in pblock vars->auth-cert is the Reverse Proxy Server Certificate and

the certificate in pblock headers->proxy-auth-cert is the Client Certificate(browser/tstclnt sent to Reverse Proxy Server) .


You can use certutil                 

$certutil -L -d https-rps/config -n Server-Cert-RP -a -----BEGIN CERTIFICATE----- MIIBpDCCAQ2gAwIBAgIFAJKQxLEwDQYJKoZIhvcNAQEFBQAwFjEUMBIGA1UEAxML ... L0wNBvqTkA7a4nagsj0UFRCUxfL1AjMRDJp6v7BGQRBcx2nrvgb+Bg== -----END CERTIFICATE-----

OR you can use openssl to confirm

$openssl s_client -connect www.rps.com:3333 -showcerts ... Certificate chain 0 s:/CN=www.rps.com i:/CN=www.rps.com -----BEGIN CERTIFICATE----- MIIBpDCCAQ2gAwIBAgIFAJKQxLEwDQYJKoZIhvcNAQEFBQAwFjEUMBIGA1UEAxML ... L0wNBvqTkA7a4nagsj0UFRCUxfL1AjMRDJp6v7BGQRBcx2nrvgb+Bg== -----END CERTIFICATE-----

... 


ssltap output between origin server and reverse proxy server will be same as section #3 above.

References

Friday Apr 11, 2008

Intrusion detection in Sun Java System Web Server 7.0 update 2 - in experimental stages

Intrusion detection in Sun Java System Web Server 7.0 update 2 - in experimental stages

I have introduced an experimental untested intrusion detection feature in Web Server 7.0 update 2. It is currently an unsupported feature. Basically we can add in server.xml a file name which contains ModSecurity ruleset. Note that this is an experimental feature so please give me feedback about your experiences.

Additions to server.xml

Element
Possible Values Description
<config-file>
Text
This element may be present at the virtual-server level as well as at the server level. Points to a file containing ModSecurity rules. As with all file paths in server.xml it may be an absolute path or a relative path, in which case it is relative to the config directory. The file name component may contain wildcard characters to specify multiple files within the given directory. Multiple config-file elements may be present as well.

Additions to obj.conf

A new AuthTrans SAF, secrule-config, is introduced to control the behavior of the ModSecurity engine. Please make sure that this is the first (topmost) AuthTrans directive in obj.conf.

The following table describes parameters for the secrule-config function.

Parameter Description
engine              
(Optional) Indicates how SecRule directives are processed at request time.
"on" indicates that the directives should be applied.
"off" indicates that the directives should not be applied.
"detection only" indicates that the directives should be evaluated but the result of the evaluation should not be enforced.
The default value is what is set by SecRuleEngine directive (if any) in configuration file(s) specified by <config-file> element. If SecRuleEngine directive is not present, it is "off".
process-request-body (Optional) Indicates whether request bodies are processed when evaluating SecRule directives. When request body processing is enabled, the server will buffer the entire request body in memory, up to the limit defined by SecRequestBodyInMemoryLimit directive (if any) in configuration file(s) specified by <config-file> element. If SecRequestBodyInMemoryLimit directive is not present, it is "131072".
"on" indicates that request bodies should be processed.
"off" indicates that response bodies should not be processed.
The default value is what is set by SecRequestBodyAccess directive (if any) in configuration file(s) specified by <config-file> element. If SecRequestBodyAccess directive is not present, it is "off".
process-response-body (Optional) Indicates whether response bodies are processed when evaluating SecRule directives. When response body processing is enabled, the server will buffer the entire response body in memory, up to the limit defined by SecResponseBodyLimit directive (if any) in configuration file(s) specified by <config-file> element. If SecResponseBodyLimit directive is not present, it is "524288".
"on" indicates that response bodies should be processed.
"off" indicates that response bodies should not be processed.
The default value is what is set by SecResponseBodyAccess  directive (if any) in configuration file(s) specified by <config-file> directive. If SecResponseBodyAccess directive is not present, it is "off".

Example

# Disable SecRule processing in the /docs directory
<Object ppath="/docs/\*">
AuthTrans fn="secrule-config" engine="off"
</Object>

SecRuleEngine, SecRequestBodyAccess and SecRequestBodyAccess will still work in the files specified in <config-file> in server.xml.

Sample :

I changed server.xml to have a new config-file element as shown below:
  <virtual-server>
    <config-file>sample.conf</config-file>
    <name>test</name>
    <host>...</host>
    <http-listener-name>http-listener-1</http-listener-name>
  </virtual-server>

and added this file in <ws7.0u2-server-install-dir>/https-test/config directory

$cat sample.conf
SecRuleEngine On
# Request related
SecRequestBodyAccess On
# default limit is 128 KB (131072)
SecRequestBodyInMemoryLimit  10000
# Variables
SecRule REQUEST_HEADERS "request_headers_match"
SecRule REQUEST_HEADERS_NAMES "request_headers_names_match"
SecRule HTTP_xxx "request_headers_xxx_match" "phase:1"
SecRule REQUEST_HEADERS:yyy "request_headers_yyy_match"  "phase:1"
SecRule REQUEST_HEADERS:/zzz/ "request_headers_zzz_match" "phase:1"
SecRule ARGS "args_match"
SecRule ARGS_NAMES "args_names_match"
SecRule REQUEST_BODY "request_body_match"
SecRule ARGS_COMBINED_SIZE "@gt 1000"
SecRule ENV "env_match"
SecRule QUERY_STRING "query_string_match"
SecRule REQUEST_COOKIES "request_cookies_match"
SecRule REQUEST_COOKIES_NAMES "request_cookies_name_match"
SecRule REQUEST_HEADERS_NAMES "x-aaaaaa.\*" "rev:1,severity:2,msg:'Oops not allwed'"
#Do not match lowercase
SecDefaultAction "deny"
SecRule HTTP_User-Agent "Internet-exprorer"
SecRule HTTP_User-Agent "Mosiac 1\\.\*"
SecRule REQUEST_BODY "X-AAAAAA.\*"
SecRule HTTP_Referer "Powered by Gravity Board" "id:350000,rev:1,severity:2,msg:'Gravity Board Google Recon attempt'"
SecRule REQUEST_URI|REQUEST_BODY "select.\*from.\*information_schema\\.tables"


I started the server. I get this warning at the time of server start up
[11/Apr/2008:12:28:26] info (28100): CORE1116: Sun Java System Web Server 7.0U3 B04/04/2008 12:38
[11/Apr/2008:12:28:27] warning (28101): HTTP3359: An unsupported element config-file is being used. The server may not operate correctly if unsupported features are used.
[11/Apr/2008:12:28:29] info (28101): CORE5076: Using [Java HotSpot(TM) Server VM, Version 1.5.0_12] from [Sun Microsystems Inc.]
[11/Apr/2008:12:28:43] info (28101): HTTP3072: http-listener-1: http://test.sun.com: ready to accept requests
[11/Apr/2008:12:28:43] info (28101): CORE3274: successful server startup

Now I send these two requests :
$telnet 0 1894
GET / HTTP/1.0
foo: request_headers_match

HTTP/1.1 403 Forbidden
Server: Sun-Java-System-Web-Server/7.0
Date: Fri, 11 Apr 2008 07:01:58 GMT
Content-length: 142
Content-type: text/html
Connection: close

<HTML><HEAD><TITLE>Forbidden</TITLE></HEAD>
<BODY><H1>Forbidden</H1>
Your client is not allowed to access the requested object.
</BODY></HTML>

$telnet 0 1894
GET / HTTP/1.0
foo: bar

HTTP/1.1 200 OK
Server: Sun-Java-System-Web-Server/7.0
Date: Fri, 11 Apr 2008 07:02:07 GMT
Content-type: text/html
Last-modified: Fri, 04 Apr 2008 14:24:09 GMT
Content-length: 12038
Etag: "2f06-47f63a09"
Accept-ranges: bytes
Connection: close

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
....
  </body>
</html>

The first request got denied as the header value matched with "SecRule REQUEST_HEADERS "request_headers_match"" rule in sample.conf as shown below :
$tail -f ../logs/errors
[11/Apr/2008:12:31:58] security (28166): for host 127.0.0.1 trying to GET /index.html while trying to GET /, HTTP8005: SecRule directive in file /export1/ws/https-test/config/ms.conf at line 7 matched returning status code 403


Note that this is an untested feature and may have bugs. Please let me know if you find any.

Currently Supported ModSecurity Directives

Due to time constraints not all of the ModSecurity directives are supported in this release. This section documents the supported subset. Note that the supported rules are based on ModSecurity 2.0.

The terms and interfaces given below are taken from ModSecurity 2.0 documentation
http://www.modsecurity.org/documentation/modsecurity-apache/2.0.0-rc-4/modsecurity2-apache-reference.html

Some of these keywords like VARIABLES etc. are abstract quantities and not elements.

Directive
Values Description
SecRuleEngine On
Off
DetectionOnly
server initialization
Default value is "off"

Directive
Values Description
SecRule VARIABLES
"
[@OPERATOR]
Text
regular expression or parameters to pass to the operator
"
[ACTIONS]

VARIABLES [&!]VARIABLE[:/regular-expression/]|
[&!]VARIABLE[:name]|
[&!]VARIABLE[:regular-expression]...

&
should count the number of variables in the array.
!
x|!x:y examine all x but y should not be checked.
|
concatenate variables
:name
a particular value
:/regular_expression/ or :'/regular_expression/' matches regular expression


Values Description
VARIABLE
REQUEST_HEADERS
REQUEST_HEADERS_NAMES
REQUEST_HEADERS:yyy
or
REQUEST_HEADERS:/yyy/
Where yyy is any applicable request header name.
ARGS Contains request body if SecRequestBodyAccess is set to on.
ARGS_NAMES

ARGS_COMBINED_SIZE
AUTH_TYPE
ENV

QUERY_STRING

HTTP_yyy
TIME, TIME_EPOCH, TIME_DAY, TIME_HOUR, TIME_MIN,  TIME_SEC, TIME_WDAY, TIME_MON, TIME_YEAR
REMOTE_HOST, REMOTE_PORT, REMOTE_USER, REMOTE_ADDRESS
PATH_INFO
SERVER_NAME, SERVER_PORT, SERVER_ADDR
SCRIPT_BASENAME, SCRIPT_FILENAME

REQUEST_COOKIES
REQUEST_COOKIES_NAMES
REQUEST_FILENAME

REQUEST_BASENAME
REQUEST_BODY

REQUEST_LINE
REQUEST_METHOD
REQUEST_PROTOCOL
REQUEST_URI, REQUEST_URI_RAW
RESPONSE_BODY
RESPONSE_STATUS
RESPONSE_HEADERS

RESPONSE_HEADERS_NAMES
RESPONSE_PROTOCOL





Values
OPERATOR rx
eq
ge
gt
le
lt
validateByteRange



 Values Description
ACTIONS
ACTION[:xxx], ACTION[:xxx] ...



 Values
ACTION
allow
msg
id
rev
severity
log
deny
status
phase
t
skip
chain


Values Description
phase
[1..4]
phase:1 - Request headers stage
phase:2 - Request body stage
phase:3 - Response headers stage
phase:4 - Response body stage

Default value is phase:2
Note that operations on "phase:5 (Logging stage)" are not supported. If encountered, these are ignored and a log message is recorded.


Values Description
t
lowercase
Transformation functions to perform on the variables before operator is executed (this includes request body)
urlDecode
none
compressWhitespace
removeWhitespace
replaceNulls
removeNulls

Directive
Values Description
SecDefaultAction ACTIONS
For a SecRule, if the previous SecDefaultAction directive is present, those actions takes into effect.

If none of these SecDefaultAction directives are present before a SecRule (in that file or files loaded before it), default SecDefaultAction directive with ACTIONS
"log,deny,status:403,phase:2,t:replaceNulls,t:compressWhitespace,t:lowercase" is internally added.

For the following directives, in case the multiple directives are present (in one or multiple files), last directive's value takes the precedence.
Directive Values Description
SecRequestBodyAccess
On
Off
Whether the server should parse request body or not.
Default value is "off"

Directive Values Description
SecRequestBodyInMemoryLimit integer

Configures the maximum request body size server will store in memory. By default the limit is 128 KB (131072)



Directive Values Description
SecResponseBodyAccess On
Off
Whether the server should parse response body or not. Default value is "off"

Directive Values Description
SecResponseBodyLimit integer

Configures the maximum response body size that will be accepted for buffering. Anything over this limit will be rejected with status code 500 Internal Server Error. This setting will not affect the responses with MIME types that are not marked for buffering. By default this limit is configured to 512 KB. (524288)


Directive Values Description
SecResponseBodyMimeType
strings

Configures which MIME types are to be considered for response body buffering. The default value is text/plain text/html.


Directive Values Description
SecResponseBodyMimeTypesClear -
Clears the list of MIME types considered for response body buffering, allowing to start populating the list from scratch.



Please look at my next blog on this topic also.


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