This document is a walk through of setting up Apache httpd on Redhat Enterprise Linux 6 for use as a reverse proxy/load balancer for a PIM 12.9/12.9SP1 ENTM and load balancing ENTM. The configuration file for Apache httpd should be applicable to any OS with potential minor modifications to paths.
Introduction
The proxy component of PIM uses websockets, which in turn requires at least Apache httpd version 2.4. Unfortunately, Redhat Enterprise Linux 6 only provides Apache 2.2, so we have to install Apache 2.4. Usually the simplest way of doing this is to compile from source. This document assumes you have the necessary build tools installed.
There will be three servers involved in this scenario:
1. <LBSERVER> is the load balancing server. This is the server where Apache httpd will be running.
2. <ENTM> is the primary Enterprise Management server
3. <LBENTM> is the load balancing Enterprise Management server
The assumption has been made that both <ENTM> and <LBENTM> are installed and working and serving SSL from port 18443. It is very important that this is the case. There is no point in implementing a reverse proxy to servers that do not work themselves, it just adds an additional layer to debug.
The aim is to have Apache httpd serving SSL on only port 8443 on <LBSERVER> acting as a reverse proxy to <ENTM> and <LBENTM>. No other ports will be served by Apache httpd.
I have also added a rewrite so that users who go to https://<LBSERVER>:8443/ will automatically be redirected to https://<LBSERVER>:8443/iam/ac.
***** YOU MUST MAKE SURE THAT NOTHING IS RUNNING ON PORT 8443 on <LBSERVER> BEFORE CONTINUING *****
Use the following command to determine if anything is running on port 8443:
netstat -an | grep ":8443 "
If it returns nothing then nothing is running on port 8443 and you are set to go.
Section 1: Compile Apache 2.4 on <LBSERVER>
1. Download the latest 2.4.x version from an apache mirror:
The latest version at the time of writing is 2.4.18.
https://httpd.apache.org/download.cgi
2. Download the latest Apache Portable Runtime from an apache mirror:
https://apr.apache.org/download.cgi
You need both apr and apr-util.
To make steps 1 and 2 easy, direct links (but please use a mirror if possible):
http://www.us.apache.org/dist/httpd/httpd-2.4.18.tar.gz
http://www.us.apache.org/dist/apr/apr-1.5.2.tar.gz
http://www.us.apache.org/dist/apr/apr-util-1.5.4.tar.gz
3. Unpack and prepare the source:
# tar xf httpd-2.4.18.tar.gz
# tar xf apr-1.5.2.tar.gz
# tar xf apr-util-1.5.4.tar.gz
# cp -a apr-1.5.4 httpd-2.4.18/srclib/apr
# cp -a apr-util-1.5.4 httpd-2.4.18/srclib/apr-util
4. Configure the source
# cd httpd-2.4.18
# ./configure --enable-ssl --enable-so --with-included-apr --with-mpm=event
Depending on your OS install, this might return errors regarding missing packages. For example:
checking for pcre-config... false
configure: error: pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/
For missing packages, you usually have to install the "-devel" rpm, not the normal rpm, for the above example:
yum install pcre-devel
not
yum install pcre
Unfortunately you have to use a bit of fuzzy logic to determine which package you would need to install. RHEL6 (and CentOS) has the necessary packages in it's repositories so you should not build from source, and especially do not need to install random rpms from the internet (unless you enjoy rpm **** and having insecure systems). So, if you are about to compile a prerequisite from source or use an rpm you downloaded from the internet, unless you have a specific need to, please consider if you really need to do it.
5. Make and make install
# make
The following must be run as root (or with root permissions, e.g. sudo, su -c etc, anyway):
# make install
Apache is now installed in /usr/local/apache2
Section 2: Test the Apache 2.4 Installation
1. Start apache:
# /usr/local/apache2/bin/apachectl start
2. Check that it is bound to the correct interfaces
# netstat -an | grep ':80'
If the results do not include the following:
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
Then you need to edit /usr/local/apache2/conf/httpd.conf using vi, nano etc, find the line:
Listen 80
And change it to:
Listen 0.0.0.0:80
This tells apache to bind to port 80 on all network interfaces. We will change this line later, but at the moment we are just testing the installation.
3. Restart apache
# /usr/local/apache2/bin/apachectl restart
4. Run netstat -an | grep ':80' again and the results should now include:
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
5. In a browser on a client machine go to http://<LBSERVER>. If everything is working is should return a page that simply states:
"It works!"
6. Stop apache:
# /usr/local/apache2/bin/apachectl stop
Section 3: Generate certificate and key
1. Execute the following command, and fill in the details as required and when prompted:
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /usr/local/apache24/conf/apache.key -out /usr/local/apache24/conf/apache.crt
2. When the certificate and key have been created, make the key and certificate readable and writable only by root
# chmod 600 /usr/local/apache24/conf/apache.key
# chmod 600 /usr/local/apache24/conf/apache.crt
Section 4: Configure Apache 2.4
Credit to Vedran Pauk for (beating me to :)) working out how to proxy the proxy stuff/pimclient.
On <LBSERVER> Make sure /etc/hosts is not setting the hostname/FQDN of <LBSERVER> to 127.0.0.1. If you get ssl errors from the browser and cannot connect after completing this section this is probably the reason why. Firefox will show a "ssl_error_rx_record_too_long" error. Chrome and IE just give a general and unhelpful general SSL not working kind of error message.
In all these steps we will be editing /usr/local/apache2/conf/httpd.conf, use any text editor you wish, nano, vi etc.
1. Comment out either
Listen 0.0.0.0:80
Or, if you did not make the change when testing the install (Section 2, Step 2)
Listen 80
Essentially, at this point we want all Listen directives in httpd.conf to be commented out.
2. Comment out:
DocumentRoot "/usr/local/apache2/htdocs"
<Directory "/usr/local/apache2/htdocs">
And comment out everything from the line above, up to and including:
</Directory>
3. Uncomment the following LoadModule statements:
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule rewrite_module modules/mod_rewrite.so
4. Modify:
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
To:
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"
# Apache Foundation probably know what they are talking about so, use
# default values for SSL from /usr/local/apache2/conf/extra/httpd-ssl.conf
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on
SSLProtocol all -SSLv3
SSLPassPhraseDialog builtin
</IfModule>
5. Add the following lines at the end of the file:
Listen 0.0.0.0:8443 https
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
6. Add the following lines, replacing...
<ENTM> with the FQDN of the primary ENTM
<LBENTM> with the FQDN of the load balancing ENTM
<LBSERVER> with the FQDN of the server where apache is installed (the server we are working on)
<SERVERADMN_EMAIL_ADDRESS> with the email addess of the administrator of the server
<Proxy balancer://pim>
BalancerMember https://<ENTM>:18443 lbset=0 route=1
BalancerMember https://<LBENTM>:18443 lbset=0 route=2
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://proxy>
BalancerMember https://<ENTM>:8443 route=1
BalancerMember https://<LBENTM>:8443 route=2
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<Proxy balancer://ws>
# ***** NOTE: The protocol must be wss, not ws, http or https *****
BalancerMember wss://<ENTM>:8443 route=1
BalancerMember wss://<LBENTM>:8443 route=2
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<VirtualHost <LBSERVER>:8443>
SSLEngine On
SSLProxyEngine On
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off
SSLProxyVerify none
SSLProxyCheckPeerName off
ServerName <LBSERVER>
ServerAdmin <SERVERADMN_EMAIL_ADDRESS>
SSLCertificateFile "/usr/local/apache24/conf/apache.crt"
SSLCertificateKeyFile "/usr/local/apache24/conf/apache.key"
ProxyPass /app balancer://pim/app
ProxyPassReverse /app balancer://pim/app
ProxyPass /iam balancer://pim/iam
ProxyPassReverse /iam balancer://pim/iam
ProxyPass /idmmanage balancer://pim/idmmanage
ProxyPassReverse /idmmanage balancer://pim/idmmanage
ProxyPass /castylesr5.1.1 balancer://pim/castylesr5.1.1
ProxyPassReverse /castylesr5.1.1 balancer://pim/castylesr5.1.1
ProxyPass /pimclient/websocket-tunnel balancer://ws/pimclient/websocket-tunnel
ProxyPassReverse /pimclient/websocket-tunnel balancer://ws/pimclient/websocket-tunnel
ProxyPass /pimclient/pim-websocket-play balancer://ws/pimclient/pim-websocket-play
ProxyPassReverse /pimclient/pim-websocket-play balancer://ws/pimclient/pim-websocket-play
ProxyPass /pimclient balancer://proxy/pimclient
ProxyPassReverse /pimclient balancer://proxy/pimclient
LogFormat "%h \"%{BALANCER_WORKER_NAME}e\" %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" custom
CustomLog logs/proxy-access.log custom
RewriteEngine on
RewriteRule "^/$" "/iam/ac/" [R]
</VirtualHost>
Section 5: Starting and Testing
1. Restart apache:
# /usr/local/apache2/bin/apachectl start
2. When you are presented with a prompt again (should only be a second or two), in a browser on a client, go to:
https://<LBSERVER>:8443
You may be prompted with some SSL warnings due to using a self signed certificate as per Section 3 - Generate the SSL keys and certificate. Once past these you should be presented with the ControlMinder/PIM login. Test by browsing around and trying a few things, checking out accounts using PROXY_RDP and PROXY_SSH etc.
3. Assuming everything appears to be working, run a few different browser sessions (that is different session, not just different tabs or windows of the same browser session) on different client machines. Then, look in /usr/local/apache2/logs/proxy-access.log and you should see entries like the below:
123.123.123.123 "https://<ENTM>:18443" - [26/Nov/2015:09:35:01 +1100] "POST /iam/ac/ca12/index.jsp?facesViewId=/app/page/screen/standard_search.jsp HTTP/1.1" 200 166071 "https://<LBSERVER>:8443/iam/ac/ca12/index.jsp?facesViewId=/app/page/screen/standard_search.jsp" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0"
123.123.123.123 is the IP Address of the client where the browser is running.
https://<ENTM>:18443 will be either the hostname/FQDN of the ENTM or LBENTM. There should be a good mix of <ENTM> and <LBENTM> to show that the load balancing is working - if you have used different browser sessions, opening new tabs and/or windows of existing browser sessions does not work to test this.
https://<LBSERVER>:8443 is the hostname/FQDN of the server we installed Apache httpd on.
4. Starting apache at boot. You can write complicated init scripts etc, but that is way out of the scope of this document. To just get it started at boot, edit /etc/rc.local and add the line:
/usr/local/apache2/bin/apachectl start