Mixing RewriteRule and ProxyPass in Apache - apache

I was working on debugging an issue today related to mixing mod_proxy and mod_rewrite together and I ended up having to use balancer://mycluster in the RewriteRule in order to stop receiving a 404 error from Apache. I have two questions:
1) Is there any other way to get the rewritten URL to go through the balancer without adding balancer://mycluster into the RewriteRule?
2) Is there a way to define all the parameters I defined in ProxyPass (stickysession=JSESSIONID|jsessionid scolonpathdelim=On lbmethod=bytraffic nofailover=Off) in either the <Proxy> or RewriteRule? I'm concerned the requests that match the new RewriteRule won't load balance in the same fashion as those that go through ProxyPass (like /app1/something.do)?
Below are the relevant sections of the httpd.conf. I am using Apache 2.2.
<Proxy balancer://mycluster>
Order deny,allow
Allow from all
BalancerMember ajp://my.domain.com:8009 route=node1
BalancerMember ajp://my.domain.com:8009 route=node2
</Proxy>
ProxyPass /app1 balancer://mycluster/app1 stickysession=JSESSIONID|jsessionid scolonpathdelim=On lbmethod=bytraffic nofailover=Off
ProxyPassReverse /app1 ajp://my.domain.com:8009/app1
...
RewriteRule ^/static/cms/image/(.*)\.(.*) balancer://mycluster/app1/$1.$2 [P,L]

Looks like I can use the ProxySet directive so the URL's that match the RewriteRule load balance in the same fashion.
<Proxy balancer://mycluster>
Order deny,allow
Allow from all
BalancerMember ajp://my.domain.com:8009 route=node1
BalancerMember ajp://my.domain.com:8009 route=node2
ProxySet stickysession=JSESSIONID|jsessionid scolonpathdelim=On lbmethod=bytraffic nofailover=Off
</Proxy>

Related

configuring multiple domains using virtual host with mod proxy in a single httpd instance

I have an apache instance running three domains using name based virtual hosting and every domain has resources to reverse proxy them down to an application server. Application server is a JBoss running a since JVM instance (http://x.x.x.x:8080/)
The domains along with their resources are,
www.abc.com
- alpha
www.def.com
- beta
www.ghi.com
- gamma
- (root URL - no resource)
abd.com and def.com domains have one resource whereas ghi.com has two (root (/) and gamma).
this is how we have setup virtual hosting for three different domains. A sample for abc.com domain is below,
<VirtualHost *>
ServerName abc.com
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/alpha" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster1>
<LimitExcept POST GET>
order Allow,Deny
Deny from all
</LimitExcept>
BalancerMember http://x.x.x.x:8080 route=1 retry=0
BalancerMember http://x.x.x.x:8081 route=2 retry=0
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /alpha balancer://mycluster4/alpha
ProxyPassReverse /alpha balancer://mycluster4/alpha
</VirtualHost>
With all configuration in place when I try accessing these domains,
www.abc.com/alpha --> works
www.def.com/beta --> works
www.ghi.com/gamma --> works
www.ghi.com/ --> works
since ghi.com domain has a root mapping (/) I am able to access resources of other domain through ghi.com and if I remove the root mapping, cross domain resource accessibility does not work.
www.ghi.com/alpha --> works
www.ghi.com/beta --> works
I do not want the resources of other domain to be accessed through ghi.com. I cannot remove root mapping from ghi.com virtual host configuration.
We have tried multiple configuration but none has worked out.
I may sound bit non technical here which I apologize, but this is my problem statement and I am looking for for a fix.
update 1: configuration file after fix proposed by pandurang.
NameVirtualHost *
<VirtualHost *>
ServerName ghi.com
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/gamma " env=BALANCER_ROUTE_CHANGED
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/ " env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster4>
<LimitExcept POST GET>
order Allow,Deny
Deny from all
</LimitExcept>
BalancerMember http://x.x.x.x:8080 route=1 retry=0
BalancerMember http://x.x.x.x:8081 route=2 retry=0
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /gamma balancer://mycluster4/gamma
ProxyPassReverse /gamma balancer://mycluster4/gamma
ProxyPass / balancer://mycluster4/
ProxyPassReverse / balancer://mycluster4/
ProxyPass /alpha !
</VirtualHost>
Use the below sequence and test.
ProxyPass /alpha !
ProxyPass /gamma balancer://mycluster4/gamma
ProxyPassReverse /gamma balancer://mycluster4/gamma
ProxyPass / balancer://mycluster4/
ProxyPassReverse / balancer://mycluster4/
Create Three different Name-based VirtualHost and disable context(alpha and beta) in www.ghi.com.
<VirtualHost www.abc.com>
ServerName abc.com
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/alpha" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster1>
<LimitExcept POST GET>
order Allow,Deny
Deny from all
</LimitExcept>
BalancerMember http://x.x.x.x:8080 route=1 retry=0
BalancerMember http://x.x.x.x:8081 route=2 retry=0
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /alpha balancer://mycluster4/alpha
ProxyPassReverse /alpha balancer://mycluster4/alpha
</VirtualHost>
<VirtualHost www.def.com>
ServerName def.com
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/beta" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster1>
<LimitExcept POST GET>
order Allow,Deny
Deny from all
</LimitExcept>
BalancerMember http://x.x.x.x:8080 route=1 retry=0
BalancerMember http://x.x.x.x:8081 route=2 retry=0
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /beta balancer://mycluster4/beta
ProxyPassReverse /beta balancer://mycluster4/beta
</VirtualHost>
<VirtualHost www.ghi.com>
ServerName ghi.com
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster1>
<LimitExcept POST GET>
order Allow,Deny
Deny from all
</LimitExcept>
BalancerMember http://x.x.x.x:8080 route=1 retry=0
BalancerMember http://x.x.x.x:8081 route=2 retry=0
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /alpha !
ProxyPass /beta !
ProxyPass / balancer://mycluster4/
ProxyPassReverse / balancer://mycluster4/
</VirtualHost>

ProxyPass redirect to the same path

I have two management console wildlfy and I want to access to both of them through reverse proxy. For that I did this conf in my httpd reverse proxy:
<VirtualHost X.X.X.X:80>
ServerName reverse.com
ProxyPreserveHost On
RewriteEngine On
<Proxy balancer://wildfly-1>
BalancerMember http://wildfly-1.com route=wildfly-1 disablereuse=On keepalive=On retry=20
ProxySet lbmethod=bybusyness
</Proxy>
RewriteRule ^/wildfly-1-console/?$ / [R]
ProxyPass / balancer://wildfly-1/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse / balancer://wildfly-1/
<Proxy balancer://wildfly-2>
BalancerMember http://wildfly-2.com route=wildfly-2 disablereuse=On keepalive=On retry=20
ProxySet lbmethod=bybusyness
</proxy>
RewriteRule ^/wildfly-2-console/?$ / [R]
ProxyPass / balancer://wildfly-2/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse / balancer://wildfly-2/
</VirtualHost>
My problem is that when I enter http://X.X.X.X:80/wildlfy1 or 2 it works, the rewriterules works perfectly and redirect to the management console, But only for the first console. I think that the problem is with my rewriterules, it redirect to the same path "/", so my reverse ignore the second redirection. How can I solve that ?
Thanks.
this was to long or a comment. This is what I meant:
<VirtualHost X.X.X.X:80>
ServerName reverse.com
ProxyPreserveHost On
RewriteEngine On
ProxyPass /wildfly-1-console http://wildfly-1.com
ProxyPassReverse /wildfly-1-console http://wildfly-1.com
ProxyPass /wildfly-2-console http://wildfly-2.com
ProxyPassReverse /wildfly-2-console http://wildfly-2.com
</VirtualHost>
This way heach URL is served via a proxy to another site.
Note that this is far from a complete configuration, it is just to show the concept. I was also no able to test it, as I have no access to an Apache right now.
As for the sticky session, you are applying balancer concepts to a single member, so it serves no purpose. The sticky cookie is to ensure you will return to the same instance for every request. Here is you ask for no1, you get no1. If you ask for no2, you get no2. It is not possible for you to ask for /wildfly-1-console and be "proxied" to http://wildfly-2.com.
Now if you want to have a single URL to proxy in front of http://wildfly-1.com AND http://wildfly-2.com, that is a subject for another question (well some research on your part :-)

Force URL pattern to specific balancer member in apache

I have a load balancer in apache with currently only two members. I want the URL's starting with "admin" to be mapped to a specific instance (http://localhost:16666/) because the admin site needs access to files on the CDN which is also in this machine. I could handle this by mounting this folder to the other server, or implementing a separate service doing this, but that's the last thing I want now. I was about to create a new proxypass rule to map these to this member rather than the balancer, but it simply ignores it.
The important part of my vhost config:
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
<Proxy balancer://videoportal>
BalancerMember http://localhost:16666
BalancerMember http://example.com:16666
Require all granted
ProxySet lbmethod=byrequests
</Proxy>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ErrorLog /var/log/apache2/videoportal-error.log
ProxyPass /balancer-manager !
ProxyPass "/admin" "http://localhost:16666/admin"
ProxyPassReverse "/admin" "http://localhost:16666/admin"
ProxyPass / balancer://videoportal/
ProxyPassReverse / balancer://videoportal/
ProxyRequests Off
Any advice what am I doing wrong?
First you are mixing apache 2.2 and apache 2.4 config
In apache 2.2 use
Order deny,allow
Allow from all
//Your apache config//
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
In apache 2.4
Require all granted
//Your apache config//
<Proxy balancer://videoportal>
...
Require all granted
ProxySet lbmethod=byrequests
</Proxy>
Second try put the /admin before the balancer definition
...
SetHandler balancer-manager
</Location>
ProxyPass "/admin" "http://localhost:16666/admin"
ProxyPassReverse "/admin" "http://localhost:16666/admin"
<Proxy balancer://videoportal>
BalancerMember http://localhost:16666
...
I figured out what was the problem.
I created a location rule for this and added a header to track if it's working:
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
<Proxy balancer://videoportal>
BalancerMember http://localhost:16666
BalancerMember http://example.com:16666
Require all granted
ProxySet lbmethod=byrequests
</Proxy>
<Proxy *>
Require all granted
</Proxy>
ErrorLog /var/log/apache2/videoportal-error.log
ProxyPass /balancer-manager !
# This is the new part
<Location "/admin">
ProxyPass "http://localhost:16666/admin"
ProxyPassReverse "http://localhost:16666/admin"
Header set ADMIN "true"
</Location>
# end of new part
ProxyPass / balancer://videoportal/
ProxyPassReverse / balancer://videoportal/
ProxyRequests Off

Apache 2.4 - configure ProxyPass based on full url instead of trailing path

Currently I have the following ProxyPass's configured in my Apache httpd.conf file.
The goal is to have one Proxypass on http://myurl.com:port1/mypath to one balance group, and then have any additional Proxypass go to http://myurl.com:port2/mypath to any additional balance groups.
Here is my code currently as is which only works based on the /mypath apparently and can have no proceeding URL. The problem is my two /mypath's are the same and only differ by port1 and port2 in the URL.
I am currently listening on Port1 and Port2 defined above in Apache, but I have no way currently to distinguish if someone who comes in on myurl.com:port1 will get directed to Group1 or Group2 in the balance manager because the /mypath is the same for both.
<IfModule proxy_module>
ProxyPass /mypath balancer://Group1/ stickysession=JSESSIONID|jsessionid
ProxyPass /mypath balancer://Group2/ stickysession=JSESSIONID|jsessionid
<Proxy balancer://Group1>
BalancerMember ajp://myurl.com:portX/mypath route=TC01
</Proxy>
<Proxy balancer://Group2>
BalancerMember ajp://myurl.com:portY/mypath route=TC01
</Proxy>
</IfModule>
The below does not work but this is essentially what I am trying to do:
<IfModule proxy_module>
ProxyPass http://myurl.com:port1/mypath balancer://Group1/ stickysession=JSESSIONID|jsessionid
ProxyPass http://myurl.com:port2/mypath balancer://Group2/ stickysession=JSESSIONID|jsessionid
<Proxy balancer://Group1>
BalancerMember ajp://myurl.com:portX/mypath route=TC01
</Proxy>
<Proxy balancer://Group2>
BalancerMember ajp://myurl.com:portY/mypath route=TC01
</Proxy>
</IfModule>
Since ProxyPass cannot occur within <If> section, seems like you are left with splitting your configuration in two VirtualHosts:
<VirtualHost *:port1>
ServerName myurl.com
<Proxy balancer://Group1>
BalancerMember ajp://myurl.com:portX/mypath route=TC01
</Proxy>
ProxyPass /mypath balancer://Group1/ stickysession=JSESSIONID|jsessionid
</VirtualHost>
<VirtualHost *:port2>
ServerName myurl.com
<Proxy balancer://Group2>
BalancerMember ajp://myurl.com:portY/mypath route=TC01
</Proxy>
ProxyPass /mypath balancer://Group2/ stickysession=JSESSIONID|jsessionid
</VirtualHost>

Load Balancer with Apache HTTPD

I'm struggling to set up a an Apache httpd load balancer in front of a couple of application servers. This is my configuration:
ProxyRequests off
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1:8080
BalancerMember http://remote-svr:8080
ProxySet lbmethod=bybusyness
ProxySet stickysession=JESSIONIDSSO
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
ProxyPassReverseCookieDomain http://127.0.0.1:8080 localhost
ProxyPassReverseCookieDomain http://remote-svr:8080 localhost
I'm not sure the last 2 lines do anything, although one of the many examples I've looked at online used them, so I added them to see if it fixed my problem (it didn't).
The issue is that if I comment out either of the BalancerMember lines eg:
#BalancerMember http://127.0.0.1:8080
BalancerMember http://remote-svr:8080
Then the behaviour from a user perspective is fine, however when both members are active, the behaviour is wrong.
The application initially displays a login screen, however when both load balancers are active, the user on submitting their username and password just get redirected back to the login screen again, maybe the session is being lost somewhere. Does anyone have any idea what the issue might be?
EDIT - NOW WORKING
for reference, this setup now seems to work:
ProxyRequests off
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1:8080 route=localServer
BalancerMember http://remote-svr:8080 route=remoteServer
ProxySet lbmethod=bybusyness
ProxySet stickysession=ROUTEID
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
Note the 'route' attribute for the individual nodes needs to be set on the nodes themselves (server.xml in this case, as the servers run JBoss). JSESSIONID worked ok as the sticky session cookie for individual applications but there is more than one application on each server, and the user needs to use the same node for all.
If I were to guess you probably loose the session due to a typo in this section:
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1:8080
BalancerMember http://remote-svr:8080
ProxySet lbmethod=bybusyness
ProxySet stickysession=JESSIONIDSSO
</Proxy>
ProxySet stickysession=JESSIONIDSSO this should probably say ProxySet stickysession=JSESSIONIDSSO? Or maybe even JSESSIONID?