IIS8 Reverse Proxy - Custom external port - windows-server-2008-r2

I am trying to configure my IIS reverse proxy to route http connections to an internal server however I am not sure how to achieve what I need or even if it is possible.
I have a sub domain on my IIS server for example,
testing.contoso.com and externally I would like to have http://testing.contoso.com:8080 which will then map to my internal server http://server04.contoso.local:8080. So I do not want my internal site to appear as http://testing.contoso.com on port 80.
My reason for doing this is that I will have quite a few internal and external corresponding ports.
Is it possible to configure this with my IIS reverse proxy or does IIS only support ports 80 & 443 externally?
Thanks in advance, Neil

From what I see in your question, it should be fairly easy to make that work using IIS Application Request Routing: http://www.iis.net/downloads/microsoft/application-request-routing
That should let you use any ports or hostnames in a machine being exposed and then let that route to any other machines (or same) in any ports or combination. It also will allow you to offload cache of static files, and many other nice features. It uses URL Rewrite for the main engine on which server to route to, so you can literally add any logic you want, and if need be you could use extensibility of URL Rewrite to add custom code to define the logic (though the built-in configuration one should be rich enough).

Related

How to create a secure internal route in the CloudFoundry environment (Swisscom AppCloud)

I would like to create a secure internal route between two applications within the same space/organization. It should never be possible to reach the Node.js application from the outside. My Java application connects via HTTP to the Node application (running on express).
I have now tried to setup the desired configuration by creating a route called example-route.apps.internal and assigned it to the Node application. As a next step, I've opened the port (I've tried 443, 80, 8080) in the network configuration of the Java application (with the destination being the Node app). I restaged both applications.
Then, I opened a Java connection to the link http://example-route.apps.internal/test123. I've also tried to use https. The result was the same. Java refused to conncet to this URL.
Now, the following questions:
How can I properly set up this communication? Should I resolve this internal DNS somehow? Which port is the correct one if I just use the port of the env variable? How should I read this port from the other application?
How secure is the communication, if HTTP is used instead of HTTPS? (I assume HTTPS is not possible internally). Is it as safe as an HTTPS connection from the outside? Which devices are between, how far out does the connection go?
Thank you!
I think you're almost there.
Then, I opened a Java connection to the link http://example-route.apps.internal/test123. I've also tried to use https. The result was the same. Java refused to conncet to this URL.
You should use http://example-route.apps.internal:8080/test123. Your app is set to listen on $PORT, which is always 8080 in current versions of CF.
Normally you don't need to worry about this because your traffic goes in through Gorouter which translates for you (maps external port 80 -> internal 8080). With internal routes, traffic is direct so there is no transformation. That's why you need to use port 8080 in your URL.
Alternatively, you could use a service discovery mechanism like Eureka or Consul, but it's not a requirement. In this case, the service would know it's listening on 8080 and register that in the registry.
As far as HTTPS, that's tricky. Your app is only listening on 80/HTTP. You would have to change it to listen on 443/HTTPS, but then you need certs and different server configuration. It's technically possible, but it's a whole can of worms.
In some newer versions, Envoy is present and accepts HTTPS traffic into a container, can make HTTPS easier but it's still not a slam dunk (at the time of writing, at least). I expect this will get better in the future.
Should I resolve this internal DNS somehow?
Internal DNS helps with locating your other apps, not the port. Otherwise you'd need to manage IP addresses, which change often, and that would require something like Eureka or Consul.
Which port is the correct one if I just use the port of the env variable?
See above.
How should I read this port from the other application?
It's always 8080 at the moment, and has been for multiple years. It's unlikely to change, so you could probably hard code or set it in a config file safely.
How secure is the communication, if HTTP is used instead of HTTPS? (I assume HTTPS is not possible internally).
Is it as safe as an HTTPS connection from the outside? Which devices are between, how far out does the connection go?
Traffic would not be accessible externally as it wouldn't leave the Cell in some cases or worst case it goes between two Cells, but traffic would be visible internally since it's not encrypted. That means you need to have more trust on your CF provider, who would have access to internal traffic.
If it were HTTPS, only someone with the key would be able to decrypt it. You would still have to trust your provider though as they could likely get the key & use it to decrypt traffic. It would just be more work for them than if traffic is unencrypted.
Hope that helps!

Want to have app (Server:Port) to have friendly alias - Understanding Host Alias / DNS / A Record / CNAME

I am trying to get my head around Windows, Networks and Domains.
I currently have a server - svr. This is on my domain companyname.co.uk
I can connect to server and ping both svr and svr.companyname.co.uk.
On this server I have a number of applications with web access; TeamCity, Octopus etc. We currently connect to them by browsing to svr:xxxx where xxxx is the port of the web app host (http://svr:9090/ for TC)
I want to create friendly alias' - for example teamcity.companyname.co.uk would point at svr:9090, octopus.companyname.co.uk would point to svr:8090.
However, not being experienced in this area I can't seem to find relevant documents or sites that fully explain what I am looking for.
First, to make one thing clear: when you visit a web page like http://example.com, your web browser is actually making a request to example.com:80. This is done transparently because port 80 is the standard port for the HTTP protocol. As you know, you can request a non-standard port by appending it to the domain name in the URL: http://example.com:888/.
Unfortunately, you cannot have a domain name "alias" that somehow includes a non-standard port - your browser will always try to use port 80 if you don't specify a port.
One solution would be to use a proxy - nginx, apache, lighttpd, and others can all do this.
The idea is that you set up a proxy server that is listening on port 80 on your host. It waits for connections, then forwards those connections to a different server (on the same host, or on a different one) based on some rule. So, for example, you might have rules that look something like this:
IF host = teamcity.companyname.co.uk THEN forward to teamcity:9090
IF host = octopus.companyname.co.uk THEN forward to octopus:8090
The syntax for these rules vary widely between different proxy configurations, so this is just an example.
Note that this is not a redirect - the user's browser connects to teamcity.companyname.co.uk for all requests. It's the proxy that sends the request on to a different service and forwards any responses back to the client "behind the scenes".
These proxy configurations can get quite complex. For example, what if your teamcity application serves a page with a link on it that points to http://teamcity:9090/path/to/page? The user's browser is going to fail if they click on that link. Fortunately, proxies can be configured to rewrite URLs like this on the fly. You'll need to do some research to tailor this solution to your situation.

Run Ghost as an NPM module on a subdomain using Node.JS

Is there any way to run Ghost on a subdomain using Node.JS? I am able to run it normally on Node.JS like:
App.Modules.Ghost = require('ghost'); /**< Ghost module. */
App.Apps.Ghost = App.Modules.Ghost({ config: '/Assets/Ghost/Config.js'.LocalFilePath }); /**< Create Ghost app. */
Then, I am then able to go to http://example.com/ghost/ and view my blog. Although this works for now, I want to be able to view my blog at http://blog.example.com/ using Node.JS.
Sadly, the way networking works prevents this in the context you desire. In order to achieve that sort of functionality, you would need a proxy server to go in front of the entire application. I would suggest NginX for this ability, due to its speed and wide-spread use.
Why is this not possible?
In this sense, networking is the system where you bind to an IP and a port. When you bind, nothing else can bind to that same IP/port. Since a domain (and subdomain) simply point to an IP address, there is no way that you can separate these connections at the networking level. This is why the Host HTTP header was added.
How does NginX do it?
NginX parses the Host header and can send the connection to your Ghost server as you wish it to be forwarded to. This also allows you to forward the main domain (http://example.com) to whatever website you like, therefor using different applications and such on the same IP and port.
This answer contains the best directions on how to achieve this functionality.

deploying a node.js on a new domain

I have a server that runs different websites on different ports. All of them (but one) are Apache servers and thanks to webmin, I managed to have, for instance, example.com point to 123.123.123.123:80 and example.fr to 123.123.123.123:8000, somehow automatically
I am now running a nodejs server on the same machine, so the 80, 8000, and many other ports are already taken. My nodejs listens on 8008. I have another domain name, say example.org, and I want it to point to my nodejs website, but I simply don't know how to do that! I have updated the DNS and everything is pointing to 123.123.123.123 (my server's IP). I want to avoid using an ugly example.org:8008/ for everything on this node server. How can I make it point implicitly to the 8008 port?? I must add that I cannot afford to take down the apache servers ;)
DNS only provides name to ip address mapping. It cannot handle ports. What you can do instead is to set up a proxy server listening on port 80. The proxy server can then return data based on the host header.
Your best option is to just redirect the request from Apache. Otherwise you can use a reverse proxy like Nginx. Also, you can write a lightweight proxy in node... check out this page

Forwarding or exporting a client certificate in IIS6/7

Currently, our program runs on JBoss and sits behind an apache reverse proxy. Apache handles verifying the client certificate. We have the +ExportCertData option set in apache, and then we use
RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}e"
to put the cert in the header field SSL_CLIENT_CERT before forwarding to JBoss. Our application in Jboss then reads the cert looking for the SubjectAltName to get the e-mail address, which we use to save the user a step in entering it in.
Now, we will have to live behind IIS, and will need similar functionality to this. What we really care about is extracting the email address from the SubjectAltName. In an ideal world, IIS would provide the same information as apache, so we wouldn't have to modify our application code too much. But if it's not possible, other options are good as well.
Some other notes:
We will probably need to support IIS6 and IIS7. It would be nice to have one solution that works across both, but not necessary
We are currently using IIRF to forward requests that go to a certain virtual directory, but I would be interested in hearing other solutions that could accomplish what we're looking for along with forwarding to our application server.
Just throwing apache in front of IIS isn't going to be a solution because we have to share the box with other programs that use IIS and they might be wary of such a solution. Also, we can't just run on a different port because of firewall restrictions only allow port 80 and port 443.
Any ideas how to make this possible? Let me know if there's any more information I can provide.

Resources