Meena Vyas

All | DTrace Web Server 7.0 | ACLs Web Server 7.0 | General Web Server 7.0 | HttpCompression Web Server 7.0 | Intrusion Detection Web Server 7.0 | Open Web Server | Reference Deployments of Web Server 7.0 | Reverse Proxy Web Server 7.0 | Security Web Server 7.0 | Troubleshooting Web Server 7.0 | WebDAV Web Server 7.0
« Building Open Web... | Main | About LDAP connectio... »
20090918 Friday September 18, 2009

Enabling Client Certificate Authentication in Sun Web Server 7.0 reverse proxy server and origin server

Enabling Client Certificate Authentication in Sun Web Server 7.0 reverse proxy server and origin server

For this I have setup two Sun Java System Web Server 7.0 update 6 instances. One acting as a reverse proxy and the other origin server that serves the request. Enabled SSL and client authentication on both these instances. Sent SSL requests with client certificates from a test client.

Installed Server Certificates in both Web Server instances

I created self signed certificate in reverse proxy server.

$cd <ws-install-dir>/https-test/config
$rm *.db
$../../bin/certutil -N -d .
$../../bin/certutil -S -d . -n Server-Cert-Reverse-Proxy-Server -s "CN=test.sun.com" -x -t "CT,CT,CT"
$../../bin/certutil -L -d .
Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI
Server-Cert-Reverse-Proxy-Server                             CTu,Cu,Cu
 You can use Admin Server CLI to create a self signed certificate

wadm>create-selfsigned-cert --config=test.sun.com --server-name=test.sun.com --nickname=Server-Cert-Reverse-Proxy-Server

For convenience I copied these *.db to origin server instance config directory, and hence used the same server certificate in origin server. In real world use a new server certificate for origin server.

Changes made in Reverse Proxy Web Server Instance

In obj.conf I have confiugured 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.

Run create-reverse-proxy CLI from Administration server

wadm>create-reverse-proxy --config test --vs test --uri-prefix=/ --server=https://test.sun.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://test.sun.com:4444"
</Object>

...

Enable "ssl" in http-listener, added server certificate nickname (if its different from "Server-Cert") and set client authentication as "required" :

 You can use Admin Server CLI to do these steps 
  1. Enable SSL for this listener and set the server certificate
    wadm> set-ssl-prop --config=test.sun.com --http-listener=http-listener-1 server-cert-nickname=Server-Cert-Reverse-Proxy-Server enabled=true client-auth=required
  2. Deploy the changes
    wadm> deploy-config test.sun.com
server.xml should get modified to look like
  <http-listener>
    <name>http-listener-1</name>
    <port>3333</port>
    <server-name>test.sun.com</server-name>
    <default-virtual-server-name>test</default-virtual-server-name>
   <ssl>
       <server-cert-nickname>Server-Cert-Reverse-Proxy-Server</server-cert-nickname>
       <client-auth>required</client-auth>
   </ssl>
  </http-listener>

In server.xml I have also modified access log format so that we can see what is happening. This will slow down Web Server performance so do not  do this in production environment.

<access-log>
    <file>../logs/access</file>
    <format>%Ses->client.ip% "%Req->reqpb.clf-request%" %Req->srvhdrs.clf-status% %Req->srvhdrs.content-length% %Ses->client.cipher% %Req->vars.auth-cert% </format>
  </access-log>

Changes made in Origin Server Web Server Instance

Enable "ssl"  in http-listener, added server certificate nickname (if its different from "Server-Cert") and set client authentication as "required" :

  <http-listener>
    <name>http-listener-1</name>
    <port>4444</port>
    <server-name>test.sun.com</server-name>
    <ssl>
        <server-cert-nickname>Server-Cert-Reverse-Proxy-Server</server-cert-nickname>
        <client-auth>required</client-auth>
    </ssl>
    <default-virtual-server-name>test</default-virtual-server-name>
  </http-listener>

In server.xml I have also modified access log format so that we can see what is happening. This will slow down Web Server performance so do not  do this in production environment.

 <access-log>
    <file>../logs/access</file>
    <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>

Created a test.html file that should be served when the client requests for it :

$cat ../docs/test.html
This is test.html on origin server

Test Client I used

I used "tstclnt" which is bundled with NSS-NSPR binaries in bin directory. Note that I used the server certificate of reverse proxy server as client certificate because I am too lazy to create more certificates. In real world use a proper client certificate.

Created a test request file :

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

Sent request to the reverse proxy server

$tstclnt -h test.sun.com -p 3333  -n Server-Cert-Reverse-Proxy-Server -d https-test/config -c n -v -o -f < sslreq.dat
tstclnt: connecting to test.sun.com:3333 (address=xxx.xxx.xxx.xxx)
...
tstclnt: stdin read 27 bytes
tstclnt: Writing 27 bytes to server
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=test.sun.com
issuer  DN: CN=test.sun.com
...
tstclnt: Read from server 350 bytes
HTTP/1.1 200 OK
Server: Sun-Java-System-Web-Server/7.0
Date: Fri, 18 Sep 2009 10:59:13 GMT
Content-type: text/html
Last-modified: Thu, 17 Sep 2009 10:44:10 GMT
Content-length: 35
Etag: "23-4ab212fa"
Accept-ranges: bytes
Via: 1.1 https-test
Proxy-agent: Sun-Java-System-Web-Server/7.0
Connection: close
This is test.html on origin server
...
tstclnt: exiting with return code 0

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 because I know this cipher that is enabled in Sun Web Server 7.0 update 6. 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 the certificate

$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%

xxx.xxx.xxx.xxx "GET /test.html HTTP/1.0" 
200 35  
RC4 
MIIBujCCASOgAwIBAgIFAI566gYwDQYJKo...fBqhD710VkFmOScYjWBxZe1vhnTbu/NexX4NqLsZG9So=

Note cipher is RC4.

Access log of origin server shows the certificate

$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 35 
RC4 
MIIBujCCASOgAwIBAgIFAI566gYwDQYJKo...fBqhD710VkFmOScYjWBxZe1vhnTbu/NexX4NqLsZG9So=
MIIBujCCASOgAwIBAgIFAI566gYwDQYJKo...fBqhD710VkFmOScYjWBxZe1vhnTbu/NexX4NqLsZG9So=

Note that as expected in origin-server, rq->headers pblock has the certificate in "proxy-auth-cert". Reverse proxy server sends the certificate to origin server in this header.

References

Posted by meena ( Sep 18 2009, 05:32:56 PM IST ) Permalink Comments [0]

Trackback URL: http://blogs.sun.com/meena/entry/enabling_client_certificate_authentication_in
Comments:

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed

This blog copyright 2009 by meena

Calendar

Search

RSS Feeds

Navigation

Referers