Redirection / Proxy of REST API in Apache2 - apache

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.

Related

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.

How to redirect URL with port to URL with context?

I have a server with apache(2.4.18) installed
I have installed multiple applications on the server like Grafana, Sonarqube, and MySQL enterprise monitor(MEM)
Each application has URL like this
http://test.com:9000
http://test.com:3000
I am looking for a solution which allows me to redirect this URL with the port to URL with context, something like that
http://test.com:9000 --> http://test.com/sonar
http://test.com:3000 --> http://test.com/grafana
I have added some code in /etc/apache2/sites-enabled/000-default.conf file
Redirect permanent /sonar http://test.com:9000
Redirect permanent /grafana http://test.com:3000
but when I enter http://test.com/sonar in the web browser it redirects to http://test.com:9000 URL only
I want http://test.com/sonar this URL to persists on Web browser
If you use Redirect permanent, server will send 301 response back to client (along with new Location). That will result in browser issuing a new request, this time to new Location, and also new location will be shown in browser address bar.
What you need is Reverse Proxy. For this you need to make sure that mod_proxy is enabled in your apache configuration (usually it is enabled by default), and put something like this in your .conf file:
ProxyPreserveHost On
ProxyPass /sonar http://127.0.0.1:9000
ProxyPassReverse /sonar http://127.0.0.1:9000
ProxyPass /grafana http://127.0.0.1:3000
ProxyPassReverse /grafana http://127.0.0.1:3000
You will probably also have to make your applications aware that they are running under non-root context (by making some configuration changes):
http://docs.grafana.org/installation/behind_proxy/
https://docs.sonarqube.org/latest/setup/install-server/
You need to proxy requests and not redirect them.
Use a ProxyPass directive as mentioned in the official apache proxy documentation
For example add this location block inside your configuration:
<Location "/sonar">
ProxyPass "http://test.com:9000"
</Location>

Apache Reverse Proxy: (Keeping Existing route alive)

I have an app running on localhost:3000. I also have another app that is configured to run on virtualhost local.testserver.com
I want to create an apache reverse proxy that will route all request from local.testserver.com/finance to my app that runs at localhost:3000.
At the same time, I want to be able to access my app when I go to localhost:3000.
Below is the configuration I am using currently. This works for routing request from local.testserver.com/finance to my localhost:3000 app. But whenever I visit localhost:3000 directly it redirects me back to local.testserver.com
<Location /finance >
ProxyPass http://localhost:3000
ProxyPassReverse http://localhost:3000
</Location>
You will need to add the path on the ProxyPassReverse setting to "/finance" so it knows where to reverse requests back.
You may not need the <Location /finance>...</Location> part
ProxyPass "/finance" http://localhost:3000
ProxyPassReverse "/finance" "http://localhost:3000"
Please refer to the documentation to better understand how
ProxyPassReverse works here:
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse

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.