Infinite redirect when using mod_proxy_ajp ? - apache

I'm trying to configure access from the root context of port 80 to redirect to my tomcat app. My config is set up like
<VirtualHost *:80>
ServerName localhost
ErrorLog /var/log/apache2/ajp.error.log
CustomLog /var/log/apache2/ajp.log combined
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
ProxyPass / ajp://localhost:8009/testApp
ProxyPassReverse / http://localhost/testApp
</VirtualHost>
Is this the correct way to do this ? It currently results in an infinite redirect loop.

Your ProxyPassReverse configuration is wrong. You want:
ProxyPass / ajp://localhost:8009/testApp
ProxyPassReverse / ajp://localhost:8009/testApp
The ProxyPass and ProxyPassReverse lines should have identical arguments.
Since you are changing the application path you may run into all sorts of additional issues including but not limited to:
cookies having the wrong path
embedded links using the wrong path
some libraries that place paths in custom HTTP headers using the wrong paths
Generally, life is a lot easier if you rename testApp to ROOT.

Related

Apache ProxyPass not working for custom app

i have the following situation:
i need to call the following url http://myapp.mydomain.com
and the url should reply as following
http://myapp.mydomain.com/index.jsp
On my apache 2.4
i tryied different setup but none seems to work,
First attempt
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /myapp http://127.0.0.1:8080/myapp
ProxyPassReverse /myapp http://127.0.0.1:8080/myapp
</VirtualHost>
Second attempt
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass /myapp/ http://127.0.0.1:8080/myapp/
ProxyPassReverse /myapp/ http://127.0.0.1:8080/myapp/
</VirtualHost>
Third attempt
<Location "/myapp/">
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/myapp/
ProxyPassReverse / http://127.0.0.1:8080/myapp/
</Location>
Fourth attempt
<Location "/myapp/">
ProxyPreserveHost On
ProxyPass /myapp/ http://127.0.0.1:8080/myapp/
ProxyPassReverse /myapp/ http://127.0.0.1:8080/myapp/
None of the configuration seem to work,
the url https://myapp.mydomain.com brings up the welcome page of the tomcat.
And what ever configuration i apply to apache, the only way to make it work is to manually add on the link the mountpoint of proxy, as following
http://myapp:mydomain.com/myapp/index.jsp
Any suggestion on how can i make this work?
Thanks in advance.
I don’t have enough cred to comment and ask for clarification, so I’ll edit my answer based on your feedback.
When using the VirtualHost, which I believe is your best option, you need a ServerName directive included as well. (Perhaps you omitted it here on purpose for some reason, but I'm showing it in the example below).
Also, I believe your route parameters for ProxyPass and ProxyPassReverse need to be in quotes unlike many other items in a VirtualHost. Make particular note of the trailing slash after myapp in the destination (second parameter). Since your desired URL would have index at the root path of your myapp.mydomain.com subdomain, make sure you're indicating that (as the first parameter, /). That should cause the URL https://myapp.mydomain.com to point to http://127.0.0.1:8080/myapp/ as you intend. (In your Example 2, you made your first parameter /myapp/ and, thus, you had to add this to your URL to access it, as you noted -- minus where you swapped a colon for a dot.)
(Disclaimer: I don't know much about Tomcat, but I am operating on the presumption that index.jsp should be treated like most other "index" files in that they'll be sought out and used if they exist and can, therefore, be omitted from the URL requested by the client).
I've also added the ProxyRequests below as I do not know if the default is "Off" or not, but unless you're using a forward proxy (versus the apparent reverse you want here) I think it's at least a potential security issue not to do so.
Minus any other directives you've not shown here, it seems this should do the trick:
<VirtualHost *:80>
ServerName myapp.mydomain.com
ProxyRequests off
ProxyPreserveHost On
ProxyPass "/" "http://127.0.0.1:8080/myapp/"
ProxyPassReverse "/" "http://127.0.0.1:8080/myapp/"
</VirtualHost>
Original reply was from mobile; I've cleaned it up and added an example and clearer explanation from desktop.

Tableau Reverse Proxy Issue

I want to make Tableau (which is on an internal network) accessible on the public network. One of the ways recommended by Tableau Support is a Reverse Proxy.
I have set up the required modules and have the reverse proxy functioning. The login page is available through these settings in httpd given below. However, once I log in and want to open Projects, Views etc. It routes to
http://actualsite.com/#/vieworproject
which should actually be http://actualsite.com/tableauaccess/#/vieworproject.
Here is the httpd configuration:
ProxyPass /tableauaccess/ http://tableauserverexample.com/
ProxyPassReverse /tableauaccess/ http://tableauserverexample.com/
<Location /tableauaccess/>
Order deny,allow
Allow from all
ProxyHTMLURLMap / /tableauaccess/
</Location>
This doesnt solve the main issue with #. I tried
ProxyPass /#/ http://tableauserverexample.com/#/
ProxyPassReverse /#/ http://tableauserverexample.com/#
But it doesnt help. Any suggestions?? Thanks!
We had this same issue recently. Your httpd.conf file is technically correct for mod_proxy, however the url you are attempting to use is not supported by Tableau. You cannot use:
http://actualsite.com/tableauaccess
But rather you must use the format:
http://tableauaccess.actualsite.com
We ended up setting up that sub-domain name and then using a VirtualHost block such as:
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ServerName actualsite.com
DocumentRoot "/path/path2/pathx"
</VirtualHost>
<VirtualHost *:80>
ServerName tableauaccess.actualsite.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://tableauaccess.actualsite.com/
ProxyPassReverse / http://tableauaccess.actualsite.com/
<IfModule mod_cache.c>
CacheDisable *
</IfModule>
RequestHeader set X-Forwarded-Proto "http" #or "https", depending on preference
</VirtualHost>
Be sure to double-check your Tableau server to update the URL format.
Sources:
https://community.tableau.com/thread/198095
https://community.tableau.com/thread/218678
(I don't have enough reputation points to post all of my sources, but thanks to Tableau community, shanemadden at ServerFault, and the Apache documentation.)
edit: forgot trailing slashes

double proxy statements for apache

As you can see I am trying to get both / and /BowlingFacelets/faces/ to point to the same place.
The problem is that the JSF pages will add /BowlingFacelets/faces/ when I sumbit the forms. I however don't want the end user to have to type such a long statement to start the app. Is there a way to do this?
Note that this will work if I manually add
score.megahooked.com/BowlingFacelets/faces to the URL
ProxyPass / http://megahooked.com:8080/
ProxyPassReverse / http://megahooked.com:8080/
This will not work correctly
score.megahooked.com/createEvent.xhtml
since when submitting the new URL will be
score.megahooked.com/BowlingFacelets/faces/updateEvent.xhtml which is not found.
<VirtualHost *:80>
ServerName score.megahooked.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://megahooked.com:8080/BowlingFacelets/faces/
ProxyPassReverse / http://megahooked.com:8080/BowlingFacelets/faces/
ProxyPass /BowlingFacelets/faces/ http://megahooked.com:8080/BowlingFacelets/faces/
ProxyPassReverse /BowlingFacelets/faces/ http://megahooked.com:8080/BowlingFacelets/faces/
</VirtualHost>
The solution could be the using of mod_proxy_html. It can parse HTML documents and rewrite URLs inside. Here for example I make the application "restfrontend" (mapped to "/restfrontend") accessible as root application (mapped to "/")
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLMeta On
ProxyHTMLLogVerbose On
ProxyHTMLURLMap ^/restfrontend()$ $1 [LR]
ProxyHTMLURLMap /restfrontend/ /
ProxyPassReverseCookiePath /restfrontend /
ProxyHTMLDoctype HTML
I would strongly dis-advice to do it. This module is very hard to configure. Configuration of two possible paths in the same time will be a nightmare.
Much better solution is to deploy the application as ROOT directly in the Tomcat and add some redirects for additional URLs shortcuts (RewriteRule with [R=301] option).

Apache ProxyPass for URLS inconsistently failing

This one's driving me nuts. I have an active and in-use Apache proxy server serving content up on EC2. It's working great, and has a variety of vhosts that are configured like this:
<VirtualHost *:80>
ServerName m.FOO.com
ServerAlias customer.FOO.com
ProxyPreserveHost On
ProxyPass / ajp://10.211.42.48:8009/
ProxyPassReverse / ajp://10.211.42.48:8009/
<Proxy ajp://10.211.42.48:8009/*>
Order allow,deny
Allow from all
</Proxy>
</VirtualHost>
These all work great, and I'm having no problems. Now what I'd like to do is move it so instead of a single vhost for each app, I want to have a sub-url on the main site that proxies back to the appserver. So instead of a customer having 'customer.FOO.com', they'll have 'FOO.com/customer/'
Great, sounds easy, right? Yeah, not so much. I edit the vhost entry for 'root' of the server (currently showing the landing page), and add the proxy entries to directories within that. That should do it,right? Yeah, it ain't:
<VirtualHost *:80>
ServerName web01.aws.FOO.com
DocumentRoot /var/www/html
ErrorLog logs/www.FOO.com-error_log
CustomLog logs/www.FOO.com-access_log common
<Location /a>
ProxyPass ajp://10.211.42.48:8009
ProxyPassReverse ajp://10.211.42.48:8009
</Location>
<Location /t>
ProxyPass http://adm01
ProxyPassReverse http://adm01
</Location>
<Proxy ajp://10.211.42.48:8009/*>
Order allow,deny
Allow from all
</Proxy>
</VirtualHost>
If i hit http://www.FOO.com/t/ - I get the internal webserver - it proxies forward correctly, and all is well. If I hit http://www.FOO.com/a/ I get a 404 error. The access log even shows a 404 error.
Note that the ProxyPass AJP entries are identical to what's in the other vhost entry. So why does it work on the root on the other vhost entry, and not as a subdir here on the main vhost?
Halp!
I ended up solving this with one particular hint I found out on a mailing list somewhere. The ProxyPassReverse directive is very touchy, and has one basic function. Anything it matches on the second argument (assuming using the ProxyPassReverse A B form) will be applied to the first argument. So it's critical to make sure the second argument is exactly the redirect that is coming from your application, or else the ProxyPassReverse directive will be ignored.
In my case, what I ended up doing was changing the Location entry to:
ProxyPass /a/ ajp://10.211.42.48:8009
ProxyPassReverse /a/ http://my.apphost.com/
And all started working just fine.

Apache proxy cookies works only with the first app

stuck on configuring apache as proxy for applications running on tomcat on different pc. Everything seems working on the first application - WebApp1. But on the left ProxyPassReverseCookiePath is not working. ProxyPassReverseCookiePath works only on the first application. When accesing other applications a jsessionid is added to the url.
What I missed and how to fix on WebApp2 and WebApp3? Thanks
httpd-vhosts.con:
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ProxyRequests off
ProxyPreserveHost on
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /WebApp1/ ajp://192.168.1.98:8009/WebApp1/
ProxyPassReverse /WebApp1/ ajp://192.168.1.98:8009/WebApp1/
ProxyPassReverse /WebApp1/ http://192.168.1.98:8080/WebApp1/
ProxyPassReverseCookiePath /WebApp1 /WebApp1/
ProxyPass /WebApp2/ ajp://192.168.1.98:8009/WebApp2/
ProxyPassReverse /WebApp2/ ajp://192.168.1.98:8009/WebApp2/
ProxyPassReverse /WebApp2/ http://192.168.1.98:8080/WebApp2/
ProxyPassReverseCookiePath /WebApp2 /WebApp2/
ProxyPass /WebApp3/ ajp://192.168.1.98:8009/WebApp3/
ProxyPassReverse /WebApp3/ ajp://192.168.1.98:8009/WebApp3/
ProxyPassReverse /WebApp3/ http://192.168.1.98:8080/WebApp3/
ProxyPassReverseCookiePath /WebApp3 /WebApp3/
</VirtualHost>
Solved it by changing to cookie path location dir:
ProxyPassReverseCookiePath /WebApp1/ http://192.168.1.98:8080/WebApp1/
One of the advantages of ajp is that it sends the original URL to the web application. So any transformations by ProxyPassReverse and ProxyPassReverseCookiePath are not necessary, so you can just leave those directives out.
Unrelated to that, ProxyPassReverseCookiePath simply replaces the path parameter in the cookies that come from the web application. As in your case, the path that the web application is accessed under is the same as the path under which it is made available by Apache, it is not necessary to replace anything in the cookie path.
I could imagine that the reason why your original code doesn’t work is because it replaces /WebApp1 by /WebApp1/, so you might end up with /WebApp1// in the cookie path, which might confuse browsers. (I am neither sure whether Apache does the transformation in this case nor whether it confuses the browsers.) I could imagine that the solution that you posted works because Apache ignored the directive because it contains an invalid path. (I am also not sure whether that’s how Apache behaves in this case.)
I had the same issue and following configuration fixed my problem.
step-1: Added ProxyPreserveHost On property on vhost.
step-2: configured ProxyPassReverseCookiePath for all the application like below
ProxyPassReverseCookiePath / /WebApp1
ProxyPassReverseCookiePath / /WebApp2
ProxyPassReverseCookiePath / /WebApp3
Hope this will help!