Stuck with apache,mod-ajp weird redirection - apache

hi all i have a redirection problem with mod ajp, that it always adds the application name before the desired page, for example:
if i requested the page:
http://myapp.com/mypage
it is converted to
http://myapp.com/myapp/mypage, and i get a 404 error
i don't know why such behaviour occurs, this is the configuration:
<Proxy *> AddDefaultCharset Off Order deny,allow Allow from all </Proxy>
ProxyPass / ajp://127.0.0.1:8009/myapp/
ProxyPassReverse /
ajp://127.0.0.1:8009/myapp/
ProxyPassReverseCookiePath /myapp/
this strange redirection occurs exaclty when an inside application redirection occurs meaning after registration the user is redirected(application side) to the login page using response.sendRedirect , any ideas ?

The ProxyPassReverse directive is possibly wrong. I guess it should be
ProxyPassReverse / http://myapp.com
See The Mystery of ProxyPassReverse.

You can resolve problems like this with this approach:
Install LiveHTTPHeaders and enable it
Access the application directly
Access the application via your reverse proxy
Compare the HTTP traffic of the previous cases
Most likely your application redirects user using relative URL. However your ProxyPassReverse only rewrites absolute versions. The relative version gets redirected with the page load according to your ProxyPass rule, causing the doubling of the path.

Related

Apache ProxyPassReverse fallback when host is down

I have been unable to find any documentation to conclusively confirm or deny this apparent mod_proxy behaviour.
We have a web reverse proxy with multiple ProxyPassReverse definitions, similar to this:
ProxyPass /foo http://fooserver/
ProxyPassReverse /foo http://fooserver/
ProxyPass / http://barserver/
ProxyPassReverse / http://barserver/
As expected, requests for URLs under /foo go to fooserver, and all other requests get sent to barserver.
Recently, fooserver was shut down for other reasons. Users noticed that - sometimes - requests for /foo/xxx were incorrectly being routed to barserver which responded with a 404 (we know it was barserver responding because it runs a different webserver software).
My question is this - is it deliberate that ProxyPassReverse will fall back to a lower-priority route if the destination server is down, and if so, under what conditions does this fallback happen? I know that you can use mod_balancer if you want it to happen. I'm more interested in why it is happening this time when I had not expected it to, and any pointers to relevant documentation.

Redirection / Proxy of REST API in Apache2

I have REST API webservice running on server on address 127.0.0.1:8090 and Apache2 server running on 192.168.10.220, where I have frontend for my app.
In my website config I added lines:
RewriteEngine on
RewriteRule ^/api/ http://127.0.0.1:8090/
And when I'm openning address http://192.168.10.220/api in webbrowser I got redirection to 127.0.0.1:8090 and site is not found.
My question is how to redirect it that I will be able to open link for example http://192.168.10.220/api/login and It will return me result of http://127.0.0.1:8090/login, but 127.0.0.1:8090 address will be not seen in browser url.
Update 1:
I found solution, instead RewriteEngine, I should use this:
ProxyPass /api http://127.0.0.1:8090/api
ProxyPassReverse /api http://127.0.0.1:8090/api
And now I can use api at address http://192.168.10.220/api
But I have problem with second proxy:
ProxyPass /raporty http://192.168.10.200:8080/ekoncept_raporty
ProxyPassReverse /raporty http://192.168.10.200:8080/ekoncept_raporty
This time it's not api, but web application (reporting system, not mine). I can login and work, but some features I can't see or when I click button it redirects me to login page. I think it's something with coockies or etc.
What parameters should I use in my Proxy config to fix it??
Final configuration:
ProxyPass /api http://127.0.0.1:8090/api
ProxyPassReverse /api http://127.0.0.1:8090/api
ProxyPass /raporty http://192.168.10.200:8080/ekoncept_raporty
ProxyPassReverse /raporty http://192.168.10.200:8080/ekoncept_raporty
ProxyPassReverseCookiePath /ekoncept_raporty /raporty
It was cookie problem as I thought. Adding this fixed problem:
ProxyPassReverseCookiePath /ekoncept_raporty /raporty
With API there isn't a problem like this, because it doesn't use cookies.

Apache ProxyPass error

I have to redirect all apache requests on 80 to tomcat on 8080, except one path.
So, if a receive http://example.com/anything --> tomcat:8080.
But, if the url is that: http://example.com/site --> apache should serve and no redirect is needed.
Currently, there is a folder named site inside /var/www/html/.
This is my current configuration file:
site.conf (this file contains only the following and is inside the conf.d folder)
<LocationMatch "/*">
Allow from all
ProxyPass /site !
ProxyPass http://127.0.0.1:8080
ProxyPassReverse http://127.0.0.1:8080
</LocationMatch>
I think this is a simple thing to accomplish with apache, but I have tried everything that I could find and I am still getting the error:
ProxyPass|ProxyPassMatch can not have a path when defined in a location.
The thing is that the root website is running on tomcat, but the other runs on apache (the one that I called site in this question).
If anyone can help, I appreciate.
Thanks!
Update 1 - 09/06/2017
I get it to work if I remove the LocationMatch and put the ProxyPass
direct in the .conf file:
ProxyPass /site !
ProxyPassReverse /site !
ProxyPass / http://127.0.0.1:8080
ProxyPassReverse / http://127.0.0.1:8080
But, I would like to know, why is that? What is the impact of putting this directives outside the LocationMatch tag? And, most important, why I cannot accomplish the same result using the LocationMatch?
I think the error is pretty clear:
ProxyPass|ProxyPassMatch can not have a path when defined in a location.
According to the documentation, inside a context block like Location or LocationBlock the ProxyPass directive does not accept a path:
When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same will occur inside a <LocationMatch> section; however, ProxyPass does not interpret the regexp as such, so it is necessary to use ProxyPassMatch in this situation instead.
You're getting the error because you were trying to use a path:
ProxyPass /site !
You could try to resolve this in theory by using multiple <Location> sections, like this:
<Location />
ProxyPass http://backend/
</Location>
<Location /site>
ProxyPass !
</Location>
The ordering of these sections is important.
Your solution of using ProxyPass directives outside of a LocationMatch block is probably the simplest solution.
As a side note, your LocationMatch directive is incorrect. The argument to LocationMatch is a regular expression, and /* would only match URLs consisting only of / characters. That is, it would match / or // or /////////, etc. I think you really meant /.*. The * in a regular expression means "the previous character, zero or more times".

Apache mod_proxy not forwarding all requests

I have a Bottle/Python app running on localhost:3000 that I am using Apache mod_proxy to forward requests to. Its working 99% of the time, except when I try and go to a url like:
http://m2t.openseedbox.com/api/upload/http%3A%2F%2Ftorrents.thepiratebay.se%2F6753175%2FPioneer_One_S01E04_720p_x264-VODO.6753175.TPB.torrent
(basically, there is a URL that is a part of the URL but its been run through encodeURIComponent). In this case, Apache is returning its own 404 page and not passing the url through to the backend server.
My apache config is as follows:
<VirtualHost *:80>
ServerName m2t.openseedbox.com
ProxyPass / http://127.0.0.1:3000/ retry=0
ProxyPassReverse / http://127.0.0.1:3000/
ProxyPreserveHost On
</VirtualHost>
Why is Apache not proxying this URL? (you can visit it yourself to see the Apache 404 page where a Bottle page should be)
EDIT: I've worked around it by passing the URL as a GET parameter. I still dont know why Apache isnt working as advertised though...
By default, Apache doesn't pass through urls with %2F in them. See the link below for more info.
%2F in URL breaks and does not reference to the .php file required

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.