Azure Cloud Service (classic) web role with load balancer probe doesn't seem to work for HTTPS - azure-cloud-services

I am trying to change an old classic cloud service to use an HTTP health probe instead of the default process-based check. We've had some issues where instances stopped working but it thought they were still usable because they were running, but couldn't respond to requests.
Our site is HTTPS only, we don't even have an HTTP endpoint defined. Or didn't. The load balancer doesn't support HTTPS, so I had to add an HTTP endpoint and configure that to be used instead. That's gross but it seems to work. However, the HTTPS site doesn't seem to be covered by the health checks for the HTTP endpoint.
If I query my health probe path via HTTP, I can see that it's returning a 503, and if all instances return a 503 I can see that endpoint fail to load until I make one return 200 again. Once I make one return a 200 again, it works. My requests get routed to the appropriate node, if possible.
However, the HTTPS requests always seem to go to the same instance, regardless of the probes. Flipping that instance from 200 to 503 doesn't cause those requests to go to the other instance, like it does with HTTP. It isn't balanced at all.
It's really hard to find useful documentation or examples on how this should be set up or if it can work at all. Below is my csdef file. Is it possible to get this working (either an HTTPS check or the HTTP check affecting the HTTPS endpoint)?
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="..." xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<LoadBalancerProbes>
<LoadBalancerProbe name="health" protocol="http" port="80" path="health" intervalInSeconds="5" timeoutInSeconds="11"></LoadBalancerProbe>
</LoadBalancerProbes>
<WebRole name="..." vmsize="Standard_D2_v3">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
<Binding name="LoadBalancerEndpointBinding" endpointName="LoadBalancerEndpoint" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="https" port="443" certificate="..." />
<InputEndpoint name="LoadBalancerEndpoint" protocol="http" port="80" loadBalancerProbe="health" />
</Endpoints>
<ConfigurationSettings>
<!-- ... -->
</ConfigurationSettings>
<Certificates>
<!-- ... -->
</Certificates>
</WebRole>
</ServiceDefinition>

The answer in my case was to add the loadBalancerProbe attribute to both endpoint elements. I also had to make sure that however I was testing the service made new connections for every request or they would always go to the same instance (e.g. HttpClient pools connections internally per instance). This is essentially the new working configuration file:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="..." xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<LoadBalancerProbes>
<LoadBalancerProbe name="health" protocol="http" port="80" path="health" intervalInSeconds="5" timeoutInSeconds="11"></LoadBalancerProbe>
</LoadBalancerProbes>
<WebRole name="..." vmsize="Standard_D2_v3">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
<Binding name="LoadBalancerEndpointBinding" endpointName="LoadBalancerEndpoint" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="https" port="443" certificate="..." loadBalancerProbe="health" />
<InputEndpoint name="LoadBalancerEndpoint" protocol="http" port="80" loadBalancerProbe="health" />
</Endpoints>
<ConfigurationSettings>
<!-- ... -->
</ConfigurationSettings>
<Certificates>
<!-- ... -->
</Certificates>
</WebRole>
</ServiceDefinition>

Related

Can I use subdomain with Visual Studio

I am trying to render my asp.net core app locally on https://localhost:44301 and also https://sub.localhost.test.
I added the following to my hosts file 127.0.0.1 sub.localhost.test. Then I edited the binding info in the C:/ProjectName/.vs/config/applicationhost.config file to the following
<site name="ProjectName" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\ProjectName" />
</application>
<bindings>
<binding protocol="https" bindingInformation="*:44301:localhost" />
<binding protocol="https" bindingInformation="sub.localhost.test" />
</bindings>
</site>
I also trird <binding protocol="https" bindingInformation="*:44301:sub.localhost.test" />. But, when I go to https://sub.localhost.test I get Unable To Connect error.
Is it possible to run my local project on both https://localhost:44301 andhttps://sub.localhost.test`? If so, how?
Use port in the bindings. For http port 80 for https post 443
<binding protocol="https" bindingInformation="*:443:sub.localhost.test" />
</bindings>
Reference

Using SSL with IIS Express

I am trying to run my VS project on localhost using a fake domain (bobby.fisher.com). To do this I created a virtual directory in the applicationhost.config file as follows:
<site name="Tidywork.Integrations.Web" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\bobbyfisher\Workspaces\bobbyfisher.Integrations\bobbyfisher.Integrations\bobbyfisher.Integrations.Web" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:35464:localhost" />
<binding protocol="http" bindingInformation="*:80:bobby.fisher.com" />
<binding protocol="https" bindingInformation="*:44321:localhost" />
<binding protocol="https" bindingInformation="*:44321:bobby.fisher.com" />
</bindings>
</site>
However, when I tried run the program (https://bobby.fisher.com/) I ended up with an error:
This site can’t be reached
bobby.fisher.com refused to connect.
Try:
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
Does anyone have any suggestions how to do this?
If you don't specify a port in your URL when accessing the site, then if you chose https:// (as per your example) the browser will try to connect on port 443 automatically - because that's the standard port for HTTPS.
But you haven't configured that port in your IIS settings. So either bind that port to https for your application, or use a port number explicitly in your URL (e.g. https://bobby.fisher.com:44321)

allow prefix before localhost domain name in IIS express

I'm building a MVC web application that should respond to domains like a.sub.example.com, b.sub.example.com, c.sub.example.com etc. I'm ok figuring out how to get out the a,b,c etc prefix and create a proper route accordingly, but I'm struggling to get the IIS webserver to actually forward the requests to the same webapplication.
I followed this guide to make IIS express listen to another address, in this case sub.example.com, which works fine. However, I cannot figure out how to get it to listen to all subdomains of that one. When I direct my browser to a.sub.example.com, I get an error:
HTTP Error 400. The request hostname is invalid.
I added both sub.example.com and a.sub.example.com as aliases for 127.0.0.1 in my hosts file.
My applicationhost.config file's 'site' entry looks like this:
<site name="MyProject.Web" id="7">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="..." />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:8888:sub.example.com" />
</bindings>
<applicationDefaults applicationPool="Clr2IntegratedAppPool" />
</site>
When I replace the 'bindingInformation attribute with
"*:8888:*.sub.example.com"
as the previously mentioned guide suggests I should do when I want IIS express to listen to multiple domains, IIS Express fails to start at all.
Am I missing something obvious here?
The way i know of is to set the IIS applicationhost.config (Full path: %UserProfile%\Documents\IISExpress\config\applicationhost.config) and find the referance to the port number.
<site name="WebSite1" id="1">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%WebSite1" />
</application>
<bindings>
<binding protocol="http" bindingInformation=":49483:localhost" />
</bindings>
</site>
i normaly add <binding protocol="http" bindingInformation=":49483:" /> to accept all hosts on that port (note empty string, not wildcard *).
You will have to have set up this host to point to 127.0.0.1 in your hosts file. Or, use a domain you own and point .sub.mydomain to 127.0.0.1. Hosts file doesn’t support wildcards () but DNS does! This means I can easily set up myproject.sub.mydomain and myproject.sub.mydomain without having to add new lines to my hosts file (so long as I have an internet connection)!
Hope this helps

Override site binding using VS2015 and IIS Express

I'm implementing OAuth authentication in a MVC6 site using VS2015 RC. The previous incarnation of the site required a custom binding and I'm trying to achieve the same with VS2015. Debugging with IIS Express, however, is proving difficult.
If I amend the dnx "web" command to use an alternate url, all works as expected:
"commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://www.devurl.co.uk:31122",
"gen": "Microsoft.Framework.CodeGeneration",
"ef": "EntityFramework.Commands"
},
If I try and do the same thing with IIS Express by changing the applicationhost.config file (within the project/.vs/config folder as per Wildcard hostname in IIS Express + VS 2015)...
<sites>
<site name="WebApp1" id="1">
<!-- removed for brevity -->
<bindings>
<binding protocol="http" bindingInformation="*:31122:www.devurl.co.uk" />
</bindings>
</site>
<!-- removed for brevity -->
</sites>
...a new site entry is with a binding to "localhost".
<sites>
<site name="WebApp1" id="1">
<!-- removed for brevity -->
<bindings>
<binding protocol="http" bindingInformation="*:31122:www.devurl.co.uk" />
</bindings>
</site>
<site name="WebApp1(1)" id="2">
<!-- removed for brevity -->
<bindings>
<binding protocol="http" bindingInformation="*:31122:localhost" />
</bindings>
</site>
<!-- removed for brevity -->
</sites>
The site is now running using the localhost binding. VS happily opens the dev url and tells me that the service is unavailable.
How can I instruct VS2015 to use the existing site and binding when debugging with IIS Express?
I used the instructions as defined here with a slight modification:
Wildcard hostname in IIS Express + VS 2015
In order to make it work I left the localhost binding and added an additional binding for *. This must be done in the ~ProjectFolder~/.vs/config/applicationhost.config and not in the old location of Documents/IISExpress.....
The corrected binding looks like this in my case:
<bindings>
<binding protocol="http" bindingInformation="*:4355:localhost" />
<binding protocol="http" bindingInformation="*:4355:*" />
</bindings>

Why does my Azure deployment still have a 3rd endpoint for Remote Desktop even though I've disabled it?

I previously enabled remote desktop in my Azure project to allow me to debug in our staging environment. This added a 3rd endpoint on port 3389 in addition to 80 and 443.
I've finished debugging and disabled remote desktop in the publishing wizard then did another deployment to staging. I then tried to do a VIP swap with our production instance, but Azure admin console is throwing an error due to staging have 3 endpoints and production have 2 (you can't do a VIP swap between instances that have different # of endpoints).
Here's what I've done to verify remote desktop is disabled:
I've triple checked that in the publish wizard that I specific to have remote desktop disabled.
The .azurePubxml has:
<AzureEnableRemoteDesktop>False</AzureEnableRemoteDesktop>
The cscfg has:
<Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="false" />
4.My csdef has:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="mysite.App" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="www" vmsize="Small">
<Sites>
<Site name="Web">
<VirtualApplication name="r" physicalDirectory="../ReviewPost/ReviewPost" />
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
<Binding name="Endpoint2" endpointName="Endpoint2" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
<InputEndpoint name="Endpoint2" protocol="https" port="443" certificate="STAR.mysite.com" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
<Import moduleName="RemoteAccess" />
<Import moduleName="RemoteForwarder" />
</Imports>
<Certificates>
<Certificate name="STAR.mysite.com" storeLocation="LocalMachine" storeName="My" />
</Certificates>
</WebRole>
</ServiceDefinition>
Despite the above configuration, the azure console is showing 3 endpoints (port 80, 443 and 3389) for the staging environment.
What am I missing?
Based on information from #smarx in the MSDN forums mirror of my question here's the solution:
Remove these lines from your .csdef:
<Import moduleName="RemoteAccess" />
<Import moduleName="RemoteForwarder" />
These 2 lines control the creation of the extra endpoint even though remote access may be disabled.

Resources