Load Balancing Cluster not working with Apache HTTP Server 2.4.6 and JBoss EAP 7 - apache

I am certifying my application on JBoss EAP 7. My application works on standalone mode but in cluster mode, my application gets deployed but I am unable to login. I am again re-routed to login url.
I have setup cluster using mod_cluster.
There is no error log in Load Balancer Server logs neither on individual nodes of the cluster.
In my test environment, my load balancer and 2 server nodes are on same machine. I have given JBoss nodes different ports and instance-ids to differentiate the nodes.
I am sharing my mod_cluster.conf and JBoss standalone-ha.xml extracts from one of the nodes in cluster.
Following are the snippets in standalone-ha.xml file:
Modcluster settings are:
<subsystem xmlns="urn:jboss:domain:modcluster:2.0">
<mod-cluster-config advertise-socket="modcluster" proxies="proxy1" balancer="testcluster" advertise="true" connector="ajp">
<dynamic-load-provider>
<load-metric type="busyness"/>
</dynamic-load-provider>
</mod-cluster-config>
</subsystem>
Undertow settings are:
<subsystem xmlns="urn:jboss:domain:undertow:3.1" instance-id="node1">
<buffer-cache name="default"/>
<server name="default-server">
<ajp-listener name="ajp" socket-binding="ajp"/>
<http-listener name="default" socket-binding="http" redirect-socket="https"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<filters>
<response-header name="server-header" header-name="Server" header-value="JBoss-EAP/7"/>
<response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
</filters>
</subsystem>
Contents of Socket Binding Group are:
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="jgroups-mping" interface="private" port="0" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
<socket-binding name="jgroups-tcp" interface="private" port="7600"/>
<socket-binding name="jgroups-tcp-fd" interface="private" port="57600"/>
<socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
<socket-binding name="jgroups-udp-fd" interface="private" port="54200"/>
<socket-binding name="modcluster" port="0" multicast-address="224.0.1.105" multicast-port="23364"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
<outbound-socket-binding name="proxy1">
<!-- host and port number of the load-balancer. -->
<remote-destination host="x.x.x.x" port="81"/>
</outbound-socket-binding>
</socket-binding-group>
Contents of mod_cluster.conf are as follows:
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule cluster_slotmem_module modules/mod_cluster_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule advertise_module modules/mod_advertise.so
MemManagerFile "//httpd2.4.6Home/var/cache/mod_cluster"
<IfModule manager_module>
Listen 81
<VirtualHost *:81>
<Directory />
Require all granted
</Directory>
<Location />
Require all granted
</Location>
<Location /mod_cluster_manager>
SetHandler mod_cluster-manager
Require all granted
</Location>
KeepAliveTimeout 60
MaxKeepAliveRequests 0
ManagerBalancerName testcluster
AdvertiseFrequency 5
ServerAdvertise on
EnableMCPMReceive
</VirtualHost>
</IfModule>

Basically you have two options - either create a cluster using JBoss own domain mode or extend you standalone configuration to contain required elements for session replication and sso.
In domain mode, most of the configurations are already present in EAP7 - just extend domain-full-ha profile.
Required changes include enabling distributable flag in your web app web.xml - simply add <distributable/> to your web.xml.
Next add single sign on flag to your undertow system:
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
<single-sign-on/> <!-- FIXME: enable SSO here -->
</host>
And enable cache container required for clustered SSO to work - this requires Infinishpan subsystem, which you might now have, if you only extended standalone-ha profile. If you do not see Infinispan subsystem, have a look at standalone-full of standalone-full-ha profiles. If you do not have it already, add web cache:
/subsystem=infinispan/cache-container=web/distributed-cache=concurrent:add
/subsystem=infinispan/cache-container=web/distributed-cache=concurrent/store=file:add
Again, if you use full-ha profile of either standalone or domain mode, you will probably have these already.
Also you do not mention, if you use JBoss security domain for authorization or not. In case you use some custom auth mechanism, make sure you set the session cookie or tokens correctly - for correct domain and context etc.

Related

undertow subsystem configuration in keycloak for http listener

Hello every one I am trying to configure keycloak and while skimming around the docs I have come across this config for undertow subsystem in wildfly (upon which keycloak runs) and verified it in my standalone.xml file
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
.....
.....
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
Now what I want to know is why the http-listener has a redirect-socket set to "https" as this listener is supposed to be listening for http requests made to the keycloak server? right? and we do have a separate https-listener. Also in a case of reverse proxy sitting in front of keycloak all requests made to keycloak via the proxy using http shall also end up on the http listener right? so why is http-listener redirecting request to a https socket binding?
What at first seems unreasonable has a very simple explanation: Keycloak should communicate with Users and Client over https. So, if a users attempts to start a session over http, he immediately redirected to https.
On the other hand, if a user already started a session over https, there is no need to redirect him further.

Apache clustering and load balancing with tomcat 8 in ubuntu

I want to do clustering and load balancing for my applications running in tomcat. I am using ubuntu, apache version 2.4.18 and two tomcat 8.5 instances. I tried with mod_jk for this but it is not working for me.
following is my configuration in apache and tomcat
in jk.conf
<IfModule jk_module>
JkWorkersFile /etc/apache2/conf/workers.properties
JkLogFile /etc/apache2/log/mod_jk.log
JkLogLevel info
JkShmFile /etc/apache2/log/jk-runtime-status
JkWatchdogInterval 60
JkMount /clusterjsp/* loadbalancer
JkMount /jk-status status
<Location /jk-status>
JkMount jk-status
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
<Location /jk-manager>
JkMount jk-manager
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Location>
</IfModule>
in workers.properies
worker.list=loadbalancer,status
worker.server1.port=8009
worker.server1.host=127.0.0.1
worker.server1.type=ajp13
worker.server1.connection_pool_size=200
worker.server1.connection_pool_timeout=600
worker.server1.socket_keepalive=1
worker.server2.port=7009
worker.server2.host=127.0.0.1
worker.server2.type=ajp13
worker.server2.connection_pool_size=200
worker.server2.connection_pool_timeout=600
worker.server2.socket_keepalive=1
worker.server1.lbfactor=1
worker.server2.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=server1,server2
worker.status.type=status
and in both tomcat server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="server1"> <!-- server2 for another instance -->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="50"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
i did not make any changes in apache2.conf or i don't have httpd.conf in apache home directory. i have deployed same application i both tomcat servers and it is working when using http://localhost:8080/clusterjsp and http://localhost:7070/clusterjsp but When i type http://localhost/clusterjsp in my browser it gives me 404 error but http://localhost shows apache default page.
Can you please let me know what i am missing or what is wrong in my configuration.
Probably it is due to the fact that you are redirecting all incoming requests matching /clusterjsp/* to load balancer, but you don't take care of the requests which don't have anything after the context path. You could try just adding this line to your jk.conf:
JkMount /clusterjsp loadbalancer
There are other aproaches too, but probably this is the easyest one to test.

How to have 2 different web/app servers for the same domain but different context path?

I'm running a standard PHP application on my domain and did set that to www.johndoe.com/p/
Now, the port 80 is apparently serviced by this HTTP server (Apache, not Tomcat). Also, I installed Wildfly 8.2 on this server on port 8000. How, can I use Wildfly WAR applications on the same domain e.g. www.johndoe.com/w/?
I'm positive that there is a way of redirecting the /w/ requests to the Java EE server and keep the /p/ serviced by Apache, right?
I assume mod_proxy (http gateway) and mod_proxy_ajp are simple solutions. Can anyone reflect on my requirements and the the mod_proxy/ajp functionality?
ProxyPass /w ajp://localhost:8000/w
ProxyPassReverse /w http://www.johndoe.com/w
I do not demand load balacing or anything else sophisticated. Just the split of the two contexti. Only port 80 is accessible from the internet.
Thank you.
Okay. Here the resolution.
I added to Wildfly 8.2 standalone.xml the following ajp-listener...
<server name="default-server">
<http-listener name="default" socket-binding="http"/>
<ajp-listener name="ajp" socket-binding="ajp"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
... and bind it to the socket ...
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="ajp" port="${jboss.ajp.port:28009}"/>
<socket-binding name="http" port="${jboss.http.port:28080}"/>
<socket-binding name="https" port="${jboss.https.port:28443}"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="mail.johndoe.com" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
Invoke service wildfly reload or service wildfly restart. To Wildfly listening on AJP requests.
Finally, add to your http.conf file of your Apache Virtual Host Domain the following:
ProxyPass /w ajp://127.0.0.1:28009/w
ProxyPassReverse /w ajp://127.0.0.1:28009/w
Also for Apache, restart with service apache2 reload.
Caution. In Parallels Plesk, the virtual host config file must be edited in /var/www/vhosts/system/johndoe.com/conf/http.conf and NOT in /var/vhosts/johndoe.com/conf/http.conf

Is it possible to run SSL and non-SSL web applications on same standalone Wildfly?

Is it possible to run SSL and non-SSL web applications on same standalone Wildfly?
I am using Wildfly 8.1.0 (Undertow) and I am having troubles at configuring this scenario...
For example, I know how to configure either HTTP or HTTPS themselves, but whenever I try to run a configuration for both, the HTTP response is redirected to the SSL one... :(
Could somebody please point out what to change for example in the default standalone.xml?
Yes it's possible.
first you need to add bellow code in ApplicationRealm
<server-identities>
<ssl>
<keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="abcd1234" alias="server" key-password="abcd1234"/>
</ssl>
</server-identities>
Then you required to add lisner for both http and https
<server name="default-server">
<http-listener name="default-http" socket-binding="http"/>
<https-listener name="default-https" socket-binding="https" security-realm="ApplicationRealm"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
Now configure the connector for both http and https
<subsystem xmlns="urn:jboss:domain:remoting:2.0">
<endpoint worker="default"/>
<http-connector name="http-remoting-connector" connector-ref="default-http" security-realm="ApplicationRealm"/>
<http-connector name="https-remoting-connector" connector-ref="default-https" security-realm="ApplicationRealm"/>
</subsystem>
But generally people won't keep enable both http and https. They redirect the request from http to https.

SSL between apache and JBoss

We have the next configuration:
one apache server with version 2.2.14.
two application servers with JBoss Application Server version 7.1.1 in domain mode.
We configure a virtual hosts and mod_cluster discover application servers without problem, but when I add the configuration for ssl then mod_cluster cannot discover application servers.
The file httpd-vhosts.conf is:
Listen <ip>:10001
MemManagerFile /var/cache/httpd
<VirtualHost <ip>:10001>
ErrorLog "/usr/IBMAHS/logs/error_ssl_log"
TransferLog "/usr/IBMAHS/logs/access_ssl_log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "/usr/IBMAHS/pki/file.com.crt"
SSLCertificateKeyFile "/usr/IBMAHS/pki/file.com.key"
<Directory />
Order deny,allow
Allow from all
</Directory>
KeepAliveTimeout 60
MaxKeepAliveRequests 0
ManagerBalancerName other-server-group_d
ServerAdvertise On
AdvertiseFrequency 5
#EnableMCPMReceive
#This directive allows you to view mod_cluster status at URL http://<ip>:10001/mod_cluster-manager
<Location /mod_cluster-manager>
SetHandler mod_cluster-manager
Order deny,allow
Allow from all
</Location>
</VirtualHost>
Can anyone help me?
I assume you would like to have this setup up and running:
clients <-- SSL --> balancer <-- SSL --> AS7 workers
and that you are aware of severe performance drawback of its
balancer <-- SSL --> AS7 workers
part. The following setup works, yet one must be aware of the fact that connection between client and AS7 worker is not transparent and that the balancer acts more or less like a man-in-the-middle. If clients trust the balancer, balancer trusts the workers and workers trust the balancer, it's all good.
Here you go bro:
Apache HTTP Server with mod_cluster
MemManagerFile "/opt/httpd/cache/mod_cluster"
ServerName 10.16.94.122:2181
<IfModule manager_module>
Listen 10.16.94.122:8847
# As soon as it works, remove/change this...
LogLevel debug
<VirtualHost 10.16.94.122:8847>
ServerName 10.16.94.122:8847
<Directory />
Order deny,allow
Deny from all
# Obviously, testing purposes...
Allow from all
</Directory>
KeepAliveTimeout 60
MaxKeepAliveRequests 0
ServerAdvertise on
AdvertiseFrequency 5
ManagerBalancerName qacluster
AdvertiseGroup 224.0.5.188:23364
EnableMCPMReceive
SSLEngine on
SSLCipherSuite AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL
SSLCertificateFile /opt/ssl/proper/server.crt
SSLCertificateKeyFile /opt/ssl/proper/server.key
SSLCACertificateFile /opt/ssl/proper/myca.crt
#SSLVerifyClient require
#SSLProxyVerify require
SSLProxyEngine On
SSLVerifyDepth 10
<Location /mcm>
SetHandler mod_cluster-manager
Order deny,allow
Deny from all
# Obviously, testing purposes...
Allow from all
</Location>
</VirtualHost>
</IfModule>
AS7 worker, standalone-ha.xml, could be applied to a proper in domain as well:
AS7 worker
+++
</extensions>
<system-properties>
<property name="javax.net.ssl.trustStore" value="/opt/ssl/proper/client-cert-key.jks"/>
<property name="javax.net.ssl.trustStorePassword" value="you-shall-never-know"/>
</system-properties>
<management>
+++
</management>
<profile>
+++
<subsystem xmlns="urn:jboss:domain:modcluster:1.1">
<mod-cluster-config advertise-socket="modcluster" connector="https">
<dynamic-load-provider>
<load-metric type="busyness"/>
</dynamic-load-provider>
<ssl key-alias="javaclient" password="you-shall-never-know" certificate-key-file="/opt/ssl/proper/client-cert-key.jks"
cipher-suite="AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL" ca-certificate-file="/opt/ssl/proper/ca-cert.jks"/>
</mod-cluster-config>
</subsystem>
+++
<subsystem xmlns="urn:jboss:domain:web:1.5" native="false">
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true" enabled="true">
<ssl name="https" key-alias="javaclient" password="you-shall-never-know" certificate-key-file="/opt/ssl/proper/client-cert-key.jks"
cipher-suite="AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL" protocol="TLS" verify-client="false"
certificate-file="/opt/ssl/proper/client-cert-key.jks" ca-certificate-file="/opt/ssl/proper/ca-cert.jks"/>
</connector>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
</subsystem>
+++
</profile>
<interfaces>
+++
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+++
<socket-binding name="https" port="8443"/>
+++
<socket-binding name="modcluster" port="0" multicast-address="224.0.5.188" multicast-port="23364"/>
+++
Let us know if it works for you. In future, you might actually target the JBoss mod_cluster forums directly :-)
Have you a sample configuration for standalone (not clustered) ?