aspnet / KestrelHttpServer

[Archived] A cross platform web server for ASP.NET Core. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
2.63k stars 528 forks source link

Azure hosting bug - The specified CGI application encountered an error and the server terminated the process. #939

Closed xatabhk closed 8 years ago

xatabhk commented 8 years ago

Azure site returns error message "The specified CGI application encountered an error and the server terminated the process." if SSL certificate is set in in Main() for Kestrel as follows:

var application = new WebHostBuilder() ...
        .UseKestrel(options => { options.UseHttps("xxxx.pfx", "1xxxxx"); })
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();
        application.Run();

azure_ssl_error

davidfowl commented 8 years ago

You can't use https on kestrel when hosted in front of IIS (which is how azure websites hosts you).

xatabhk commented 8 years ago

So how to detect if an app is hosted in front of IIS?

guardrex commented 8 years ago

Maybe something like this?

KestrelServerOptions kestrelOptions = new KestrelServerOptions();
kestrelOptions.AddServerHeader = false;
kestrelOptions.<some_other_option> = <value>;
var pairingToken = Environment.GetEnvironmentVariable($"ASPNETCORE_TOKEN");
if (string.IsNullOrEmpty(pairingToken))
{
    kestrelOptions.UseHttps("xxxx.pfx", "1xxxxx");
}
...
var host = new WebHostBuilder()
    .UseKestrel(kestrelOptions)

Note that if you want to explicitly know if you're on Azure, do it the publish iis way: https://github.com/aspnet/IISIntegration/blob/dev/src/Microsoft.AspNetCore.Server.IISIntegration.Tools/PublishIISCommand.cs#L92

Tratcher commented 8 years ago

@halter73 this looks like a similar error to the other thread we saw. Have you been able to repro it to at least understand why it throws?

davidfowl commented 8 years ago

@xatabhk When are you not running behind IIS?

cwe1ss commented 8 years ago

@xatabhk When are you not running behind IIS?

obligatory "Azure Service Fabric" mention :laughing:

xatabhk commented 8 years ago

@davidfowl I don't know actually. Behind IIS or not I see no difference in code.

davidfowl commented 8 years ago

Not sure what you mean. Do you have plans to run your program with just kestrel (btw that's not recommended for the public internet). If you're running behind IIS and I don't think you need to detect that, then you configure ssl there not in your application.

If you plan to run on azure website then you're running on IIS and I'd recommend running IIS express locally (since your target is IIS)

guardrex commented 8 years ago

@xatabhk

configure ssl there not in your application

https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure-ssl-certificate/

xatabhk commented 8 years ago

@GuardRex I know how to configure SSL for Azure web site; Just want to write an app works no matter how it is hosted.

guardrex commented 8 years ago

@xatabhk Then you can use the code I posted above, which should detect running behind IIS based on the pairing token. In theory, that should work ... but @Tratcher and @davidfowl are the real experts here, so they'll give us the word on it.

Tratcher commented 8 years ago

@GuardRex Yes that should work, but I think your polarity is reversed:

if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable($"ASPNETCORE_TOKEN")))
{
    kestrelOptions.UseHttps("xxxx.pfx", "1xxxxx");
}

That said, I'd still like to see the exception that's preventing it from working without this workaround.

guardrex commented 8 years ago

Oooops! :smile: ... yeah ... cut-and-paste out of the repo code got me. Thx. It's fixed now.

xatabhk commented 8 years ago

@davidfowl Not planning, just doing tests and don't want to tie an app to IIS. Also no this issue with IIS Express in VS IDE.

halter73 commented 8 years ago

@Tratcher I was able to successfully get Kestrel's sample app running behind ANCM with UseHttps. It makes sense considering that the address provided by the module is HTTP, so the HTTPS connection filter isn't used.

@xatabhk Are you able to use HTTPS locally without IIS? Are you sure your publishing your pfx file to the correct location? If the pfx file isn't where the app expects you'll see an error like the following even at startup if HTTPS isn't used:

Unhandled Exception: System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertFileType(String fileName)
   at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
   at Microsoft.AspNetCore.Hosting.KestrelServerOptionsHttpsExtensions.UseHttps(KestrelServerOptions options, String fileName, String password) in C:\Users\shalter\dev\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel.Https\KestrelServerOptionsHttpsExtensions.cs:line 51
   at SampleApp.Startup.<>c.<Main>b__1_0(KestrelServerOptions options) in C:\Users\shalter\dev\Universe\KestrelHttpServer\samples\SampleApp\Startup.cs:line 55

You could enable stdout logging to try to see what error is happening. Make sure that the logging directory is published, because it will not be automatically created for you. You might also need to enable console logging in your application.

xatabhk commented 8 years ago

@Tratcher @GuardRex Yes. The workaround works. But IIS Express does not need this workaround, so there may be a fix.

xatabhk commented 8 years ago

@halter73 Everything is OK locally, self-hosted or IIS Express hosted.

benaadams commented 8 years ago

@xatabhk When are you not running behind IIS?

obligatory "Azure Service Fabric" mention :laughing:

Not sure what you mean. Do you have plans to run your program with just kestrel (btw that's not recommended for the public internet).

I'd assume interconnected microservices that communicate directly with each other using Kestrel (either webapi or websockets) rather than a different network protocol (e.g. FabricTransport, Wcf, RabbitMQ, custom TCP etc).

If its an internet exposed cluster you would only have one gateway microservice exposed, which would be fronted by IIS (or multiple using hostname differentiation - which would also need IIS/http.sys); but you wouldn't use IIS as a layer between each microservice - however you may want to use https to secure the comms.