Apache ProxyPass to 2 different tomcat servers with same URI - apache

I have 2 servers with apache http server (2.4.9) on them. I have 2 servers with tomcat 7.0.39 running on them. Ultimately I need to load balance between the 2, but right now am simply trying to get this ProxyPass configuration to work.
I have one url on the 2 apache servers- example.com. They are load balanced. The load balancing is in place and there is no issue.
I have 2 applications, 1 on each tomcat server. Each tomcat server has 2 instances of tomcat running- each on a different port. They are running a very similar application with the exact same uri.
I need to redirect:
example.com/site1 to example.com/app (for app1)
example.com/site2 to example.com/app (for app2)
I can redirect this easily enough for 1 application only:
ProxyPass /app/ AppSrv:8080/app/
ProxyPassReverse /app/ http://example.com/app/
I can get to the page, log in, no problem. For a singe application only.
When I set up a configuration for both applications, I can get to the login page of both applications as well when configured as such:
ProxyPass /site1/ AppSrv:8080/app
ProxyPassReserve /app/
ProxyPass /site2/ AppSrv:8081/app
ProxyPassReverse /app/
Both urls come up with the tomcat application login page. But neither work after this- they fail. The uri reads 'site1' (or 'site2') not 'app'. I cannot log in.
The application requires the uri '/app/' as the base uri in order to function.
The applications are listening on different ports, but have the same uri. How do I keep the uri in the url, but change it so the application responds?
Ultimately I have to balance this, but I've done that before. This is the part I'm having a hard time with.

Ok, I finally solved this. I had to modify the header.
ProxyPass /site1/ balancer://example.com/app/
ProxyPass /site2/ balancer://example.com/app/
<Location /site1>
ProxyPassReverse /app
ProxyPassReverseCookiePath /app /site1
Header edit Location ^(https?://)?example.com/app/ /site1/
</Location>
<Location /site2>
ProxyPassReverse /app
ProxyPassReverseCookiePath /app /site2
Header edit Location ^(https?://)?example.com/app/ /site2/
</Location>

Related

Proxypass and reverse proxy from apache to nginx

I have subdomain website http://subdomain.mywebsite.com/path which is hosted on Siteground and running on nginx server. I want the users should be able to access the above path or its subpaths through main website URL lets say http://mywebsite.com/path which is running on apache server.
I have tried to proxypass and reverseproxypass using following in apache configuration file on my main website:-
<Location "/path">
ProxyPass "http://subdomain.mywebsite.com/path"
ProxyPassReverse "http://subdomain.mywebsite.com/path"
</Location>
When i access the page http://mywebsite.com/path I get 404 page of siteground whereas the same path is directly accesible using http://subdomain.mywebsite.com/path.
I have been trying to find the solution but could not get it working.
You can use the below configuration:
ProxyPass /path http://subdomain.mywebsite.com/path
ProxyPassReverse /path http://subdomain.mywebsite.com/path

Apache as proxy to use same URL with subroutes for different apps

I am trying to set up an Apache2 web server as a proxy to redirect requests to different apps running on the server in separate Docker containers.
All requests going to route http://my_url.com/App2 should be directed to App2 running at localhost:8002.
All other requests to http://my_url.com should be redirected to App1 running on localhost:8001.
I used the following Apache configuration file:
VirtualHost my_url.com/:80>
ServerName my_url.com
ServerAlias www.my_url.com
ProxyPreserveHost On
ProxyPass /App2/ http://localhost:8002/
ProxyPassReverse /App2/ http://localhost:8002/
ProxyPass / http://localhost:8001/
ProxyPassReverse / http://localhost:8001/
</VirtualHost>
If I try to access App2, it initially redirects to the correct Docker container. However, the Problem is now that if App2 does a redirect to for example the /login route, the subroute /App2/ gets lost and Apache tries to find /login in App1 container.
What should happen is:
App2 wants to redirect to /login and makes the browser access my_url.com/App2/login and not my_url.com/login.
Is this achievable with just Apache configurations or do I need to change the redirects in App2 Docker container?
The issue was the line ProxyPreserveHost On. This resulted in Apache adding the header field:
X-Forwarded-Host: 'my_url.com'
for every request.
Thats why the ProxyPassReverse:
ProxyPassReverse /App2/ http://localhost:8002/
didn't work since it is only rewriting requests from http://localhost:8002/.
Setting ProxyPreserveHost Off (which is also the default) solved the issue for me.

ProxyPassReverse to Tomcat adding path to URL

I'm running Railo 3 in Tomcat 6.0.32. The tomcat server is fronted by Apache 2.2.20. Tomcat and Apache are pre built binaries from openCSW. Railo is just the latest build war deployed in tomcat's autodeploy dir webapps.
Everything is working fine when I try to access railo and content on the tomcat server.
It fails however, when railo on tomcat redirects me to itself. Mostly, when a cfm script uses the CGI.script_name, it will be returned wrong.
On the Apache side, the content is available on www.hostname.com. Apache redirects the user to tomcat through AJP on www.hostname.com:8009/railo/content.
A script on tomcat (taken from open OAuth example) is available at:
/opt/csw/share/tomcat6/webapps/railo/content/oauth_test/examples/admin_consumers.cfm
When I access it and try to perform some action, it calls itself with a few parameters, but at that point, railo dumps out an error, complaining that the file can not be found:
Page /content/railo/content/oauth_test/examples/admin_consumers.cfm [/opt/csw/share/tomcat6/webapps/railo/content/railo/content/oauth_test/examples/admin_consumers.cfm] not found
As you can see railo added twice the relative path from tomcat: /railo/content/railo/content
This is my configuration for the virtual host in Apache:
<VirtualHost *:443>
ServerName www.hostname.com
DocumentRoot "/opt/www/hostname/htdocs/"
ProxyRequests Off
<proxy *="">
Order deny,allow
Allow from all
</proxy>
ProxyPass / ajp://www.hostname.com:8009/railo/content/
ProxyPassReverse / http://www.hostname.com:8888/railo/content/
</VirtualHost>
I tried several variant for the ProxyPassReverse directive, but with no luck so far. Based on extensive searches on the web (The Mystery of ProxyPassReverse), I tried this for the proxypassreverse:
ProxyPassReverse / ajp://www.hostname.com:8009/railo/content/
ProxyPassReverse / http://www.hostname.com:8888/railo/content/
ProxyPassReverse / http://localhost:8888/railo/content/
ProxyPassReverse / https://www.hostname.com
The tomcat server also has a virtual host defined like this:
<Host name="www.hostname.com">
<Context path="" docBase="/opt/csw/share/tomcat6/webapps/railo/content" />
</Host>
But everytime, I always get the error from Railo.
Has anyone ever seen this problem with Railo, or CGI, and has an idea how to fix it?
You are specifying "/railo/content" twice. Once in your "docBase" attribute and again in your Proxy attributes. So, requests being proxied through Apache are going to have "railo/content/" twice in their request paths because you have it listed twice: once in Apache, another time in Tomcat.
Try leaving off the /railo/content/ in your ProxyPassReverse attribute:
ProxyPassReverse / http://www.hostname.com:8888/
This will let the Tomcat config add the /railo/content/ bit all by itself.

Multiple ProxyPassReverse for a Virtual Host with identical URLs

We have a situation where we have one JBoss application that is being proxied by two Apache paths as a Virtual Host below:
<VirtualHost *:80>
ServerName localhost1
ProxyPass /abba/ http://localhost:8080/app/
ProxyPass /babba/ http://localhost:8080/app/
ProxyPassReverse /abba/ http://localhost:8080/app/
ProxyPassReverse /babba/ http://localhost:8080/app/
</VirtualHost>
The routing of /abba/ and /babba/ need to go to the same application - going forward we are using rewrites to add some parameters that the application uses to configure itself based on whether /abba/ or /babba/.
However when the application sends a redirect the ProxyPassReverse does not work as access sayfrom /babba/ gets redirected to /abba/.
I understand the reason as it's the same application - however is there are way of configuring Apache to support two difference routes (ProxyPass and ReverseProxyPass) to the same application.
Many Thanks
Have you tried duplicating the VirtualHost and changing the duplicate to server name "localhost2"?

AJP proxy that maps internal servlet name to a different external name

Using apache2 I want to set up an AJP proxy for a Tomcat server that maps an internal servlet URL to a completely different URL externally. Currently I am using the following configurations:
Apache2 configuration:
<IfModule mod_proxy.c>
ProxyPreserveHost on
ProxyPass /external_name ajp://192.168.1.30:8009/servlet_name
ProxyPassReverse /external_name ajp://192.168.1.30:8009/servlet_name
</IfModule>
Note that external_name and servlet_name are different.
Tomcat 6 configuration:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
This however does not work. Apache seems to forward http requests to Tomcat.
However the URLs and redirects returned by Tomcat are still using the original servlet_name and Apache does not map them to external_name.
Is this possible at all with AJP? If not can it be done using a plain http proxy instead?
Mapping different names between Apache and Tomcat can be quite tricky and depends much on how the web application builds its urls for the response.
Basically your setup is correct, but if your application uses its own servlet_name for redirects and urls ProxyPassReverse won't map them.
If you need this kind of setup have a look at mod_proxy_html (Apache 3rd party module) which will parse and rewrite also the contents, not only the url and response headers as mod_proxy.
( A late answer, but I just ran into this problem myself. )
It appears that ProxyPassReverse using ajp: doesn't work because the headers returned from a redirect don't have an ajp: URL in Location:, they have a http: URL. ProxyPassReverse just causes a rewrite of matching headers, and
that string doesn't match what's being returned.
This should work (provided the Location: field uses that numerical address
and not a host name.)
ProxyPreserveHost on
ProxyPass /external_name ajp://192.168.1.30:8009/servlet_name
ProxyPassReverse /external_name http://192.168.1.30/servlet_name
( You can use 'curl -I' to inspect the redirect headers and debug. )
See this note, or a more involved solution here using mod_proxy_html
for rewriting the URLs in web pages as well.
Additionally to the answer from Steven D. Majewski there is one more problem. If the target application uses the request host name to create a redirect (302 Moved Temporarily), it won't work with multiple host names. One must create multiple configurations for every name, like this:
ProxyPassReverse /external_name http://server.com/servlet_name
ProxyPassReverse /external_name http://server.org/servlet_name
ProxyPassReverse /external_name http://server.co.uk/servlet_name
Actually the ProxyPreserveHost on must solve this issue and replace the HOST header in the incoming requests with the address or IP specified in ProxyPass. Unfortunately it seems to be the ProxyPreserveHost doesn't work with ajp connectors. The tomcat in my configuration still received the host name got from browser instead replacing it with 192.168.1.30. As result the browser based redirects still didn't work for every name.
Following configuration didn't work as well :-(
# NOT WORKING !!!
ProxyPassReverse /external_name http://%{HTTP_HOST}/servlet_name
The workaround was using http instead of ajp.
ProxyPreserveHost on
ProxyPass /external_name ajp://192.168.1.30:8009/servlet_name
ProxyPassReverse /external_name http://192.168.1.30/servlet_name
Did somebody investigate it deeply?
For me, this seemed to cause problems:
ProxyPreserveHost on
ProxyPass /external_name ajp://192.168.1.30:8009/servlet_name
ProxyPassReverse /external_name http://192.168.1.30/servlet_name
While this seemed to work:
ProxyPreserveHost on
ProxyPass /external_name ajp://192.168.1.30:8009/servlet_name
ProxyPassReverse /external_name ajp://192.168.1.30:8009/servlet_name
I don't know why but it just did.