Friday Sep 29, 2006

Migrating JKS Keystore Entries to NSS datbase in Sun Java System Web Server 7.0 or 6.x

Migrating JKS Keystore Entries to NSS database in Sun Java System Web Server 7.0 or 6.x

Migrating JKS Keystore Entries to NSS database in Sun Java System Web Server 7.0 using Administration CLI

I installed Sun Java System Web Server 7.0 in <server-installation>directory and started Administration server.
$ ./admin-server/bin/startserv
Now I used wadm to run Administration CLIs
$ ./bin/ wadm --user=admin
Please enter admin-user-password> typed-admin-password-here
wadm>
I have a config named "test"
wadm> list-configs
test
If the keystore is in file /tmp/ my-jks-key-store.jks, keystore password is storepass, key password is keypass, and NSS DB password is nsspass, I run migrate-jks-keycert CLI
wadm> migrate-jks-keycert --config=test --keystore=/tmp/my-jks-key-store.jks
Please enter keystore-password> storepass
Please enter key-password> keypass
Please enter certdb-password> nsspass
CLI201 Command "migrate-jks-keycert" ran successful.

I confirmed that migration worked by listing the certificates using list-certs CLI
wadm> list-certs --config=test
CN=test,OU=WS,O=SUN,L=BLR,ST=KA,C=IN
wadm>


After all the changes are done, run deploy-config CLI.

From server instance's config directory run certutil to confirm that the certificates are present in NSS DB.
$.${server-install-dir}/bin/certutil -L -d ${server-instance-dir}/config
CN=test,OU=WS,O=SUN,L=BLR,ST=KA,C=IN u,u,u

Migrating JKS Keystore Entries to NSS Datbase in Sun One Web Server 6.x

We have to manually migrate jks keystore to NSS Database here is what we have to do
From the server instance config directory, initialize NSS DB if required
$${server-install-dir}/bin/certutil -N -d ${server-instance-dir}/config
Enter a password which will be used to encrypt your keys.
The password should be at least 8 characters long, and should contain at least one non-alphabetic character.

Enter new password: nsspass
Re-enter password: nsspass

Use keytool from JDK greater than version 6, it has importkeystore option which converts JKS keystore to PKCS12 format.
$/share/builds/components/jdk/1.6.0_01/SunOS/bin/keytool -importkeystore -srckeystore server-keystore.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore server-keystore.pkcs12
Enter destination keystore password: storepass
Re-enter new password: storepass
Enter source keystore password: storepass
Entry for alias s1as successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

Now import them into NSS database
$${server-install-dir}/bin/pk12util -i server-keystore.pkcs12 -d ${server-instance-dir}/config
Enter Password or Pin for "NSS Certificate DB": nsspass
Enter password for PKCS12 file: storepass
pk12util: PKCS12 IMPORT SUCCESSFUL

Verify if the certificate was imported
$${server-install-dir}/bin/certutil -L -d .
CN=Server,OU=JWS,O=SUN,ST=Some-State,C=AU                    u,u,u

Then we may have to set trust flags using the following command
$${server-install-dir}/bin/certutil -M -t "CTu,CTu,CTu" ....

For migrating Apache server(OpenSSL) certificate, we can use openssl utility to export it to a PKCS#12 file
$ openssl pkcs12 -export -out <output-pkcs-file> -in <openssl-server-crt-file> -inkey <openssl-server-key-file> -nodes -name <alias>
And import it into SJS Web Server NSS database using pk12util utility
$ ${server-install-dir}/bin/pk12util -i <exported-pkcs12-file> -d ${server-instance-dir}/config

For more readability, the commands I used are shown in brown and the output is shown in green.
Sun Java System Web Server 7.0 Technology Preview 3 is released and is FREE download it from here.


Thursday Sep 21, 2006

Solaris Cryptographic Framework and Sun Java System Web Server 7.0

Solaris Cryptographic Framework and Sun Java System Web Server 7.0

Here are my initial experiments to use external PKCS#11 security module Solaris Cryptographic Framework in Sun Java System Web Server 7.0.  Some references I liked in this regard are "man libpkcs11", "Using the Cryptographic Accelerator of the UltraSPARC T1 Processor" and Jyri's article "Configuring Solaris Cryptographic Framework and Sun Java System Web Server 7 on Systems With UltraSPARC T1 Processors" . Special Thanx to Basant who helped me.

Note that I executed these commands from the server instance's config directory.  For more readability, the commands I used are shown in brown and the output is shown in green.

Initial steps

First I move .sunw directory
$mv $HOME/.sun $HOME/.sunw.OLD

Then I initialized password/pin
$pktool setpin
Enter new PIN:typed-my-password-here
Re-enter new PIN:typed-my-password-here

Then disabled the following mechanisms
Note that these commands need to be executed as root.
#cryptoadm disable provider=/usr/lib/security/\\$ISA/pkcs11_kernel.so mechanism=CKM_SSL3_PRE_MASTER_KEY_GEN,CKM_SSL3_MASTER_KEY_DERIVE,CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE_DH,CKM_SSL3_MD5_MAC,CKM_SSL3_SHA1_MAC

#cryptoadm disable provider=/usr/lib/security/\\$ISA/pkcs11_softtoken.so mechanism=CKM_SSL3_PRE_MASTER_KEY_GEN,CKM_SSL3_MASTER_KEY_DERIVE,CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE_DH,CKM_SSL3_MD5_MAC,CKM_SSL3_SHA1_MAC
(if pkcs11_softtoken_extra.so is used, disable these mechanisms in that also)

#cryptoadm list -p
user-level providers:

=====================
/usr/lib/security/$ISA/pkcs11_kernel.so: all mechanisms are enabled, except CKM_SSL3_SHA1_MAC,CKM_SSL3_MD5_MAC,CKM_SSL3_MASTER_KEY_DERIVE_DH,CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE,CKM_SSL3_PRE_MASTER_KEY_GEN.
/usr/lib/security/$ISA/pkcs11_softtoken.so: all mechanisms are enabled, except CKM_SSL3_SHA1_MAC,CKM_SSL3_MD5_MAC,CKM_SSL3_MASTER_KEY_DERIVE_DH,CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE,CKM_SSL3_PRE_MASTER_KEY_GEN. random is enabled.
...

Registering PKCS#11 library

I  have used PKCS#11 library /usr/lib/libpkcs11.so (for 64 bit, it is /usr/lib/64/libpkcs11.so).

The following command added the Solaris crypto framework module to the NSS database in the config directory :
$../../lib/modutil -dbdir . -add "scf" -libfile /usr/lib/libpkcs11.so -mechanisms RSA
...
Module "scf" added to database.


$../../lib/modutil -dbdir . -enable "scf"


Verified the above steps,
$../../lib/modutil -dbdir . -nocertdb -list
Listing of PKCS #11 Modules
-----------------------------------------------------------
   1. NSS Internal PKCS #11 Module
          slots: 2 slots attached
         status: loaded

          slot: NSS Internal Cryptographic Services
         token: NSS Generic Crypto Services

          slot: NSS User Private Key and Certificate Services
         token: NSS Certificate DB

   2. scf
         library name: /usr/lib/libpkcs11.so
          slots: 1 slot attached
         status: loaded

          slot: Sun Crypto Softtoken
         token: Sun Software PKCS#11 softtoken

   3. Root Certs
         library name: libnssckbi.so
          slots: There are no slots attached to this module
         status: Not loaded
-----------------------------------------------------------
Note that slot "Sun Crypto Softtoken" has token "Sun Software PKCS#11 softtoken". I will be using this token in the next stages.

Creating Server Certificates

The normal process for requesting and installing certificates is used. Only with a difference, create all certificate and keys in that security module, not using "internal" NSS database token, but using the "Sun Software PKCS#11 softtoken" token instead.

1. Exporting and Importing already existing certificates using pk12util

If I already had certificates in NSS database, I could have exported and imported them using pk12util
$pk12util –o server.pk12 –d . –n MyCert
$pk12util –i server.pk12 –d . –h “Sun Software PKCS#11 softtoken”

By default, certutil / pk12util searches for databases named cert8.db and key3.db, but some of the versions of Web Server use alternate names such as https-instance-hostname-cert8.db and https-instance-hostname-key3.db in that case add -P parameter for the prefix.

2. Using certutil to create self signed server certificate

I used NSS utility "certutil" to create a self signed server certificates.
$../../bin/certutil -S -d . -n MyCert -s "CN=test.sun.com" -x -t "u,u,u" -h "Sun Software PKCS#11 softtoken" -5
Enter Password or Pin for "Sun Software PKCS#11 softtoken":typed-my-password-here
A random seed must be generated that will be used in the
creation of your key.  One of the easiest ways to create a
random seed is to use the timing of keystrokes on a keyboard.

To begin, type keys on the keyboard until this progress meter
is full.  DO NOT USE THE AUTOREPEAT FUNCTION ON YOUR KEYBOARD!


Continue typing until the progress meter is full:

|\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*|

Finished.  Press enter to continue:


Generating key.  This may take a few moments...

                           0 - SSL Client
                           1 - SSL Server
                           2 - S/MIME
                           3 - Object Signing
                           4 - Reserved for future use
                           5 - SSL CA
                           6 - S/MIME CA
                           7 - Object Signing CA
                           Other to finish
1
                           0 - SSL Client
                           1 - SSL Server
                           2 - S/MIME
                           3 - Object Signing
                           4 - Reserved for future use
                           5 - SSL CA
                           6 - S/MIME CA
                           7 - Object Signing CA
                           Other to finish
5
                           0 - SSL Client
                           1 - SSL Server
                           2 - S/MIME
                           3 - Object Signing
                           4 - Reserved for future use
                           5 - SSL CA
                           6 - S/MIME CA
                           7 - Object Signing CA
                           Other to finish
9
Is this a critical extension [y/N]?
y

Verified that the certificate was added to the database
$../../lib/certutil -L -d . -h "Sun Software PKCS#11 softtoken"
Enter Password or Pin for "Sun Software PKCS#11 softtoken":typed-my-password-here
Sun Software PKCS#11 softtoken:MyCert                        u,u,u

Enable SSL for the Web Server instance

In server.xml,  enabled ssl for http-listener element, and  added server certificate nickname correctly.

....
<http-listener>
  ...
<ssl>
  <enabled>true</enabled>
  <server-cert-nickname>Sun Software PKCS#11 softtoken:MyCert</server-cert-nickname>
  </ssl>
</http-listener>
...
Note the prefix "Sun Software PKCS#11 softtoken:".

3. Using Administration CLI to create self signed certificate and enabling SSL

Start admin-server, from <server-installation>/bin directory,
$wadm --user=admin

Please enter admin-user-password>typed-admin-server-password-here
Sun Java System Web Server 7.0-Technology-Preview-3 B09/20/2006 10:07

wadm>create-selfsigned-cert --config=test.sun.com --server-name=test.sun.com --nickname=MyCert --token="Sun Software PKCS#11 softtoken"
ADMIN4099: Token 'Sun Software PKCS#11 softtoken' was not found

wadm>list-tokens --config=test.sun.com
internal

The reason for this error is I ran modutil into server instance's config directory so I need to pull-config (I should have run modutil command from admin-server/config-store/test.sun.com/config directory to avoid this)
wadm>pull-config  --config=test.sun.com test.sun.com
CLI201 Command 'pull-config' ran successfully

wadm>list-tokens --config=test.sun.com
internal
Sun Software PKCS#11 softtoken
This looks ok.

wadm>create-selfsigned-cert --config=test.sun.com --server-name=test.sun.com --nickname=MyCert --token="Sun Software PKCS#11 softtoken"
Please enter token-pin>typed-my-password-here
CLI201 Command 'create-selfsigned-cert' ran successfully

wadm>set-ssl-prop --config=test.sun.com --http-listener=http-listener-1 enabled=true server-cert-nickname="Sun Software PKCS#11 softtoken:MyCert"
CLI201 Command 'set-ssl-prop' ran successfully

wadm>deploy-config test.sun.com
CLI201 Command 'deploy-config' ran success


Now I started the Web Server,
$../bin/startserv
Sun Java System Web Server 7.0 B09/11/2006 12:04
Please enter the PIN for the "Sun Software PKCS#11 softtoken" token:typed-my-password-here
info: HTTP3072: http-listener-1: https://test.sun.com:2222 ready to accept requests
info: CORE3274: successful server startup

I sent a request through the browser to https://test.sun.com:2222, and the server served the request.

More References

  1. Jyri's BigAdmin Article "Configuring Solaris Cryptographic Framework and Sun Java System Web Server 7 on Systems With UltraSPARC T1 Processors"
  2. Using the Cryptographic Accelerator of the UltraSPARC T1 Processor
  3. man libpkcs11
  4. man cryptoadm
  5. Sun crypto accelerator 6000 user's guide has chapter on Installing and configuring with Sun Java System Web Server 6.1.


Tip : If
1. Web server does not present the Intermediate CA certificates installed as Server Certificate Chain to the browser and that causes the certificate validation by the browser to fail.
or
2. Client authentication fails with the following error message in the errors log .  Root CA cert has been installed to the certificate database.

failure (16670): HTTP3068: Error receiving request from 123.45.67.897(SEC_ERROR_UNKNOWN_ISSUER: Peer's certificate is signed by an unknown issuer)

These two issues are caused by the /.sunw directory not being accessible by the web server running user "webservd". That directory has permissions 0700 and is owned by root. Web Server starts up as root and then changes (using setuid) to user "webservd".  Solution to this is
1) Have the web server running as root
2) Open up the permission on /.sunw so that it is readable by the web server running user
3) Set  the environment variable SOFTTOKEN_DIR to point to some directory that is owned by webservd before the web server is started. The SCF will then access the files in $SOFTTOKEN_DIR/pkcs11_softoken/ during execution.

Read my next blog Using builtin hardware accelerators of Niagara 1 (Sun Fire T 2000) server with SSL enabled Sun Java System Web Server 7.0 instance


Tuesday Jun 13, 2006

Cross Site Scripting Prevention in Sun Java System Web Server 7.0

Cross Site Scripting Prevention in Sun Java System Web Server 7.0

    Check out the new improvements we made in Sun Java System Web Server 7.0. It can be downloaded for free from http://www.sun.com/download/index.jsp?cat=Web%20%26%20Proxy%20Servers&tab=3&subcat=Web%20Servers. In this blog I will talk about Cross Site Scripting (XSS) prevention.

Obj.conf now supports a lot of features which allows you to use it a lot like a programming language, which allows us to configure in our Web Server features similar to in ModSecurity Apache Module.

The main method of preventing Cross Site Scripting (XSS) is through entity encoding, using entities such as "&lt;".  We now have a introduced a native input stage filter based on sed which can do XSS filtering. This sed-request filter applies sed edit commands to an incoming request entity body, e.g. an uploaded file or submitted form.

Input fn="insert-filter" ... filter="sed-request" sed="script" [ sed="script" ... ]

Where "script" is the actual sed script you want to run on request body.
For example, if we take example of request body posted in HTML form containing  "<" and ">" characters. In ModSecurity in Apache server you have SecFilter like
SecFilterEngine On
SecFilterScanPOST On
SecFilter "<(.|\\n)+>"


By adding the following in obj.conf, Web Server 7.0 will encode any < and > characters.

Input fn="insert-filter"
method="POST"
filter="sed-request"
sed="s/(<|%3c)/\\\\&lt;/gi"
sed="s/(>|%3e)/\\\\&gt;/gi"

\* Note that because POST bodies are usually URL-encoded, it is important to check for URL-encoded forms also when editing POST. "%3C" is the URL-encoded form of "<" and bodies. "%3E" is the URI-encoded form of ">".


In Web Server 7.0 update 2 or 3 onwards, you can have a config file myrules.txt as shown below

SecRuleEngine On
SecRequestBodyAccess On
SecRule REQUEST_BODY "<(.|\\n)+>"

I have added in server.xml <config-file>myrules.txt</config-file>

I have added a simple cgi script to test my stuff.
$cat https-test/docs/cgi-bin/test.pl
#!/tools/ns/bin/perl5
binmode(STDOUT);
binmode(STDIN);

if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
    @pairs = split(/&/, $buffer);
} else {
    @pairs = split(/&/, $ENV{'QUERY_STRING'});
}

foreach $pair (@pairs) {
    ($key, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $value =~ tr/\\cM/\\n/;
    eval("\\$$key = \\"$value\\"");
    $FORM{$key} = $value;
}

print "Content-Type: text/html\\n\\n";
print "CGI values passed\\n\\n";

if ($#pairs < 0) {
    print "No CGI Variables\\n";
} else {
    foreach $var (keys(%FORM)) {
        print "$var $FORM{$var}\\n";
    }
}
exit;


So when we send a request without < and > , it goes through fine as shown below

$telnet 0 3333
POST /cgi-bin/test.pl HTTP/1.0
Content-length: 10

abcde12345
HTTP/1.1 200 OK
Server: Sun-Java-System-Web-Server/7.0
Date: Wed, 16 Jul 2008 07:56:47 GMT
Content-type: text/html
Connection: close

CGI values passed

abcde12345

When we send request with < and > as shown below we get forbidden error
$telnet 0 3333
POST /cgi-bin/test.pl HTTP/1.0
Content-length: 10

ab<cd>12
HTTP/1.1 403 Forbidden
Server: Sun-Java-System-Web-Server/7.0
Date: Wed, 16 Jul 2008 07:57:24 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>




When we send a request with just < it doesn't match the pattern, and hence passes :
$telnet 0 3333
POST /cgi-bin/test.pl HTTP/1.0
Content-length: 10

ab<cdef12345
HTTP/1.1 200 OK
Server: Sun-Java-System-Web-Server/7.0
Date: Wed, 16 Jul 2008 07:58:03 GMT
Content-type: text/html
Connection: close

CGI values passed

ab<cdef123

More details on SecRule and other related Directives supported in Web Server 7.0 update 2 onwards are in this blog.

Tuesday May 16, 2006

Access Control In Sun Java System Web Server 7.0 - II

Access Control In Sun Java System Web Server 7.0 -II

After my first blog about Access Control in general, let me try to talk about some more ACL related topics.

Access Rights in Access Control Lists in Sun Java System Web Server 7.0

Access rights that can be used to set access control in ACL file in Sun Java System Web Server 7.0 - are
  • all
  • read
  • execute
  • info
  • write
  • list
  • delete
  • http_<method>
  • dav:read-acl
  • dav:read-current-user-privilege-set
If we want to grant write,delete,list rights ONLY to authenticated users but grant read, execute, info rights to all users (authenticated as well as unauthenticated users), we need to have an ACL like.

#default.acl
...

acl "default";
authenticate (user, group) {
  prompt = "Sun Java System Web Server";
};
allow (read, execute, info) user = "anyone";
allow (list, write, delete) user = "all";

This is already set by default in <WS_INSTALLATION_DIR>/https-<servername>/config/default.acl file.

If we want to grant write,delete,list access to a set of high privileged users only (users alpha,beta and gamma) and grant read,execute,info rights to ONLY authenticated users, set the following ACL in <WS_INSTALLATION_DIR>/https-<servername>/config/default.acl file in the end.
(We can also add this in that Virtual Server's ACL file if we are using multiple virtual servers.)

#default.acl
...
acl "uri=/"
deny (all) user="anyone";
allow (read, execute, info) user = "all";
allow (list, write, delete) user = "alpha" or user = "beta" or user = "gamma";

Note that the first ACE (ACE starting with deny)  MUST BE added. It denies all rights to "anyone" i.e. all users (both authenticated and unauthenticated users).
Second ACE,  grants read,execute and info rights to authenticated users only.
Third ACE,  grants list, write, delete rights to alpha, beta or gamma only.

Instead of adding individual users, we can also create a group (lets say "premium") in authentication database and add these three users  alpha, beta and gamma in the group. The new ACE will be

#default.acl
...
acl "uri=/"
deny (all) user="anyone";
allow (read, execute, info) user = "all";
allow (list, write, delete) group = "premium";

Mapping between rights and HTTP Methods

Rights
Maps to HTTP Methods
read
GET, HEAD, TRACE, OPTIONS, COPY, BCOPY
write
PUT, MKDIR, LOCK, UNLOCK, PROPPATCH, MKCOL, ACL, VERSION-CONTROL, CHECKOUT, UNCHECKOUT, CHECKIN, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE-CONTROL, MKACTIVITY, BPROPPATCH
execute
POST, CONNECT, SUBSCRIBE, UNSUBSCRIBE, NOTIFY, POLL
delete
DELETE, RMDIR, MOVE, BDELETE, BMOVE
info
HEAD, TRACE, OPTIONS
list
INDEX, PROPFIND, REPORT, SEARCH, BPROPFIND
Note that to get directory listing we need "list" rights.
Note that we have HEAD, TRACE and OPTIONS map to both read and info rights.
\* Will discuss dav:read-acl and dav:read-current-user-privilege-set  later.

We can also set these http_<method> into ACL file for finer access control.

#default.acl
...
acl "uri=/dirGETNotAllowed";

authenticate (user, group) {
  database = "mykeyfile";
  method = "basic";
};
deny (http_GET) ip = "123.45.\*";

ACL Evaluation

The server goes through the list of ACEs to determine the access permissions. Attribute pattern anyone means all users. If that ACE's attribute is user or group and it does NOT contain pattern anyone, the server first authenticates the user. The first ACE is evaluated and it denies/allows access to the current user. The server then checks the second ACE in the list, and if it matches, the next ACE is used. The server continues down the list until it reaches the end or it reaches an absolute ACE\*. The last matching ACE determines if access is allowed or denied.
\*absolute ACE is an ACE that contains absolute keyword.

Lets take the example of a simple ACL file and lets see how they are effective for some requests.

#default.acl
version 3.0;
acl "default";
# call it ACE#1
allow (read, execute, info) user = "anyone";
# call it ACE#2
allow (list, write, delete) user = "all";
...
acl "uri=/file.html";
# call it ACE#3
deny (info) user = "alpha";

Request
Server reads ACEs from ACL file
Server Evaluates ACEs in this order
Result
HEAD /
Reads all ACEs containing "all", "read", "http_head" and "info" rights applicable for this resource.

(It reads ACE#1 in the ACL file above)
ACE#1 is evaluated, operation is allowed. HEAD request is allowed.
GET / or GET /file.html
Reads all ACEs containing "all", "read" and "http_get" rights applicable for this resource.

(It reads ACE#1in the ACL file above)
ACE#1 is evaluated, operation is allowed. GET request is allowed.
HEAD /file.html as user alpha Reads all ACEs containing "all", "read", "http_head" and "info" rights applicable for this resource.

(It reads ACE#1 and ACE#3 in the ACL file above)
  1. ACE#1 is evaluated, operation is allowed.\*
  2. ACE#3 is evaluated, operation is denied (for alpha).
HEAD request is denied.
HEAD /file.html as user beta
  1. ACE#1 is evaluated, operation is allowed.\*
  2. ACE#3 is evaluated, operation is allowed (for beta).
HEAD request is allowed.
HEAD /file.html\*\*
  1. ACE#1 is evaluated, operation is allowed.\*
  2. ACE#3 is evaluated, operation is denied (for unauthenticated users).
HEAD request is denied.
\* It continues to the next step as "absolute" keyword is not found.
\*\* Although we do not have any deny ACEs for "anyone" (unauthenticated users), having a deny or allow ACE for a particular user implicitly denies access to unauthenticated users.

Absolute ACE

ACL Evaluation stops if an "absolute" ACE is found. For example if we have ACEs like

#default.acl
version 3.0;
acl "default";
# call it ACE #1
allow absolute (read, execute, info) user = "anyone";
# call it ACE #2
allow (list, write, delete) user = "all";

acl "uri=/file.jsp";
# Call it ACE #3 is ignored
deny (info) user="all";
...

For HEAD request for /file.jsp, request is allowed for all users even though ACE#3 sets a deny.  During the evaluation of ACE#1 as it encounters absolute keyword, it never evaluates ACE#3 and other ACEs below it.

Access Control In Sun Java System Web Server 7.0

Access Control In Sun Java System Web Server 7.0

You can now download Sun Java System Web Server 7.0 for FREE from http://www.sun.com/download/index.jsp?cat=Web%20%26%20Proxy%20Servers&tab=3&subcat=Web%20Servers .

What Is Access Control?

Access control allows us to determine and manage

  • Who (subject) can access the resources on our web site
  • Which resources (like files or directories)  they can access
  • Which operations can they perform (like creating a file, POST-ing contents to the server).

We can allow or deny access based on:

  • Who is making the request (for example, user or group using user, group attributes).
  • Where the request is coming from (for example, host or IP using ip, dns attributes).
  • When the request is happening (for example, time of day or day of week using timeofday, dayofweek attributes).
  • What type of connection is being used (for example, SSL using ssl attribute).
Authentication is the process of acquiring and verifying the attributes of the subject which help to identify the subject. For example, authentication may involve prompting the user to login with a username and password, and then looking in a database to verify that the user's password is correct.

Authorization is the process of checking the rights (or permissions) to the server resource that are allowed for the subject. for example, a subject might be allowed read access but not write access to a server resource.

An access control entry (ACE) specifies the rules for accessing a given server resource. There are two kinds of ACEs
  • Authentication ACE defines how subject(who is making the request) is identified. It can be used to set authorization method (Digest, Basic, SSL) or database names (like default, myldap, mykeyfile).
  • Authorization ACE defines the rights allowed or denied for a particular subject or a group of subjects.
ACL (Access Control List) is an ordered list of ACEs. An ACL can contain both types of ACEs.

We can control access to the entire server or to parts of the server, or the files or directories on our web site.  When the server gets a request for a page, the server uses the rules in the ACL file to determine if it should grant access or not. We create a hierarchy of rules (called ACEs) to allow or deny access. Each ACE specifies whether or not the server should check the next ACE in the hierarchy. The collection of ACEs we create is called an access control list (ACL).

Types Of ACLs

  • Named ACLs
  • URI (Uniform Resource Indicator) ACLs specify a directory or file relative to the server’s document root.
  • Path ACLs specify an absolute path to the resource they affect.
Path and URI ACLs can include wildcards at the end of the entry. For example: /a/b/\*. Wildcards placed anywhere except at the end of the entry will NOT work.

Examples of Named ACLs

Named ACLs are ACLs which have the first line like acl "<name>"; . It MUST have a corresponding check-acl SAF entry in obj.conf. For example, named acl default or named ACL dav-src  for WebDAV requests we add in Object named dav.

#default.acl
version 3.0;
acl "default";
authenticate (user, group) {
  prompt = "Sun Java System Web Server";
};
allow (read, execute, info) user = "anyone";
allow (list, write, delete) user = "anyone";
...
acl "dav-src";
deny (all) user = "anyone";

Named ACL default  has a corresponding check-acl SAF in obj.conf.  Named ACL dav-src has a corresponding check-acl SAF in obj.conf.

#obj.conf
<Object name=default>
...
PathCheck fn="uri-clean"
PathCheck fn="check-acl" acl="default"
...
</Object>
...
<Object name="dav">
PathCheck fn="check-acl" acl="dav-src"
Service fn="service-dav" method="(GET|HEAD|POST|PUT|DELETE|COPY|MOVE|PROPFIND|PROPPATCH|LOCK|UNLOCK|MKCOL)"
</Object>

Examples of URI based ACLs

URI based ACLs start with uri= prefix. We can set ACLs for a particular resource or a directory and resources inside it. For example, we can set URI based ACL for a particular file file.html

#default.acl
....
acl "uri=/dir1/file.html";
authenticate (user,group) {
  method = "basic";
  database = "myldap";
};
deny (all) user = "anyone";
allow (all) user = "beta";

For setting a URI based ACL on a directory and all the files inside that directory, we can set ACEs like

#default.acl
...
acl "uri=/dir1/\*";
allow (all) dns=".sun.com";
Or
#default.acl
...
acl "uri=/dir1/";
deny (read) user="anyone";
allow (read) group="premium" and dayofweek="Sat,Sun";

Example of Path based ACLs

Path based ACLs start with  "path=" prefix.

#default.acl
...
acl "path=/opt/Sun/Servers/docs/index.html";
deny (read) user="anyone";
allow (read) timeofday<0800 or timeofday=1700;


The URI or path that preceeds the wildcard does NOT work properly if the URI or path information is not a directory but is, instead, a file. For example, the following ACL settings work. When /test/README is accessed, access is allowed only for the user abc.

#default.acl
...
acl "uri=/test/\*";
authenticate (user) {
  prompt = "Test ACL.";
};
deny (all) user = "anyone";
allow (all) user = "abc";

But, the following ACL settings do NOT work. When /test/README is accessed the request is allowed to everyone.

#default.acl
...
acl "uri=/test/READ\*";
authenticate (user) {
  prompt = "Test ACL.";
};
deny (all) user = "anyone";
allow (all) user = "abc";


Only tailing "/\*" is supported in ACL file. ACLs with patterns XX\*, \*XXX\* are ignored. For such scenarios, declare it as a named ACL in obj.conf. For example,

#obj.conf
...
PathCheck fn="check-acl" fn=check-acl path="/pathtosomedir/tes\*.html" acl="acl123"
...
Or
#obj.conf
...
<Object ppath="/pathtosomedir/tes\*.html" >
PathCheck fn="check-acl" acl="acl123"
</Object>

\*\* Note that check-acl usage has a limitation as ACLs are cached in memory. As long as the same ACLs are applied for a resource it is ok. You can not use check-acl for the case where different ACLs are supposed to be added for different condition. For a particular resource we have in obj.conf , <If $client-ip="1.1.1.1"> PathCheck fn="check-acl" acl="acl123" </If> it may or may not add this ACL depending on client's ip address. To make it work we have to disable acl-cache in server.xml (in Web Server 7.0 onwards).

One tip, whenever you want to set an ACL to allow access of a resource to a small audience, first add a deny ACE that would restrict the whole audience from accessing the resource and then add specific ACEs to allow access to the resource to the smaller audience. Something like
#default.acl
...
acl ...
deny (all) user ="anyone";
allow (all) user="alpha,beta,gamma";
Or if you want to add allow ACE first use "absolute" keyword.
#default.acl
...
acl ...
allow absolute (all) user="alpha,beta,gamma";
deny (all) user ="anyone";
Refer my next blog for more information about this.
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