ProxyHTMLURLMap not rewriting URLs the right way - apache

I have a Web-IRC-Client (The Lounge) running at http://www.example.com:3000/ (no HTTPS) and visiting the link works fine. When I specify the port I can use the Web-Client without any problems. Now, I don't want to type the port every time and that's why I am trying to setup a reverse proxy using Apache2's configuration file. The problem is that the client is loading the assets (CSS, JS, images) from the wrong location. See below for more info. I think ProxyHTMLURLMap is the right way of fixing it, but cannot get it to work. I should also note, that I am redirecting all non-www-http traffic to the www-https version.
<VirtualHost *:443>
[...]
SSLProxyEngine on
ProxyPass /irc http://www.example.com:3000/
ProxyPassReverse /irc http://www.example.com:3000/
ProxyHTMLURLMap http://www.example.com:3000/ /irc
</VirtualHost>
When I visit https://www.example.com/irc I just get the text of the website with my javascript, css, etc. Checking the source code reveals, that it is trying to load the assets from:
https://www.example.com/css/bootstrap.css
Which is wrong. It should, instead, be loading from:
https://www.example.com/irc/css/bootstrap.css
Any advice would be greatly appreciated!
EDIT 1: Some more info: Browsing to the https proxy with a slash at the end (https://www.example.com/irc/) kind of works. The images and CSS get loaded, but the client itself doesn't respond and shows "This is taking longer than it should, there might be connectivity issues." even though everything is up.
EDIT 2: Another user suggested adding ProxyHTMLExtended On, but it didn't help either.

Even though this question is very old, I want to leave this here:
https://serverfault.com/a/685326
Note:
If it's still not working, you might add to your config:
ProxyHTMLEnable On

Related

How to set up a seamless proxy in Apache to get around my ISP's firewall?

I'm really hoping someone can help me out with this because I've been at it for several days and I think I'm going crazy!
I'm trying to do what to me sounds like a stupidly simple thing. I want to set up a proxy server using Apache on a dedicated machine that I rent so that I can get around my ISPs nonsense firewall. I am aware that I could use a VPN, I don't want to do that for reasons that should hopefully become clear after I explain the details of what I want.
First of all, I don't want the proxy server to be used for every request. Only for the sites that are blocked by my ISP.
Suppose I try to access blockedsite.com/path/to/resource and it fails. I then simply want to change the URL in the address bar to proxy.myserver.com/proxy/blockedsite.com/path/to/resource and have Apache handle everything to provide me with a seamless experience. That means,
ProxyPassReverse should modify the response headers to use to the proxy server.
All URLs in the response body should be modified to use the proxy
Here's what I have so far:
<VirtualHost *:80>
ServerName proxy.myserver.com
ProxyRequests off
ProxyPass /proxy/ http://
ProxyPassReverse /proxy/ http://
ProxyPassReverse /proxy/ https://
ProxyHTMLURLMap http:// /proxy/
ProxyHTMLURLMap https:// /proxy/
<Location /proxy/>
ProxyPassReverse /
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|</title>|</title><meta name='referrer' content='no-referrer' />|ni"
ProxyHTMLEnable On
#ProxyHTMLURLMap / /app1/
RequestHeader unset Accept-Encoding
Order allow,deny
Allow from all
</Location>
</VirtualHost>
This setup works beautifully for URLs that don't try to redirect me elsewhere. But if for example I try to access proxy.myserver.com/proxy/facebook.com I am still being redirected on the client side to https://www.facebook.com instead of https://proxy.myserver.com/proxy/www.facebook.com as I would like. The extra weird thing is that when I set up my own test site which does nothing except redirect me to an HTTPS address, the ProxyPassReverse rule for HTTPS does actually seem to work... but not when I try to access sites like Facebook or Google.
I see no reason to ramble on about my issues, what I'm looking for is astoundingly simple: a transparent, seamless experience! Aside from sticking proxy.myserver.com/proxy/ in front of the URL in the address bar, I shouldn't have to do anything else for it to work. Yet that is not the case and despite over a week of searching, I have found nothing online to help me with this. It's as if I'm the only person in the universe to want to create a simple proxy with Apache that actually works as a firewall-get-arounder.
Please can someone lend me a hand here?! Even just to tell me I'm going about this all wrong and should give up and install Squid or something??
Your last paragraph contains the right answer. You should indeed just "install Squid or something". In particular, I'd recommend Apache Traffic Server - http://trafficserver.apache.org/ - this is exactly what it's made for.
While Apache httpd can do proxying, it's not it's primary function, and so there are always things that will end up being frustrating with it. We could get your above scenario working, but it's really not the right tool for the job.

How to make yii2 module load at root level

I'm more of a frontend guy (CSS, javascript) trying to expand my knowledge about backend (apache, proxies) (so try to be gentle) and I'm asking after serveral hours of documentation, trying different approaches but so far nothing worked. I'm aware that I might be oblivious to concepts that go without saying for someone knowing their way around backend.
I have this Yii2 application, with a module, working fine. I would like this module to be available at the root level of another domain, on the same machine.
From everything I've read, the following code, placed in vhosts of my apache, should work:
<VirtualHost *:80>
ServerName buletin
ProxyPass / http://bdc/ik2/frontend/web/buletin/default/
ProxyPassReverse / http://bdc/ik2/frontend/web/buletin/default/
</VirtualHost>
I'm expecting to see the default action of my module when I go to http://buletin.
What am I missing?
Ok, in case someone else has the same problem, just double check all of your app's redirects and make sure everything works inside your module. If it doesn't, either add it as exception to the ProxyPass i.e.:
ProxyPass /ik2/frontend/web/themes/ http://bdc/ik2/frontend/web/themes/
ProxyPass /ik2/frontend/web/img/ http://bdc/ik2/frontend/web/img/
ProxyPass /ik2/frontend/web/assets/ http://bdc/ik2/frontend/web/assets/
#(all exceptions need to be placed above general ProxyPass and ProxyPassReverse)
or make it available inside your module.
In my case, I wasn't logged in the "new" website and it was redirecting me to /site/login, which did not exist (no buletin/default/site/login). Once I handled it and I added the exceptions for the assets and images to the ProxyPass, it's all working smoothly.

Apache Reverse Proxy Sending Browser to Backend Directly Instead

(UPDATE at the bottom for the main question, below may be superfluous details)
I'm having an interesting problem with Apache not reverse proxying as expected.
Basically, what's happening is when I click a link on my website that goes to the relative path /app1, I am expecting it the URL to be external.company.ca/app1 with content coming from internal.company.ca/some_app. Instead, the browser is going directly to internal.company.ca/some_app.
No 302 or anything, just straight there. This is odd to me, since internal.company.ca is not mentioned anywhere in the configuration except for the reverse proxy config, so I don't know how the browser is learning of the domain at all.
Here is a Fiddler capture from the client (browser) point of view showing the behaviour right after I click the link that goes to /app1 (you'll have to trust me that the green names are external.company.ca and the black names are internal.company.com and the path is /some_app/blahblah):
Everything happening after this point is loading the page with internal.company.com. This won't work at all in production, of course.
The following is a (truncated) version of our Apache configuration files for consideration:
<VirtualHost *:80>
# rewrite rules to 443
</VirtualHost>
<VirtualHost *:443>
ServerName external.company.ca
ServerAlias external.company.com
# Logging rules.........
SSLEngine on
SSLProxyEngine on
SSLProxyVerify none
# Most of this is off for testing purposes, adding in case it matters
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
# more SSL stuff.... Now on to the interesting part
ProxyPreserveHost On
ProxyPass /app1 https://internal.company.com/some_app
ProxyPassReverse /app1 https://internal.company.com/some_app
</VirtualHost>
At one point, I thought that possibly the cookies were throwing things off since they were under different domains (.ca in front, .com in back), but I believe if the reverse proxying was working correctly, the browser would be none the wiser. Anyone see anything wrong with the above?
UPDATE
I found the culprit:
<script type="text/javascript">window.location.assign('https://internal.company.com/app1/login?redirectUrl=' + encodeURIComponent(window.location.pathname + window.location.hash));</script>
The problem is, how do I rewrite this absolute URL using Apache? I know mod_proxy_html modifies element attributes (such as href in the a element) but can it rewrite arbitrary data in an element itself?
The internal application was provided by a vendor, and although it may be possible to make modifications to it to remove code like the above, I would prefer to stay away from that path for now to see if there are alternatives.
I've come up with a somewhat nasty work-around:
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLLinks script src
ProxyHTMLURLMap https://internal.company.com
The problem is the use of absolute URL's throughout the HTML (and javascript) coming from the vendor's app. A search and removal of the domain solves the problem (but is incredibly slow).
If anyone has this problem in the future, I do not recommend using this solution. I'm guessing you're here because you can't modify the internal application. You should instead be sending in a ticket to whoever maintains the code to make their application more reverse-proxy friendly.
A potentially safer solution would be the use of mod_substitute. You could also consider ProxyHTMLExtended, but it can be quite brutal in its replacements, occasionally breaking JavaScript here and there.
Edit: Just noticed you're currently using ProxyHTMLExtended. My bad. As you've highlighted it is a pretty brutal and dangerous solution to the problem.

serving laravel with apache vhost

I followed instructions and added in my httpd-vhost.conf file
<VirtualHost *:80>
ServerName project-laravel-learn.my
DocumentRoot "/srv/http/project-laravel-learn.my/public/"
</VirtualHost>
also added like for other local projects, map in hosts file so that
project-laravel-learn.my goes resolves to 127.0.0.1
http (web user), has all permissions to write and read on that public
folder,
also app/storage is rw- for http,
however, when I visit project-laravel-learn.my I get page saying
Whoops, looks like something went wrong!
What might be the problem? Also how I can get more detailed error message as
this one above isn't that much useful.
Just to add, app was working fine before I moved it to /srv/http/, while developing and using php artisan serve command.
EDIT: Ok it works, I forgot to start my local web server instance, however now routing does not work, I get only homepage, but clicking on any link gives 404 object not found error!?
How to fix that?
Found solution here..
http://www.epigroove.com/blog/laravel-routes-not-working-make-sure-htaccess-is-working
I will leave it for a future reference.

Apache2 httpd.conf help

I have a domain, for example, http://example.com. It is already configured to point to
/var/www/
Basically, i want http://example.com to point to
/var/www/4.0/
and http://example.com/foobar/ to point to
/var/www/moo/
How can I do this with the httpd.conf file for Apache2? Thanks
Assuming you are only serving one domain (example.com), you can change your DocumentRoot to /var/www/4.0/
and set an Alias for the /foobar like
Alias /foobar /var/www/moo
If you are serving more than one domain from the same Apache, then you need to use the DocumentRoot within a VirtualHost tag.
More info is here: http://httpd.apache.org/docs/2.2/vhosts/
I think you're going about this the wrong way with httpd.conf, but I'll answer your question as you asked it first and then explain about that.
There are two settings in httpd.conf relevant to this.
The DocumentRoot setting is the important one, it configures the base directory from which to serve. Change it as so:
Before:
DocumentRoot "/var/www"
After:
DocumentRoot "/var/www/4.0"
Be sure not to use any / after the 4.0, it's not needed.
A little under 30 lines below this setting is another, which should say:
As the comment above it says, change it to "/var/www/4.0" too.
This would set www.example.com to the 4.0 directory (first part) and apply the relevant settings to this directory too (second part).
But I don't think you should do that, setting apache to serve the 4.0/ directory with httpd.conf makes a mess for serving the other directories. I'd suggest you read about redirects and how to implement them with whatever language you're using. Then you can point one URL to another without it ever being noticed in the browser (unless they're really trying to).
So without changing DocumentRoot from "/var/www", you can edit /var/www/index.php (or whatever) and have it redirect to /var/www/4.0/. The same can be done in /var/www/foobar/index.php to display /var/www/moo/ instead, but here I'd really just rename the "foobar" directory on the server to "moo". If you want to get elaborate, look into mod_rewrite, but I'd advise you to try all your alternatives first and only use it if you really need to, it's quite a complex tool.