Do I need to use ProxyPassReverse if I'm using mod rewrite? - apache

I am using mod rewrite to mask the context root of my application. For example,
RewriteRule ^/directory/(.*) balancer://appcluster/directory/$1 [P]
The appcluster looks like this:
<Proxy balancer://appcluster>
BalancerMember http://localhost:8080/App route=app_01 keepalive=On loadfactor=1 ttl=300 min=3 smax=5 max=15
ProxySet lbmethod=byrequests stickysession=JSESSIONID|jsessionid timeout=120 nofailover=On
</Proxy>
Do I need to use ProxyPassReverse at all? I used to use it because my old webserver code looked like this:
ProxyPass /App balancer://appcluster lbmethod=byrequests stickysession=JSESSIONID|jsessionid timeout=120 nofailover=On
ProxyPassReverse /App http://localhost:9013/App

The ProxyPassReverse is used to change the headers sent by the app (appcluster) to Apache, before Apache sends it the browser. For example, if the app sits at http://localhost:9013/, and it tries to redirect the browser to, say, /new_location/, then it will respond with a redirect and location header of http://localhost:9013/new_location/, and Apache will take this and send it off to the browser. Problem is, the browser (assuming it's somewhere else) then tries to send a request to http://localhost:9013/new_location/, and gets an error.
What ProxyPassReverse does is intercepts those headers, and rewrites them so that they match what the Apache server that's doing the proxying looks like. So if my apache server is hosting http://myhost.com/ and I have a ProxyPass that points / to http://localhost:9013/App, if the application sitting at localhost:9013 returns a redirect to http://localhost:9013/App/new_location/, I'll need to use ProxyPassReverse so that it gets rewritten to http://myhost.com/new_location/ by Apache before sending the request back to the browser.
If you aren't issuing redirects, it's not going to be an issue, but it doesn't hurt to have it there in case a 301/302 redirect is returned. As far as mod_rewrite, the RewriteRule applies to the request going to the App, and not the response coming from the App. So they are mutually exclusive events.

Related

How to put Qbittorrent webui port behind a https Apache2 server?

So basically, i have a apache2 server with https where i run some application
I am tring to using mod_proxy to proxy all traffic to url example.com/qb to [::1]:qb-webui-port.
So in /etc/apache2/mods-enabled/proxy.conf, i wrote:
ProxyRequests Off
<proxy *>
AddDefaultCharset off
Order Allow,Deny
Allow from all
</proxy>
ProxyPass /transmission http://[::1]:9091/transmission
ProxyPassReverse /transmission http://[::1]:9091/transmission
ProxyVia On
ProxyPass /qb http://[::1]:8112
ProxyPassReverse /qb http://[::1]:8112
The above is my similiar configuration for Transmission, i intended to do the same trick to Qbittorrent.
But it only returned plain html from example.com/qb.
In the firefox console i noticed that there were some request towards example.com/css, example.com/script etc.
This make me confused.
Can anyone provide some insights on this one?
Thx.
You missed the trailing slash on your addresses.
Here's my config file. I added a RewriteRule in case I enter the URL without the trailing slash. With these configs I haven't needed to modify anything else to get qb reverse proxy working.
I use the "/torrent/ subdir to access my qbittorrent webUI and it's listening on the 8080 port, so you should modify this in order to get your installation fully functional.
# Para qbittorrent
RewriteEngine on
RewriteRule ^/torrent$ "/torrent/$1" [R]
ProxyPass /torrent/ http://127.0.0.1:8080/
ProxyPassReverse /torrent/ http://127.0.0.1:8080/

Apache configuration proxy pass

I want to configure a server to listen to localhost adress with proxy pass.
Fist, I added a proxy pass configuration like that:
ProxyPass /test http://localhost:5959/ nocanon
ProxyPassReverse /test http://localhost:5959/
ProxyPassReverse /test http://domain_name.net/
The index is working fine, but the problem is when i click on some button to be redirected to another page. I expected the redirection would be like : http://domaine_name.net/test/anotherpage.php but it didn't work.
I tried another configuration but it didn't work
ProxyPass /test/ http://localhost:5959/test/
ProxyPassReverse /test/ http://localhost:5959/test/
ProxyPassReverse /test/ http://domain_name.net/test/
How can I resolve this issue ?
Do not put 2 ProxyPassReverse directives. Only one. And it should match the ProxyPass destination. So your first ProxyPassReverse only is required.
ProxyPass /test http://localhost:5959/ nocanon
ProxyPassReverse /test http://localhost:5959/
From the documentation for ProxyPassReverse, (https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypassreverse):
This directive lets Apache httpd adjust the URL in the Location,
Content-Location and URI headers on HTTP redirect responses. [...]
You said in your question:
I expected the redirection would be like :
http://domaine_name.net/test/anotherpage.php but it didn't work.
this is normal. A proxy hides the final destination server to the client. If you want to redirect the client, do not use a proxy. Use mod_rewrite (RewriteRule and others).

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 :-)

Apache load-balancer: direct to specific application based on URL

I have multiple applications deployed in Tomcat's webapps folder (app1.0, app1.1, app1.2 etc.). When I hit www.example.com:8080/app1.0, the corresponding application appears.
But how to do it on the load-balancing server? For instance, I have a website on which I can click a button (app1.0, app1.1, app1.2 etc.) and an URL pops up like: www.lb.com/app1.0/.../... How to direct to the app based on application version in URL? Use RewriteCond and regex and pass it to ProxyPass? I don't really how to script it, anyone could help? :)
Edit: This is what I done for the 2 apps for 1 Tomcat and 2 apps for 2 Tomcat, but I got 404 sometimes because the Tomcat that has another version has been chosen by the load-balancer.
<VirtualHost *:80>
#Add a http header to explicitly identify the node and be sticky
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
#Declare the http server pool
<Proxy "balancer://plf">
BalancerMember "http://worker1.com:8080" route=worker1
BalancerMember "http://worker2.com:8080" route=worker2
ProxySet stickysession=ROUTEID
ProxySet lbmethod=bybusyness
</Proxy>
#Common options
ProxyRequests Off
ProxyPreserveHost On
#Declare the redirection for the http requests
ProxyPassMatch "/app(.*)" "balancer://plf/app$1"
ProxyPassReverse "/app(.*)" "balancer://plf/app$1"
This is how I did it:
1) define a balancer proxy:
<Proxy balancer://portalcluster stickysession=JSESSIONID>
BalancerMember ajp://TOMCATSERVER1:8009 route=TOMCARSERVER1-0
BalancerMember ajp://TOMCATSERVER2:8009 route=TOMCATSERVER2-100
</Proxy>
2) proxy to it in your VirtualHost:
Listen 443
<Virtualhost *:443>
ServerName example.com
Alias /static /var/www/portalstatic
ProxyPass /static !
ProxyPass / balancer://portalcluster/
ProxyPassReverse / balancer://portalcluster/
</Virtualhost>
NB I removed a lot of configuration from these, that are not related to the question (logs, deny clauses, certificate directives, ...). This is just to illustrate the way I did the proxy.
NB2 I did leave the /static trick since this is usually something you will want to do. Static files must stay on the HTTP, and not send them from Tomcat all the time.

Apache reverse proxy: how to redirect relative URLs in external site back to itself?

I need to bypass cross-site scripting restrictions in order to show users a map when they click a link from an external site which I have loaded inside an iframe (external.com/onlyforme). I learned that the easiest way to do this is to set up a reverse proxy so that Apache would retrieve external.com/onlyforme when I access local.com/external, and make it so that it appears to be coming from my domain.
This mostly works, but when external.com/onlyforme/index.html tries to access external.com/onlyforme/site_media/script.js, this gets redirected to local.com/site_media/script.js, which is not what I want. Instead, I would like this to be redirected to the correct URL inside external.com/onlyforme, so that the external site works as expected.
How can I do that?
I have this in my httpd.conf, outside any other config statements:
ProxyRequests Off
ProxyPass /external/ http://www.external.com/onlyforme
ProxyPassReverse /external/ http://www.external.com/onlyforme
I am running Apache 2.2.
You need to add a couple of ProxyHTMLURLMap directives to the above, to inspect and rewrite any hard coded URL's in the returned HTML e.g.
ProxyRequests Off
ProxyPass /external/ http://www.external.com/onlyforme
ProxyHTMLURLMap http://www.external.com/onlyforme /external
<Location /external/>
ProxyPassReverse http://www.external.com/onlyforme
SetOutputFilter proxy-html
ProxyHTMLURLMap / /external/
ProxyHTMLURLMap /site_media /external/site_media/
</Location>
See also: http://wiki.uniformserver.com/index.php/Reverse_Proxy_Server:_mod_proxy_html
arober11's answer greatly helped solving my similar issue. I tried to narrow it down to the shortest set of rules possible, and there is my own configuration to have an Etherpad running at https://my-domain-name.wtf/pad :
<Location /pad>
ProxyPass http://localhost:9001 retry=0
# retry=0 => avoid 503's when restarting etherpad-lite
ProxyPassReverse http://localhost:9001
SetOutputFilter proxy-html
ProxyHTMLURLMap http://localhost:9001
</Location>
RewriteRule ^/pad$ /pad/ [R]