ProxyPassReverse does not keep correct protocol while redirecting - apache

I have set up a Virtuoso server that serves Linked Data using content negotiation. The server is served through a reverse proxy Apache server and may be queried using http or https.
http://public.server.org/myapp --> http://private.local.domain:1234/
https://public.server.org/myapp --> http://private.local.domain:1234/
The Virtuoso server then performs content negotiation and redirects to /describe?...
I have no problem when accessing the public server through http. The redirection takes place and content is retrieved.
However, when I access the public server though https, the redirection sends me to http://public.server.org/describe?... (that is HTTP, not HTTPS).
I'm expecting to be redirected to https://public.server.org/describe?... (with the same protocol as the original query).
My configuration is:
<VirtualHost xxx.yyy.zzz.ttt:80>
ServerName public.server.org
ProxyPass /myapp http://localhost:8890/myapp
ProxyPassReverse /myapp http://localhost:8890/myapp
ProxyRequests Off
<Location /describe>
ProxyPass http://localhost:8890/describe
ProxyPassReverse /describe
</Location>
</VirtualHost>
<VirtualHost xxx.yyy.zzz.ttt:443>
ServerName public.server.org
ProxyPass /myapp http://localhost:8890/myapp
ProxyPassReverse /myapp http://localhost:8890/myapp
ProxyRequests Off
<Location /describe>
ProxyPass http://localhost:8890/describe
ProxyPassReverse /describe
</Location>
</VirtualHost>
Is it possible for apache to correctly reverse the proxy in order to maintain the original query protocol while redirecting?

After debugging with dumpio and Apache error logs, I think I found the problem.
What happened?
First, my configuration was incorrect. At another place I did not transcribe here, I had a ProxyPreserveHost On directive that was active. Hence, the configuration worked but for wrong reasons.
Apache was keeping the Host and Virtuoso used this host. Hence, when sending a redirect to /describe..., Virtuoso was redirecting to http://public.server.org/describe... instead of my expected http://localhost:8890/describe...
Hence, the redirection was not captured by the ProxyPassReverse directives and passed unchanged to the client (and it worked). The problem being that the redirection was always done through http, regardless of the original query scheme.
Solution
I decided to drop the ProxyPreserveHost On directive and rely on a correct ProxyPassReverse directive.
For an unknown reason, I could not figure out the correct setting inside the Location, hence I used the settings:
<VirtualHost xxx.yyy.zzz.ttt:443>
ServerName public.server.org
ProxyPass /myapp http://localhost:8890/myapp
ProxyPassReverse /myapp http://localhost:8890/myapp
ProxyRequests Off
ProxyPreserveHost Off # To avoid problems if it is set On elsewhere.
ProxyPass /describe http://localhost:8890/describe
ProxyPassReverse /describe http://localhost:8890/describe
</VirtualHost>
Note: I only changed the https settings as the http ones were functioning somehow (hence the http virtualhost still uses ProxyPreserveHost On and no ProxyPassReverse

Related

Apache ProxyPass adding Port only on base URL

This is getting frustrating to say the least haha.
I have setup a proxypass and proxypassreverse in apache under virtual host 443 to proxy to nginx running in a container on port 8443.
This is all I have set up to do this
CustomLog /srv/apps/ktech-connect/log/apache/custom.log combined
ErrorLog /srv/apps/ktech-connect/log/apache/errors.log
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass / https://127.0.0.1:8443/
ProxyPassReverse / https://127.0.0.1:8443/
When I hit any url such as example.com/page it works like it should
But when I go to example.com or even example.com/ it will show a redirect from apache to example.com:8443 in the url.
I have tried adding ProxyPreserveHost but it does nothing, and a whole host of other options. I just don't understand where the redirect is coming from and the fact that it only happens when hitting the base url.
Any thoughts?
Thanks to ServerFault, It was an old rewrite directive still in my browser cache lol. Cleared it and now it works as expected.

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.

apache 2 proxypassreverse appends virtualhost port

I have been trying to setup a reverse proxy using apache 2 mod_proxy and the proxypass & proxypassreverse directives.
I am installing WSO2 Identity Server and wish to access that app using a url such as the following .
hxxp://myserver.domain.com/wso2/
The myserver.domain.com is accessible on the internet
Internally on my network I have set up a virtualhost running in my apache2 configuration with the following parameters:
For various reasons, port 80 is unavailable and the virtualhost must stay as :8080.
Finally, here is my virtual host configuration
<VirtualHost *:8080>
<Location /wso2/>
ProxyPass hxxps://internal.wso2.node:9443/
ProxyPassReverse hxxs://internal.wso2.node:9443/
</Location>
ProxyVia On
ProxyPreserveHost Off
ProxyAddHeaders Off
ProxyRequests Off
SSLProxyEngine On
SSLProxyCheckPeerCN Off
</VirtualHost>
The issue:
I can use my web browser ( Firefox/Chrome) to request the http://myserver.domain.com/wso2/ resource. In my log files I see that the request does hit the apache server and the virtualhost catches the /wso2/ location.
It passes through the proxy and lands on the internal.wso2.node server. however, the product WSO2 IS preforms several redirects which, in the log files I see it requesting the resource with the port appended.
Here is the request flow
hxxp://myserver.domain.com/wso2/ -> hxxps://internal.wso2.node:9443/
REDIRECT x3
hxxps://internal.wso2.node:8080/carbon ->
hxxps://internal.wso2.node:8080/carbon/admin/login.jsp
Back to my web browser
hxxp://myserver.domain.com:8080/wso2/carbon/admin/login.jsp
For some reason the apache response back appends its virtual host to the url I am requesting.
If I remove the port:8080 and request again the full url it will access the resource fine. However any attempt to access using only http://myserver.domain.com/wso2/ will result in redirects and the port appended.
As per covener's suggestion the culprit in this case proved to be the following directives:
UseCanonicalName Off
UseCanonicalPhysicalPort Off
Additionally, the web app I am trying to access makes use of sessions and cookies, therefore we must also proxy those, see the added directives under the ProxyPass & ProxyPassReverse.
Therefore the updated virtualhost configuration file should now look like this
<VirtualHost *:8080>
ServerName: myServer.domain.com
UseCanonicalName Off
UseCanonicalPhysicalPort Off
<Location /wso2/>
ProxyPass hxxps://internal.wso2.node:9443/
ProxyPassReverse hxxs://internal.wso2.node:9443/
ProxyPassReverseCookiePath / /wso2/
ProxyPassReverseCookieDomain internal.wso2.node myserver.domain.com
</Location>
ProxyVia On
ProxyPreserveHost Off
ProxyAddHeaders Off
ProxyRequests Off
SSLProxyEngine On
SSLProxyCheckPeerCN Off
</VirtualHost>

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!