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

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]

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 reverse proxy for Kibana

I'm currently trying to set up an Apache server to redirect e.g localhost/kibana to Kibana at localhost:5601.
I've tried adding this to apache2.conf:
ProxyPass /kibana http://localhost:5601
ProxyPassReverse /kibana http://localhost:5601
However it gets stuck on the Kibana "loading components" page and never actually loads fully. It works when changed to this:
ProxyPass /kibana/ http://localhost:5601/
ProxyPassReverse /kibana/ http://localhost:5601/
Obviously it's not ideal to force the user to enter the extra / at the end though, so I've tried rewriting the URL in .htaccess:
RewriteEngine On
RewriteRule http://localhost/kibana$ http://localhost/kibana/
But the rewrite doesn't seem to work. I've set AllowOverride to all and enabled the rewrite module, as well as played around with various different rewrite/proxy rules but haven't had any luck so far.
I have finished my apache configuration file for kibana with elasticsearch. It may be useful for you:
/etc/httpd/conf.d/kibana.conf:
ProxyRequests On
ProxyPass /app/kibana http://127.0.0.1:5601/app/kibana
ProxyPassReverse /app/kibana http://127.0.0.1:5601/app/kibana
ProxyPass /elasticsearch http://127.0.0.1:9200/
ProxyPassReverse /elasticsearch http://127.0.0.1:9200/
Alias /bundles/ /opt/kibana/optimize/bundles/
<Directory /opt/kibana>
Require all granted
</Directory>
This way it does not require any additional "/" and it works with default kibana configuration file.

How to redirect to another domain But Not Show The URL redirection with .htaccess?

I am not sure if .htaccess can handling this, I do search a lot's of related topics, but find no solution.
What I need is:
when my users visit my site: www.mysite.com
actually they got content from www.otherplace.com/folder1/folder2/folder3/page.html
I would like user's browser address shows: www.mysite.com or www.mysite.com/page.html also fine for me, but not show's anything about the site: www.otherplace.com....
page.html is just single page, tiddlywiki, :)
thank you. :)
If you are using apache this can be done with proxy.
Open /etc/apache2/mods-available/proxy.conf and add your's definition
<IfModule mod_proxy.c>
ProxyRequests Off
<Proxy *>
AddDefaultCharset off
Order Allow,Deny
Allow from all
</Proxy>
ProxyPass / http://www.otherplace.com/folder1/folder2/folder3/page.html
ProxyPassReverse / http://www.otherplace.com/folder1/folder2/folder3/page.html
</IfModule>
I use similar configuration to host multiple services that listen on different ports (e.g. Jenkins, codebrag e.t.c) with on http each with their own directory e.g
ProxyPass /jenkins http://localhost:8080/jenkins
ProxyPassReverse /jenkins http://localhost:8080/jenkins
and the url is http://my.domain.com/jenkins/ instead of http://my.domain.com:8080/jenkins
Remember to restart apache sudo service apache2 restart or another equivalent
Rewrite is another option but IMO proxy is easier to set up although it's not so powerful.

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 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!