How to rewrite / proxy an Apache URI to an application listening on a specific port / server? - apache

They say that Apache's mod_rewrite is the swiss-army knife of URL manipulation, but can it do this?
Lets say I want to add a new application to my Apache webserver, where the only configurable option of the app is a port number.
I want to use & give out URLs of the form "http://hostname.example.com/app" rather than "http://hostname.example.com:8080". This would ensure that clients would be getting through the institution's firewall as well, and it's generally tidier.
My application includes absolute URIs in php, javascript and css, so I want to prepend my own root location to the URI in the applications internal links. I have no access to DNS records and so can't create another name-based virtual server.
Using Apache's mod_rewrite and mod_proxy modules, I can transparently redirect a client to the correct home-page of the application. But links within that homepage don't point a client to links relative to the new base URL.
So, what's the best way of proxying a request to an application that is listening on a specific port?
For example, if I had an application listening on port 8080, I could put this in my Apache configuration:-
<VirtualHost *:80>
SSLProxyEngine On
ServerName myhost.example.com
RewriteEngine On
UseCanonicalName On
ProxyVia On
<Location "/application">
RewriteRule ^/application/?(.*) http://localhost:8080/$1 [P,L]
</Location>
</VirtualHost>
This would work fine if the application didn't use absolute URLs, but it does. What I need to do is rewrite URLs that are returned by the application's css, javascript and php.
I've looked at the ProxyPass and ReverseProxyPass documentation, but I don't think these would work..?
I've also come across Nick Kew's mod_proxy_html, but this isn't included in the standard Apache Distribution, and my institution's webserver seems to have been fine for years without it.. Other than trawling manually (or using a grep -r | sed type expression) through the application's source code, or using this 3rd party add-on, are there any other ways to go about this?
Could I perhaps use some of the internal server variables in a mod_rewrite rule? For example a rewrite rule based on ’HTTP_REFERER'?

Using mod_proxy would work just fine. For instance, I mapped https://localhost/yalla/ to point to a subdirectory of my webserver:
LoadModule proxy_module modules/mod_proxy.so
ProxyRequests On
<Proxy *>
Order deny,allow
Allow from localhost
</Proxy>
ProxyPass /yalla/ http://yalla.ynfonatic.de/tmp/
If you implement this, you'll note that the pictues of the directory-listing aren't visible; this is because they're below the /tmp/ directory on the remote server, hence not visible.
So, in your case you'd do:
LoadModule proxy_module modules/mod_proxy.so
ProxyRequests On
<Proxy *>
Order deny,allow
Allow from localhost # Or whatever your network is if you need an ACL
</Proxy>
ProxyPass /app/ http://hostname.example.com:8080/
Like with everything in Apache configuration, watch those trailing slashes when referring to directories.
Good luck!
Alex.

Related

Allow internet users to access privately hosted website pages

I have a corporate private network(VPN) and on one VM a website is hosted which can be accessed internally only. e.g. https://internal.com/welcome.html
Now, I want to allow few pages of the site to be accessible from outside but with their own url.
e.g. they will open http://theirdoamin.com/welcome.html which will be redirected into my private network and internally it will be mapped/proxied to https://internal.com/welcome.html.
This way outside will never know the actual url (i.e https://internal.com/welcome.html.
My question is, can we achieve this using Apache Reverse proxy server sitting in-front of my hosted VM?
Second question, can I also limit the access to welcome.html page only and not others?
My colleague already implemented using Apache Nifi but I still believe it can be simple done using Apache Reverse Proxy setup.
Please advise.
Thanks
1) Yes, Apache reverse-proxy is able to do that.
2) You can limit access as you like.
1) I'd set up two vhosts (for examples), one with the original name and one with the VPN-accessable name.
Listen 80
#If you are running a Apache 2.2 you'll need the following line, for 2.4 you won't
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "srv/www/example1"
ServerName internal.com
<Directory "/srv/www/example1">
Require all granted
</Directory>
# Other directives here, if needed
</VirtualHost>
<VirtualHost *:80>
ServerName external.com
ProxyPreserveHost On
RewriteEngine On
RewriteRule ^ https://internal.com/welcome.html [P]
ProxyPassReverse / https://internal.com/
</VirtualHost>
You'll need the RewriteRule to target a specific file instead of a whole domain. Otherwise a simple ProxyPass would have been enough.
This requires the modules mod_rewrite, mod_proxy and mod_proxy_http to be activated.
2) is done by the RewriteRule. It only allows access to that specific target-file (welcome.html).

Apache 2.4 multiple applications on separate IPs under single domain

I am a little lost on how to achieve the following...
I have a single domain name which is running a CMS # www.mywebsite.com
If a specific URL is given apache calls the other VM (different IPv4) running a shop. www.mywebsite.com/store
I've trawled through apache vhosts but nothing seemingly covers the above scenario if its even possible ...https://httpd.apache.org/docs/2.0/vhosts/examples.html
Any guidance would be very much appreciated.
If I understand your problem correctly, you could do this with mod_proxy.
For example:
<VirtualHost *:80>
ServerName www.mywebsite.com
ProxyPass /store/ http://store.local/
ProxyPassReverse /store/ http://store.local/
</VirtualHost>
You could use the IP address, server hostname or whatever in the proxy directives - store.local is just an example.
The mod_proxy documentation is extensive.

Apache domain redirect between virtualservers

I've got one dedicated server which I splitted into more virtual servers.
On main server I use standard port for http (80), but for others I was forced to set different ports.
But I've got some spare domains.
What is best way to make invisible redirect to another server when user come through specific domain?
I don't want to use iframes or redirect to another website. I would like domain to act like on shared web hostings. But with different servers.
Is it possible to do?
I know that apache gets information about from which domain user came.
I would like to do it with virtual hosts if it's possible.
<VirtualHost *>
ServerName mydomain
ServerAlias mydomain
some redirection
CustomLog /var/log/apache2/mydomain.access.log combined
ServerAdmin myemail
</VirtualHost>
Thanks in advance :]
Since you have access to the server's config, take a look at the ProxyPass, ProxyPassMatch, and ProxyPassReverse directives that are part of mod_proxy. You'll need to make sure the module is loaded before you can use these directives.
In general, in your mydomain config, say you want to have visitors see the site at http://myother.domain.com/ when they go to http://mydomain/other, you'd just add:
ProxyPass /other http://myother.domain.com/
ProxyPassReverse /other http://myother.domain.com/
The ProxyPassReverse is to ensure proxied location responses get rewritten. For example, if a page at http://myother.domain.com/ returned a 301 redirect to http://myother.domain.com/newimage.gif, this directive will internal rewrite the response's location from http://myother.domain.com/newimage.gif to http://mydomain/other/newimage.gif, for it to be proxied again.
If you have cookie domains that also need rewriting, take a look at ProxyPassReverseCookieDomain and ProxyPassReverseCookiePath.

What are my options to deploy Go applications alongside PHP applications?

What I'm basically trying to accomplish is having my main website running a CMS written in Go. This will be located at www.example.com.
I also have applications written in PHP located in directories, such as www.example.com/clients/
How can I serve example.com/clients using Apache/PHP while serving example.com using Go built-in web server?
Via mod_proxy in Apache2, you can proxy different paths into different destinations at localhost or anywhere else accessible by your server, including within your local network (if your server can access it).
For this you would use ProxyPass (Apache2 Docs for ProxyPass, which is very useful reading) like the example below:
<VirtualHost *:80>
ServerName some.example.host.xyz
DocumentRoot /var/www/your-document-root
Alias /clients/ /var/www/clients/
ProxyPass /clients/ !
ScriptAlias /something-using-cgi/ /var/www/cgi-stuff/
ProxyPass /something-using-cgi/ !
ProxyPreserveHost On
ProxyPass / http://localhost:9876/
ProxyPassReverse / http://localhost:9876/
ProxyPass /elsewhere/ http://elsewhere.example.host.xyz:1234/
ProxyPassReverse /elsewhere/ http://elsewhere.example.host.xyz:1234/
</VirtualHost>
You'll want to be sure that you set your proxy security such that external users can't use your reverse proxy as a forward proxy, too. You can do that via ProxyRequests as described in the official Apache2 docs. The way I did this on a server is to put this in your server-wide config (you should verify on your own that this is secure enough):
# disables forward proxy
ProxyRequests Off
Andrew Gerrand has a good blog post about this for nginx but the principle is the same for Apache.
You want to set up Apache as a reverse proxy for requests coming in for the Go application.
For Apache you want to look at mod_proxy

Subdirectory on a different host

I've got a site www.example.com on one server. I'd like to create www.example.com/blog on another server/host.
A) Can I do this?
B) How can I do this?
I've read a bit on using Apache's mod_proxy, proxypass, and ProxyPassReverse, but I'm not gifted enough with Apache or server mgt to know if I'm on the right track or not. Or, if there are other options to doing what I want.
To be clear, I do not want a subdomain like blog.example.com. I know how I COULD do that with DNS, but I don't believe DNS is an option for subdirectories.
This is not doable nicely IMO. As you say, you would need a proxy based solution that fetches the content from the blog server and serves it to the user.
That has the serious downside that any traffic on your blog will have to run through your primary host, eating up bandwidth, resources and traffic volume.
Is a redirect (i.e. www.domain.com/blog doing a header redirect [visible in the browser's address bar] to blog.otherhost.com) an option?
If not, check out the documentation on mod_proxy. The basic example for a reverse proxy looks good already:
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar