中港费是什么:Red Hat Magazine | JBoss Drools how

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 05:48:06
http://magazine.redhat.com/2008/08/14/jboss-drools-how-to-tuning-guvnor-part-2/

JBoss Drools how-to: Tuning Guvnor, part 2

by kijanowski

Guvnor is the business rules management system in Drools 5. When you deploy it out of the box, you get an unsecured web application that stores data in Jackrabbit’s embedded Derby database.

This two-part article explains how to tune Guvnor deployed on JBoss Application Server 4.2.3. (If you missed the first half of the series, catch up in our archives.)This means that we will use the container’s configuration files and security infrastructure. This installment covers enabling password validation based on an OpenLDAP server, moving from the default data repository, and enabling SSL for better security.

  1. Use OpenLDAP as a user repository
  2. Use MySQL as a data repository
  3. Enable SSL
  4. How to use a secured Guvnor package
  5. Summary

Use OpenLDAP as a user repository

There are several reasons why you would want to use an LDAP directory instead of a clear text file — security, provisioning, and reuseability are just a few. First of all, we need a directory. OpenLDAP will do for this example. Download and extract the bits from the OpenLDAP home page. In this example, I’ve used openldap-2.3.39.tgz. Next, go to the directory where you’ve extracted the installation files and perform following steps:

$ mkdir -p /data/openldap-2.3.39$ ./configure --prefix=/data/openldap-2.3.39$ make depend$ make$ make install

For more detailed instructions, look at the INSTALL file or the OpenLDAP Administrator’s Guide.

The next instructions will configure our directory and create a tree which looks like this:

Fig 2.1 tree

We need to initialize the LDAP server and provide data like the root suffix, directory manager, and password. We also want to enable SSL like so:

$ mkdir /data/openldap-2.3.39/ssl$ openssl req -newkey rsa:1024 -x509 -nodes -out /data/openldap-2.3.39/ssl/server.pem -keyout /data/openldap-2.3.39/ssl/server.pem -days 365Generating a 1024 bit RSA private key....++++++................++++++writing new private key to 'server.pem'-----You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [GB]:EUState or Province Name (full name) [Berkshire]:MazoviaLocality Name (eg, city) [Newbury]:WarsawOrganization Name (eg, company) [My Company Ltd]:KijanowskiOrganizational Unit Name (eg, section) []:GuvnorCommon Name (eg, your name or your server's hostname) []:localhostEmail Address []:a@a.a

Since this is a self-signed certificate we will need to add it to the client’s (JBoss AS) truststore.

$ opensslOpenSSL> x509 -inform PEM -outform DER -in /data/openldap-2.3.39/ssl/server.pem -out /data/openldap-2.3.39/ssl/server.derOpenSSL> exit$ keytool -import -file /data/openldap-2.3.39/ssl/server.der -keystore $JBOSS_SERVER/conf/ldap.truststoreEnter keystore password:  qwertyOwner: EMAILADDRESS=a@a.a, CN=localhost, OU=Guvnor, O=Kijanowski, L=Warsaw, ST=Mazovia, C=EUIssuer: EMAILADDRESS=a@a.a, CN=localhost, OU=Guvnor, O=Kijanowski, L=Warsaw, ST=Mazovia, C=EUSerial number: d8537a079c5eed59Valid from: Wed Jul 16 18:35:50 CEST 2008 until: Thu Jul 16 18:35:50 CEST 2009Certificate fingerprints:         MD5:  25:C5:88:7B:D4:88:02:46:F1:EF:0D:6B:D6:EE:1F:A7         SHA1: 57:B8:F4:25:77:F0:12:BD:B2:2E:DD:7D:CE:09:D2:D4:96:56:BC:26Trust this certificate? [no]:  yesCertificate was added to keystore

To enable the new truststore, edit $JBOSS_SERVER/deploy/properties-service.xml and add following lines:

    javax.net.ssl.trustStore=/data/jboss-4.2.3.GA/server//conf/ldap.truststore    javax.net.ssl.trustStorePassword=qwerty

Now edit the file /data/openldap-2.3.39/etc/openldap/slapd.conf:

include         /data/openldap-2.3.39/etc/openldap/schema/core.schemainclude         /data/openldap-2.3.39/etc/openldap/schema/cosine.schemainclude         /data/openldap-2.3.39/etc/openldap/schema/inetorgperson.schemapidfile         /data/openldap-2.3.39/var/run/slapd.pidargsfile        /data/openldap-2.3.39/var/run/slapd.argsdatabase        bdbsuffix          "dc=kijanowski,dc=eu"rootdn          "cn=DirManager,dc=kijanowski,dc=eu"rootpw          secretdirectory       /data/openldap-2.3.39/var/openldap-dataindex   objectClass     eqTLSCipherSuite HIGH:MEDIUM:-SSLv2TLSCACertificateFile /data/openldap-2.3.39/ssl/server.pemTLSCertificateFile /data/openldap-2.3.39/ssl/server.pemTLSCertificateKeyFile /data/openldap-2.3.39/ssl/server.pemTLSVerifyClient never

The rootpw attribute should be changed from ‘secret’ to:

$ /data/openldap-2.3.39/sbin/slappasswd -s admin123

where ‘admin123′ is the new directory manager’s password. For better performance, you can create a config file for the backend database or copy the sample configuration file like so:

$ cp /data/openldap-2.3.39/var/openldap-data/DB_CONFIG.example /data/openldap-2.3.39/var/openldap-data/DB_CONFIG

To start the server with a customized listener, run:

$ /data/openldap-2.3.39/libexec/slapd -h ldaps://localhost:16636

You can make sure your LDAP server is up and running (listening) by running:

$ netstat -an|grep 16636tcp        0      0 127.0.0.1:16636             0.0.0.0:*                   LISTEN

To create tree like the one shown above, we need to add the following myorg.ldif file:

dn: dc=kijanowski,dc=euobjectclass: topobjectclass: dcObjectobjectclass: organizationdc: kijanowskio: kijanowskidn: o=guvnor,dc=kijanowski,dc=euobjectclass: topobjectclass: organizationo: guvnordn: ou=People,o=guvnor,dc=kijanowski,dc=euobjectclass: topobjectclass: organizationalUnitou: Peopledn: uid=admin,ou=People,o=guvnor,dc=kijanowski,dc=euobjectclass: topobjectclass: uidObjectobjectclass: personobjectClass: inetOrgPersonuid: admincn: Guvnor Adminsn: AdministratoruserPassword: {SSHA}ZGUjbzh0wN0JoWxIAcZfFXpV5MIu/gZwdn: uid=user1,ou=People,o=guvnor,dc=kijanowski,dc=euobjectclass: topobjectclass: uidObjectobjectclass: personobjectClass: inetOrgPersonuid: user1cn: Regular Usersn: RegularuserPassword: {SSHA}Gcif1SlGPu2vHrtoLGYlKXbKBytJiVVFdn: ou=Roles,o=guvnor,dc=kijanowski,dc=euobjectClass: topobjectClass: organizationalUnitou: Rolesdn: cn=admin,ou=Roles,o=guvnor,dc=kijanowski,dc=euobjectClass: topobjectClass: groupOfNamescn: admindescription: the GuvnorAdmin groupmember: uid=admin,ou=People,o=guvnor,dc=kijanowski,dc=eudn: cn=regular,ou=Roles,o=guvnor,dc=kijanowski,dc=euobjectClass: topobjectClass: groupOfNamescn: regulardescription: the Guvnor Regular groupmember: uid=user1,ou=People,o=guvnor,dc=kijanowski,dc=eu

The passwords for admin and user1 are ’9uvn04′ and ‘user1′ (respectively) and were generated with slappasswd. To add this ldif to our directory, we will use an ldap client application called ldapadd. First we need to update its configuration to be able to talk over SSL. Edit the file /data/openldap-2.3.39/etc/openldap/ldap.conf and add following line:

TLS_REQCERT allow

This will prevent us from getting errors like these:

client side:ldap_initialize( ldaps://localhost:16636 )ldap_bind: Can't contact LDAP server (-1)        additional info: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failedserver side:TLS trace: SSL3 alert read:fatal:unknown CATLS trace: SSL_accept:failed in SSLv3 read client certificate ATLS: can't accept.TLS: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca s3_pkt.c:1057connection_read(11): TLS accept failure error=-1 id=4, closingconnection_closing: readying conn=4 sd=11 for closeconnection_close: conn=4 sd=11

Now we can add the ldif file to our directory:

$ /data/openldap-2.3.39/bin/ldapadd -x -D "cn=DirManager,dc=kijanowski,dc=eu" -H ldaps://localhost:16636 -w admin123 -f myorg.ldifadding new entry "dc=kijanowski,dc=eu"adding new entry "o=guvnor,dc=kijanowski,dc=eu"adding new entry "ou=People,o=guvnor,dc=kijanowski,dc=eu"adding new entry "uid=admin,ou=People,o=guvnor,dc=kijanowski,dc=eu"adding new entry "uid=user1,ou=People,o=guvnor,dc=kijanowski,dc=eu"adding new entry "ou=Roles,o=guvnor,dc=kijanowski,dc=eu"adding new entry "cn=admin,ou=Roles,o=guvnor,dc=kijanowski,dc=eu"adding new entry "cn=regular,ou=Roles,o=guvnor,dc=kijanowski,dc=eu"

The last step is to configure JAAS in $JBOSS_SERVER/conf/login-config.xml. Replace the previous file based login module with this one:

            ldaps://localhost:16636            ssl            cn=DirManager,dc=kijanowski,dc=eu            admin123            ou=People,o=guvnor,dc=kijanowski,dc=eu            (uid={0})            ou=Roles,o=guvnor,dc=kijanowski,dc=eu            (member={1})            cn            -1            ONELEVEL_SCOPE

Now restart JBoss AS and try to login as admin with password 9uvn04. The application server will talk with the OpenLDAP server over SSL. If you want to shutdown the OpenLDAP server you need to determine its PID and interrupt it by sending the process a SIGINT signal:

$ kill -INT `cat /data/openldap-2.3.39/var/run/slapd.pid`

Use MySQL as a data repository

Jackrabbit has been chosen as a Java Content Repository (JCR) implementation. By default, it uses the Derby database as a backend. You may want to switch to a database you are more familiar with, and can regularly back up and properly tune. If you have already used the file-based repository and don’t want to loose all your assets, export them. After MySQL is up and running, import them back. To export your current repository, go to the ‘Administration’ menu on the left side, expand ‘Admin,’ choose ‘Import/Export,’ and click on ‘Export’:

Fig 2.2 export

Shut down the server and set up MySQL as your new repository. First, download MySQL and extract it. I will use the community server 5.0.51a standard, extracted to /data/mysql-5.0.51. As root, perform the following steps. (For more details, have a look at the INSTALL-BINARY file):

$ /usr/sbin/groupadd mysql5$ /usr/sbin/useradd -g mysql5 mysql5$ cd /data/mysql-5.0.51$ chown -R mysql5 .$ chgrp -R mysql5 .$ /data/mysql-5.0.51/scripts/mysql_install_db --user=mysql5$ chown -R root .$ chown -R mysql5 data# now start MySQL$ /data/mysql-5.0.51/bin/mysqld_safe --user=mysql5 &# and create a password for root$ /data/mysql-5.0.51/bin/mysqladmin -u root password mysqladminpwdTo shutdown the MySQL server run:$ /data/mysql-5.0.51/bin/mysqladmin -u root shutdown -pLogout as root and log in to MySQL to create a user and database for Guvnor:$ /data/mysql-5.0.51/bin/mysql -u root -pmysql> create database guvnor;Query OK, 1 row affected (0.00 sec)mysql> grant all privileges on guvnor.* to 'guvnor-user'@'localhost' identified by 'guvnor-pwd';Query OK, 0 rows affected (0.00 sec)mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)

Now the DB side is complete.

Edit the $GUVNOR/WEB-INF/components.xml file and provide a path to where you would like to keep the repository configuration files. You can leave the default value–which is the JBoss Application Server’s bin directory–however it is recommended to provide a location that is regularly backed up. Under the ‘repositoryConfiguration’ component add:

/data/GuvnorRepo/

This last step creates a repository.xml file. It is created by default when running Guvnor the first time and is placed into the AS bin directory. This file configures the data repository. We would like to use MySQL, so we will create /data/GuvnorRepo/repository.xml:

                                

As you see we’re using the com.mysql.jdbc.Driver, so we need to provide it. Download the mysql java connector from MySQL, unzip it, and copy the JAR file to $JBOSS_SERVER/lib. (I’m using mysql-connector-java-5.1.6.)

Now you can start the app server. If you have exported your assets, just go to the ‘Administration’ menu, expand ‘Admin,’ choose ‘Import/Export,’ and import your xml file. Please note that you have to unzip your exported xml file before you can upload it.

Enable SSL

The last tweak is enabling SSL. It not only provides security, but also ensures the transmitted data hasn’t been modified. This is strictly a server-side task.

First, we need a certificate. Please note that as the “first and last name” you have to provide the fully qualified domain name of the host. For testing purposes you can use localhost like so:

$ keytool -genkey -alias guvnor -keyalg RSA -keystore $JBOSS_SERVER/conf/guvnor.keystore -validity 365Enter keystore password:  guvnorkspwdWhat is your first and last name?  [Unknown]:  localhostWhat is the name of your organizational unit?  [Unknown]:  My DepartmentWhat is the name of your organization?  [Unknown]:  My CompanyWhat is the name of your City or Locality?  [Unknown]:  My CityWhat is the name of your State or Province?  [Unknown]:  My StateWhat is the two-letter country code for this unit?  [Unknown]:  USIs CN=My Name, OU=My Department, O=My Company, L=My City, ST=My State, C=US correct?  [no]:  yesEnter key password for        (RETURN if same as keystore password):

Now we can enable an SSL connector. Edit the file $JBOSS_SERVER/deploy/jboss-web.deployer/server.xml like so:

Restart your JBoss Application Server. Guvnor should be available at https://localhost:8443/drools-guvnor.

How to use a secured Guvnor package

The last part of this article shows how you can access a drools package from Guvnor in a secure way. This is very straight forward if you use certificates signed by trusted authorities. In our test environment, it’s a little bit more complicated since we use self-signed certificates.

First create a package and deploy it. I’ll use the package we made during the quick introduction. This package is available under https://localhost:8443/drools-guvnor/org.drools.guvnor.Guvnor/package/myNewPackage/LATEST. Replace the url attribute with the new value in Guvnor.properties:

url=https://localhost:8443/drools-guvnor/org.drools.guvnor.Guvnor/package/myNewPackage/LATEST

One would expect that running the Drools application should end successfully, however this is not the case:

RuleAgent(default) INFO (Wed Jul 23 20:38:03 CEST 2008): Configuring with newInstance=false, secondsToRefresh=-1RuleAgent(default) INFO (Wed Jul 23 20:38:03 CEST 2008): Configuring package provider : URLScanner monitoring URLs:  https://localhost:8443/drools-guvnor/org.drools.guvnor.Guvnor/package/myNewPackage/LATESTRuleAgent(default) WARNING (Wed Jul 23 20:38:04 CEST 2008): Was an error contacting https://localhost:8443/drools-guvnor/org.drools.guvnor.Guvnor/package/myNewPackage/LATEST. Reponse header: {}RuleAgent(default) EXCEPTION (Wed Jul 23 20:38:04 CEST 2008): Was unable to reach server.. Stack trace should follow.java.io.IOException: Was unable to reach server.        at org.drools.agent.URLScanner.hasChanged(URLScanner.java:149)        at org.drools.agent.URLScanner.getChangeSet(URLScanner.java:113)        at org.drools.agent.URLScanner.loadPackageChanges(URLScanner.java:90)        at org.drools.agent.RuleAgent.checkForChanges(RuleAgent.java:341)        at org.drools.agent.RuleAgent.refreshRuleBase(RuleAgent.java:300)        at org.drools.agent.RuleAgent.configure(RuleAgent.java:285)        at org.drools.agent.RuleAgent.init(RuleAgent.java:209)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:177)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:149)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:217)        at kijanowski.eu.GuvnorTest.main(GuvnorTest.java:12)Exception in thread "main" java.lang.NullPointerException        at org.drools.agent.RuleAgent.refreshRuleBase(RuleAgent.java:301)        at org.drools.agent.RuleAgent.configure(RuleAgent.java:285)        at org.drools.agent.RuleAgent.init(RuleAgent.java:209)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:177)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:149)        at org.drools.agent.RuleAgent.newRuleAgent(RuleAgent.java:217)        at kijanowski.eu.GuvnorTest.main(GuvnorTest.java:12)

If you navigate with your browser to this URL, you will be asked to accept the non-signed certificate. In case of our test application, we need to trust the server by importing its public key to our (temporary) local keystore:

$ mkdir /data/ssl# export the public key$ keytool -export -alias guvnor -keystore $JBOSS_SERVER/conf/guvnor.keystore -file /data/ssl/out.cert# you don't have to provide a passwordEnter keystore password:*****************  WARNING WARNING WARNING  ****************** The integrity of the information stored in your keystore  ** has NOT been verified!  In order to verify its integrity, ** you must provide your keystore password.                  ******************  WARNING WARNING WARNING  *****************Certificate stored in file # import this key to a local truststore$ keytool -import -alias guvnor -file /data/ssl/out.cert -keystore /data/ssl/myKSEnter keystore password:  qwertyOwner: CN=localhost, OU=My Department, O=My Company, L=My City, ST=My State, C=USIssuer: CN=localhost, OU=My Department, O=My Company, L=My City, ST=My State, C=USSerial number: 48862cb6Valid from: Tue Jul 22 20:53:42 CEST 2008 until: Wed Jul 22 20:53:42 CEST 2009Certificate fingerprints:         MD5:  81:FD:97:97:12:E7:2B:94:DA:62:35:11:2C:2B:4E:2B         SHA1: 7E:B1:36:F4:C9:F9:45:5A:98:F2:F1:46:F6:58:E6:0D:81:46:EC:B5Trust this certificate? [no]:  yesCertificate was added to keystore

Now we have a keystore with a server’s key that we trust. To use this keystore, just start the drools application with the following property:

-Djavax.net.ssl.trustStore=/data/ssl/myKS

In Eclipse, click on GuvnorTest.java. From the menu Run -> Open Run Dialog and then add this property to the VM arguments:

Fig 2.3 eclipse

Now your Drools application runs in a secure environment.

Summary

This article has shown how you can upgrade your BRMS, which should only be deployed out-of-the-box for testing purposes. For a multiuser environment with mission-critical applications, Guvnor should be tuned. Have a look at this blog post, the JSSE Reference Guide or the key tool docs page for more details about the tools we used. For LDAP browsing I recommend this user-friendly and light-weight tool.

One response to “JBoss Drools how-to: Tuning Guvnor, part 2”

  1. Boris says:

    Hi! When i am config Guvner to PostgreSQL 8.3 i get exception:
    org.postgresql.util.PSQLException: ERROR: type “varbinary” does not exist!!!! Postgres not support this type. Need changing the column type from bytea to oid. How and where ???