JBoss Community Archive (Read Only)

JBoss AS 7.1

Using mod_jk with JBoss AS7

In this article I'd like to show you how to use mod_jk as HTTP connector of JBoss AS, and I'll also show you how to configure SSL to work with connector.

Install JBoss EAP 6.1.0

Go to http://www.jboss.org/jbossas/downloads/ and download EAP 6.1.0.Final:

images/author/download/attachments/69534936/SafariScreenSnapz004.png

Unzip jboss-eap-6.1.0.zip and try to start server in standalone mode:

images/author/download/attachments/69534936/iTermScreenSnapz006.png

If everything goes fine you can see server is started:

images/author/download/attachments/69534936/iTermScreenSnapz007.png

Try to access web port and you should see:

images/author/download/attachments/69534936/SafariScreenSnapz005.png

Now we stop server by pressing 'CTRL-C':

images/author/download/attachments/69534936/iTermScreenSnapz008.png

Compile & Install Apache Httpd

Go to http://httpd.apache.org/download.cgi and download httpd 2.2.25:

images/author/download/attachments/69534936/SafariScreenSnapz006.png

images/author/download/attachments/69534936/SafariScreenSnapz007.png

Unzip httpd-2.2.25.tar.bz2 and run configure:

images/author/download/attachments/69534936/iTermScreenSnapz009.png

Please note the command we've used:

./configure --prefix=/Users/weli/projs/httpd-bin --enable-ssl

We define 'httpd-bin' will be the place that we install our compiled httpd. And we've enabled 'ssl' option so we'll have 'mod_ssl' in our httpd binaries.

If everything goes fine the 'configure' should be finished without any problems:

images/author/download/attachments/69534936/iTermScreenSnapz009.png

Now we run 'make' to compile the code:

make

After it finished we run 'make install':

make install

You can see everything is installed to 'prefix' folder we've defined:

images/author/download/attachments/69534936/iTermScreenSnapz011.png

images/author/download/attachments/69534936/iTermScreenSnapz012.png

Then we need to verify 'mod_ssl' is installed correctly:

images/author/download/attachments/69534936/iTermScreenSnapz014.png

Now let's start the httpd and test its connection:

images/author/download/attachments/69534936/iTermScreenSnapz016.png

After verify it works we could shutdown http server for now:

dhcp-17-85:bin weli$ sudo ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -k stop

Install mod_jk

Goto http://tomcat.apache.org/download-connectors.cgi and download JK 1.2.37 Source Release:

images/author/download/attachments/69534936/SafariScreenSnapz008.png

Extract downloaded zip and run 'configure':

images/author/download/attachments/69534936/iTermScreenSnapz017.png

Please note we have defined the position of our httpd binary:

./configure --with-apxs=/Users/weli/projs/httpd-bin/bin/apxs

After configure finished let's compile & install it:

make
make install

If everything goes fine you can see mod_jk is installed to httpd:

images/author/download/attachments/69534936/iTermScreenSnapz018.png

And we can verify 'mod_jk.so' is correctly installed:

dhcp-17-85:native weli$ ls /Users/weli/projs/httpd-bin/modules/mod_jk.so
/Users/weli/projs/httpd-bin/modules/mod_jk.so

But now if you dump modules that is used by httpd you'll see mod_jk is not there yet:

dhcp-17-85:bin weli$ pwd
/Users/weli/projs/httpd-bin/bin
dhcp-17-85:bin weli$ ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -D DUMP_MODULES | grep mod_jk
Syntax OK
dhcp-17-85:bin weli$

Because we haven't configure httpd to load 'mod_jk.so', in next section let's work on it.

Configure mod_jk

First is to open 'httpd.conf' in 'conf' folder:

dhcp-17-85:conf weli$ pwd
/Users/weli/projs/httpd-bin/conf
dhcp-17-85:conf weli$ ls httpd.conf
httpd.conf

Go to the 'Dynamic Shared Object (DSO) Support' section:

#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#

And add mod_jk configurations under this section:

# Load mod_jk.so
LoadModule jk_module /Users/weli/projs/httpd-bin/modules/mod_jk.so

# Config file of mod_jk
JkWorkersFile /Users/weli/projs/httpd-bin/conf/workers.properties

# Redirect all requests to 'worker1' node, which will be the JBoss AS server we've installed.
JkMount /* worker1

# Set mod_jk log level to 'debug', we'll check these debug info later
JkLogLevel debug

After finish the above modifications to 'httpd.conf', let's save the file and exit to test 'mod_jk.so' is loaded by httpd correctly:

dhcp-17-85:bin weli$ ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -D DUMP_MODULES | grep jk
Syntax error on line 59 of /Users/weli/projs/httpd-bin/conf/httpd.conf:
JkWorkersFile: Can't find the workers file specified

Oops, seems we've forgetten to add '/Users/weli/projs/httpd-bin/conf/workers.properties' defined in config, now let's create this file:

dhcp-17-85:conf weli$ pwd
/Users/weli/projs/httpd-bin/conf
dhcp-17-85:conf weli$ touch workers.properties

Now we open this file and put in the config:

worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=127.0.0.1
worker.worker1.port=8009

Let's read the above config line by line:

worker.list=worker1

mod_jk supports cluster by using multple workers(workers could be JBossAS or Tomcat, or the application servers that support ajp13 protocol) in behind. Because for this article we just have one 'worker', which is jboss-eap-6.1.0 we've installed, so we just config one worker here, and named it 'worker1'.

worker.worker1.type=ajp13

We'll use AJP13 protocol for mod_jk to communicate with JBoss AS. You can see in JBoss AS the 'AJP 1.3' procotol stack is enabled in 'standalone-ha.xml':

dhcp-17-85:configuration weli$ pwd
/Users/weli/projs/jboss-eap-6.1/standalone/configuration
dhcp-17-85:configuration weli$ grep 'AJP' standalone-ha.xml
            <connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>

Now let's go back to 'workers.properties':

worker.worker1.host=127.0.0.1
worker.worker1.port=8009

This is the worker's working address and port. This is set according to the config in JBoss AS:

dhcp-17-85:configuration weli$ grep '8009' standalone-ha.xml
        <socket-binding name="ajp" port="8009"/>
dhcp-17-85:configuration weli$ grep 'inet-address.*127.0.0.1' standalone-ha.xml
            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
            <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>

After editing the 'worker.properties' and its meanings, now let's save the file and test httpd config again:

dhcp-17-85:bin weli$ pwd
/Users/weli/projs/httpd-bin/bin
dhcp-17-85:bin weli$ ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -D DUMP_MODULES | grep jk
Syntax OK
 jk_module (shared)

Seems mod_jk is loaded correctly now, so it's time to get all components online and do the testing images/author/images/icons/emoticons/smile.gif

Test Connector

Start JBoss AS

Goto 'bin' folder of JBoss AS and run the startup script:

dhcp-17-85:bin weli$ pwd
/Users/weli/projs/jboss-eap-6.1/bin
dhcp-17-85:bin weli$ ./standalone.sh -c standalone-ha.xml

Server should start with 'standalone-ha' profile:

images/author/download/attachments/69534936/iTermScreenSnapz019.png

After server started, please try to access AJP port:

images/author/download/attachments/69534936/iTermScreenSnapz020.png

As we have verified that JBoss AS is configured properly, now let's move to httpd side.

Start httpd

Before using httpd, we need to bind httpd to public IP address. This is similar to the situations in productisation environment: We ask connector to listen to public address and redirect these requests to backend AS servers sits in LAN.

Binding httpd to public IP address

First we need to find our machine's public IP address:

dhcp-17-85:~ weli$ ifconfig en1
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether 88:53:95:2d:fb:cd
	inet6 fe80::8a53:95ff:fe2d:fbcd%en1 prefixlen 64 scopeid 0x4
	inet 10.0.1.13 netmask 0xffffff00 broadcast 10.0.1.255
	media: autoselect
	status: active

So my machine's public address is

10.0.1.13
. Then we need to configure 'httpd.conf' to listen to this address. Firstly we find 'httpd.conf' and open it:

dhcp-17-85:conf weli$ pwd
/Users/weli/projs/httpd-bin/conf
dhcp-17-85:conf weli$ ls httpd.conf
httpd.conf

We goto 'Listen' section:

#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80

Change

Listen 80
to:

Listen 10.0.1.13:80

Next step we need to setup server name of httpd:

Binding httpd to a hostname

Go to 'ServerName' section of httpd:

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
#ServerName www.example.com:80

Add a ServerName below this section:

ServerName mini

We've set my ServerName as 'mini'. Now let's save 'httpd.conf' and exit editor. Next step is to map this hostname with the public IP address of this machine in

/etc/hosts

images/author/download/attachments/69534936/TextMateScreenSnapz014.png

dhcp-17-85:~ weli$ ping mini
PING mini (10.0.1.13): 56 data bytes
64 bytes from 10.0.1.13: icmp_seq=0 ttl=64 time=0.076 ms
64 bytes from 10.0.1.13: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 10.0.1.13: icmp_seq=2 ttl=64 time=0.053 ms
64 bytes from 10.0.1.13: icmp_seq=3 ttl=64 time=0.058 ms
^C
--- mini ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.053/0.063/0.076/0.009 ms

From the ping output we could see our public IP address is correctly mapped to hostname 'mini'.

Everything seems ready now:

  • JBoss AS is started with 'standalone-ha.xml' profile, and listening to AJP port 8009 binding with IP address '127.0.0.1'

  • httpd is listening on port 80 binding with public IP address '10.0.1.13', and ready to redirect all the requests to 'worker1', which is actually the AS 7 server sitting behind.

Time to make some fun!

Connection Test

Now let's start httpd:

dhcp-17-85:bin weli$ pwd
/Users/weli/projs/httpd-bin/bin
dhcp-17-85:bin weli$ sudo ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -k start

And let's check the debug log of 'mod_jk.so' to verify it is started correctly:

dhcp-17-85:logs weli$ pwd
/Users/weli/projs/httpd-bin/logs
dhcp-17-85:logs weli$ tail -n 1 mod_jk.log
[Wed Aug 07 00:38:13.566 2013] [30877:140735242764672] [debug] jk_child_init::mod_jk.c (3248): Initialized mod_jk/1.2.37

Now let's access our httpd serving address:

http://mini

images/author/download/attachments/69534936/SafariScreenSnapz102.png

With the help of mod_jk, the requests from public address port 80 has been redirected to the backend(through AJP protocol) JBoss AS server which is listening on localhost port 8009.

Recovery Test

Now let's kill the JBoss AS server by using 'CTRL-C':

00:47:46,537 INFO  [org.jboss.as] JBAS015950: JBoss EAP 6.0.0.GA (AS 7.1.2.Final-redhat-1) stopped in 19ms

And now let's connect to 'http://mini' again:

images/author/download/attachments/69534936/SafariScreenSnapz103.png

Because the backend service is down, so httpd could no longer redirect requests to worker. Checking the 'mod_jk.log' and you can see it's reporting the errors:

[Wed Aug 07 00:47:49.375 2013] [30873:140735242764672] [info] ajp_connect_to_endpoint::jk_ajp_common.c (995): Failed opening socket to (127.0.0.1:8009) (errno=61)
[Wed Aug 07 00:47:49.375 2013] [30873:140735242764672] [error] ajp_send_request::jk_ajp_common.c (1630): (worker1) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=61)

Now we start JBoss AS again:

dhcp-17-85:bin weli$ pwd
/Users/weli/projs/jboss-eap-6.1/bin
dhcp-17-85:bin weli$ ./standalone.sh -c standalone-ha.xml

After server started, we try to connect to 'http://mini' again:

images/author/download/attachments/69534936/SafariScreenSnapz102.png

The whole service back to work now.

Using SSL

Using SSL in our system is not as difficult as you think. Because we are using AJP 1.3 protocol in between httpd and JBoss AS, and httpd is listening to public address, so we just need to configure SSL in httpd and that's all:

images/author/download/attachments/69534936/dia.jpg

Now let's see how to enable SSL in httpd:

Configure SSL in httpd

Prepare Certification File

First we create a 'cert' directory in 'httpd-bin' to store certificates:

dhcp-17-85:httpd-bin weli$ pwd
/Users/weli/projs/httpd-bin
dhcp-17-85:httpd-bin weli$ mkdir certs
dhcp-17-85:httpd-bin weli$ ls
bin     certs   conf    htdocs  include man     modules
build   cgi-bin error   icons   logs    manual

Now we enter this directory and create a key:

dhcp-17-85:httpd-bin weli$ cd certs/
dhcp-17-85:certs weli$
dhcp-17-85:certs weli$ openssl genrsa -des3 -out mini.key 1024
Generating RSA private key, 1024 bit long modulus
..........++++++
.........................................++++++
e is 65537 (0x10001)
Enter pass phrase for mini.key: secret
Verifying - Enter pass phrase for mini.key: secret
dhcp-17-85:certs weli$

As show above, we've set the pass phrase as 'secret' and created the key file 'mini.key'. After generating our key, we need to sign it, so next step is to generate a CSR(Certificate Signing Request) file:

dhcp-17-85:certs weli$ openssl req -new -key mini.key -out mini.csr
Enter pass phrase for mini.key: secret
You are about to be asked to enter information that will be incorporated
into 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 blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company): Personal
Organizational Unit Name (eg, section) []:Personal
Common Name (e.g. server FQDN or YOUR name) []:mini
Email Address []:l.weinan@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

In above section, the 'Common Name' section is very important:

Common Name (e.g. server FQDN or YOUR name) []:mini

This must match your 'ServerName' in your 'httpd.conf' and your hostname in '/etc/hosts'.

Last step is to sign this CSR file, we'll use our own key file to sign it:

dhcp-17-85:certs weli$ openssl x509 -req -days 30 -in mini.csr -signkey mini.key -out mini.crt
Signature ok
subject=/C=CN/ST=Beijing/L=Beijing/O=Personal/OU=Personal/CN=mini/emailAddress=l.weinan@gmail.com
Getting Private key
Enter pass phrase for mini.key: secret

Now we have prepared the cert file 'mini.crt':

dhcp-17-85:certs weli$ ls
mini.crt mini.csr mini.key

Next step is to configure httpd to use the cert to enable SSL:

Use Certification File in httpd

Open httpd.conf, and in 'Listen' section, add:

Listen 10.0.1.13:443

for httpd to listen to 443 port (which is default port used by https).

Goto the bottom of 'httpd.conf', add:

NameVirtualHost *:443

<VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile /Users/weli/projs/httpd-bin/certs/mini.crt
        SSLCertificateKeyFile /Users/weli/projs/httpd-bin/certs/mini.key
	JkMount /* worker1  
	JkLogLevel debug  
</VirtualHost>

Now we start httpd:

sudo ./httpd -f /Users/weli/projs/httpd-bin/conf/httpd.conf -k start
Apache/2.2.25 mod_ssl/2.2.25 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server mini:443 (RSA)
Enter pass phrase: secret

OK: Pass Phrase Dialog successful.

And don't forget to start JBoss AS:

./standalone.sh -c 'standalone-ha.xml'

Now it's time to play with our SSL connection:

Test SSL Connector

Try to access:

https://mini

And browser will complain the cert provided by web server is not valid because it's not signed by a CA:

images/author/download/attachments/69534936/SafariScreenSnapz104.png

We know this cert is signed by ourself so just ignore the warning and continue to access the URL:

images/author/download/attachments/69534936/SafariScreenSnapz105.png

Now we can see the https connection is working and the request is successfully send to JBoss AS.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:24:25 UTC, last content change 2013-08-14 16:53:15 UTC.