apach proxy requests to multiple different subdomains - apache

I have a web app at domain1.com which needs to be able to make requests to many different sites, too many to add specific vhost information for each site, what I'd like to be able to do is make a request with the web app to its hosting apache server like this
/domain1.com/some/path
/domain2.com/some/path
and for it to be send to
https://domain1.com/some/path
https://domain2.com/some/path
I've tried different settings using apaches ProxyPass but with no success
How do I do this?

That should be able to work with these directives:
ProxyPass /domain1.com/ https://domain1.com/
ProxyPass /domain2.com/ https://domain2.com/
A request to https://yourproxy.com/domain1.com/some/path should then be forwarded on to https://domain1.com/some/path. It is also possible you may need to use some of the SSLProxy* directives from mod_ssl.
Edit Based on the comment, you might try this:
ProxyPass / http://
I just now tried that, and http://myproxy.com:port1/myserver.com:port2/some/path was sent on to (and returned from) http://myserver.com:port2/some/path.
However, this seems like a bad idea from a security standpoint. I suppose it does allow the proxy to sit on one side of a firewall and allow the backends to be behind the firewall. I am certainly no web expert, but it just feels a bit sketchy.

Related

rewrite subdomain using .htaccess

My main domain is subdomain.domain.tld, and I want to rewrite all the traffic from subdomain1.domain.tld to the first one. Meaning if someone accesses subdomain1.domain.tld/whatever.php, he actually accesses subdomain.domain.tld/whatever.php, however, he's still shown subdomain1 in the browser's navigation bar.
I did some research, but I couldn't find something too promising.
You don't need rewriting for this, in fact internal rewriting is not possible between separate hosts...
Assuming that both "subdomains" (those are actually hostnames) are served by the same http server you can simply configure the same DocumentRoot for both hosts. That way they serve exactly the same file system which obviously means that the same scripts will be called.
Maybe you can get away even more simple if you just use the ServerAlias command for your virtual host. This obviously is only possible if you do not need separate configurations for both hosts.
Just take a look into the documentation of the apache http server. This is explained and good examples are offered:
https://httpd.apache.org/docs/2.4/vhosts/examples.html
In case those two hosts are not served by the same http server you could use an internal proxy setup: subdomain1.domain.tld acts as a front end proxy for subdomain.domain.tld, so it just relays all incoming requests and also the outgoing responses. That is easily done with a combination of the ProxyPass and the ProxyPassReverse rules offered by apaches proxy module: https://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassreverse
This setup can even be used if the two http servers operate on different IP addresses or even completely separate systems.

Forwarded Tomcat through Apache uses wrong Context path

Okay let me explain my problem really fast. I have a JEE Programm running on my tomcat server. The server has some user defined in the tomcat-users.xml When i test my programm on my local machine everything works fine.
However if i deploy the .war on my server and i want to access a Rest Endpoint i get a 401 unauthorized error. If i remove the users security check i can work fine with the program. So the URLs and server setup is correct.
I think that the problem is somehow related to the forwarding of tomcat through my apache.
So lets assume i have an apache running on http://myIp.de
then i forwarded tomcat with following apache config:
ProxyRequests off
ProxyPass /tomcat http://localhost:8181/ nocanon
ProxyPassReverse /tomcat http://localhost:8181/
so now i can reach tomcat through: http://myIp.de/tomcat
also i can "speak" to my app via: tomcat/myApp
But somehow the Authentizication now fails. And i think the problem is
somehow related to wrong context path. Because tomcat/manager
also fails to login.
Make your life easier by deploying your app under /tomcat on tomcat too. This way there's no path-translation required. Keep in mind that you'll get all the session cookies tied to a specific path and this path is not necessarily translated once forwarded to the client.
Also, sooner or later you might need
ProxyPreserveHost On
(look it up) or utilize mod_jk to preserve this header (and more information) automatically.
Edit: Following your comment, Basic Auth headers seem not to be forwarded to tomcat as well. I haven't attempted this myself, but all the places that I've looked up seem to imply that there'd be some duplication (e.g. second credentials file for Apache) - that doesn't look good. In this case I'd suggest to try out mod_jk rather than mod_proxy. You'll use the JkMount directive, rather than ProxyPass and need a workers.properties, but mod_jk is a lot better in keeping the full context of the request when forwarding to tomcat. I've had good experience with it so far and have only heard little complaints about it - largely in situations that were pretty huge and complex/complicated anyway. At least you should try if it solves your problems.

What's a simple way to serve http://localhost as https://someOtherDomain?

I run a local development web server for testing out code changes.
Often I have to test my local changes with remote services that can only connect securely to another domain.
e.g. https://external1.com will only talk to https://someOtherDomain.com, but I've got to test integration of my new code changes with https://external1.com
While I've got a setup configured that works, it seems complex, and took a bit to get setup right. It seems to me that many developers would want to do this same thing, so my question is this:
Is there an easy way to proxy my local webserver as https://someOtherDomain.com ?
EDIT: So maybe this should be asked this way - Does a command line or GUI tool exist that you can pass a local port and a domain name, and it serves your local port securely over https://someOtherDomain.com - no config or SSL cert creation required? Of course it'd be nice if the SSL cert could be replaced through configuration if need be, but by default, it'd work automatically, by using a precanned SSL cert. And even though I'm using Apache, I'm looking for a solution that actually doesnt use Apache - it uses something else. Why? Because I want this solution to work well with any other webserver that's being used by people on our team - as we all run different stacks, and I'd like to be able to let any of us securely serve our sites without having to configure each webserver individually.
Here's my current setup for taking my local webserver and serving it up at https://www.someOtherDomain.com
To test this locally, I've been:
editing my hosts file, and adding an entry to make www.someOtherDomain.com point to my local machine, which of course is running my dev server. This makes it so my local site is now available at http://www.someOtherDomain.com
127.0.0.1 www.someOtherDomain.com
Running Apache with a SSL Cert setup and mod_proxy to redirect all https requests to my local http server, thus making my site available at https://www.someOtherDomain.com. Here's my Apache config for this:
ServerName www.someOtherDomain.com
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/
<Proxy balancer://mycluster>
BalancerMember http://localhost route=1
</Proxy>
ProxyPass / balancer://mycluster
ProxyPassReverse / balancer://mycluster
SSLHonorCipherOrder On
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite RC4-SHA:HIGH:!ADH
# Rewrite all http requests to https
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
I run this on a mac, but am interested in solutions for linux as well. I've seen various Man in the Middle proxy's that sound like they'd work with some configuration... but I'm looking for something really simple to install and run - not just for me, but something I can tell team members about too, as we may all have to do this a lot in the future.
IMPORTANT NOTE: My local webserver isn't running on Port 80, though I've put it this way in the above example, to keep it simple. I understand port 80 on a mac is a bit special, but am very happy with solutions that work fine on all ports but port 80.
I think mitmproxy can do this for you, as least on linux and os-x. I haven't tried it myself but this question seems to show how it is done. It's still not a trivial program though.
There are however other approaches, which I have used:
The first one is the most pretty simple one, create a DNS entry for develop.mydomain.com which points to 127.0.0.1 and a single certificate for a (sub)domain where you control the DNS. Spread that certificate to all your developers. They'll still need to setup SSL themself but they don't need to generate certificates anymore. It has the added benefit that everybody is developing against https://develop.mydomain.com which allows them to share the configuration.
For bonus points, create a DNS entry for *.develop.mydomain.com and a wildcard certificate and your developers can have different sites (e.g. https://project1.develop.mydomain.com and https://project2.develop.mydomain.com) on there local machine. (Contrary to what the internet sometimes tells you, name based virtual hosting works fine with SSL as long as the certificate is valid for all the named hosts). Since the domain is the same for everybody you can consider getting a valid wildcard certificate to get rid of the warnings.
Unlike the solutions below this works even outside of the office network, which may be relevant when people are working from home or at the customer.
Building on this you could also create DNS entries for the internal IP's of the developer machines (if those are fixed). This does add some work, but it means the ongoing work of a developer can be reached by others in the local network, which can be very convenient for demo's, testing on mobile devices, etc.
An other option is to configure a single machine to proxy for all your developers. Create a DNS entry pointing to the internal IP of this box on something like *.develop.mydomain.com, a matching wildcard certificate and configure that box once with the correct certificate. Now you can create a virtual host for each proxied server, and again, all sites will be reachable throughout the local network, but it does require the developer to have fixed ip addresses (or hostnames added to DNS through DHCP).
Combined with the ability of apache to include all files in a directory in it's configuration makes it trivial to create a script which adds a new site based on a template. All it has to do is write a new file based on the requested subdomain plus the destination and reload the apache config. This means something like a simple PHP script can do what you want the application to do.
If you want to expose your web on your local machine to the internet try Runscope Passageway, it's easy to setup and "just works" (from experience).
Another alternative is ngrok which I also used, but it didn't always work for me.

How can I use a different URL instead of a port?

I have a server with several services running. One of them is accessible through the domain name like "https://www.foo.bar". Two other services are running on specific ports. So they are accessible through "https://www.foo.bar:1234".
Is it able to configure an apache2 server in a specific way, so it uses always the port 443 but with a different URL like "https://www.foo.bar/service1"?
Try ProxyPass, what you describe is a special case of a setup called Reverse Proxy: your httpd forwards requests to the other service and returns the answers to the client. (The other service happens to run on the same machine in your case, but it needn't. A simple kind of backend load-balancing can also be done this way.)
<Location /service1>
ProxyPass https://localhost:1234
ProxyPassReverse https://localhost:1234
</Location>
Be careful that your other service needs some rudimentary support for this kind of setup: if it returns HTML pages with links in it, it can't assume anymore that https://www.foo.bar:1234/foo/bar.html is the correct URL to tell the client. httpd will not look into the returned content and rewrite it for you.

Applying IP rules to HTTP only (and not HTTPS) with .htaccess

I have been setting up an IP blocklist reciently and I was wondering is it possible to block an IP that is connecting via HTTP and not to block them if they connect via HTTPS. There was a post on SO .Htaccess rules to redirect respective HTTP links to HTTP and HTTPS to HTTPS? which is similar but uses mod_rewrite which I have had horrible experience with and has only given me 500 errors in the past . Is there any way to do it with the standard format?
order allow,deny
allow from 192.168.1.0/24
deny from all
I need support for IPv6 addresses too. If the rewrite method is the only option, in your answer could you include a link that I could look at to perform my task properly? Many thanks!
I am using Apache/2.2.20 (Ubuntu)
What you desire isn't built into Apache's .htaccess mechanism. Simply: no protocol level commands are supported by mod_auth or mod_access. Furthermore, what you seek breaks the expected assumption that if you provide a resource over HTTP, that same path will work over HTTPS. This will cause surprising results for people using HTTPS enforcers.
But, if you're dead set on doing something like this, I would recommend Squid. You can use it to do all kinds of nifty things, like denying access to the cache from certain protocols on a per-file basis, and otherwise fiddling with data coming off your Apache server before you serve it to your users.