Azure Web App deployment certificate problem

Hi,
For a number of days now we’ve been struggling to be able to deploy to a new Azure Web Application that we’ve setup in a new environment. This is caused by a certificate problem, but we’d like to bypass the certificate check when deploying.

Unfortunately there doesn’t appear to be an AlllowUntrustedCertificates option like there was in the old MSDeploy step.

To get around this I’ve tried a number of things.

  1. Running the following deployment script before executing the deployment:
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;    
    public class IDontCarePolicy : ICertificatePolicy {
        public IDontCarePolicy() {}
        public bool CheckValidationResult(
            ServicePoint sPoint, X509Certificate cert,
            WebRequest wRequest, int certProb) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy 
  1. Trying to execute the following before deployment:
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true; }

Neither of these seems to make any difference.

The full stacktrace is as follows:

Microsoft.Web.Deployment.DeploymentDetailedException: Connected to the remote computer ("xxx.xxx.xxx.xxx") using the specified process ("Web Management Service"), but could not verify the server's certificate. If you trust the server, connect again and allow untrusted certificates.  Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_CERTIFICATE_VALIDATION_FAILED. ---> System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
January 16th 2017 12:24:38Error
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
January 16th 2017 12:24:38Error
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
January 16th 2017 12:24:38Error
   at System.Net.ConnectStream.WriteHeaders(Boolean async)
January 16th 2017 12:24:38Error
   --- End of inner exception stack trace ---
January 16th 2017 12:24:38Error
   at System.Net.HttpWebRequest.GetResponse()
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponseHelper(HttpWebRequest request)
January 16th 2017 12:24:38Error
   --- End of inner exception stack trace ---
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponseHelper(HttpWebRequest request)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponse(HttpWebRequest request)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.PerformHeadRequestHelper(Boolean getVersionInfo, Version& maximumSupportedVersion, Version& minimumSupportedVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider..ctor(DeploymentProviderContext providerContext, DeploymentBaseContext baseContext, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentManager.CreateObjectPrivate(DeploymentProviderContext providerContext, DeploymentBaseOptions baseOptions, DeploymentObject sourceObject, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentManager.CreateDestinationObject(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentObject sourceObject, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentObject.SyncTo(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentSyncOptions syncOptions)
January 16th 2017 12:24:38Error
   at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.Install(RunningDeployment deployment) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 63
January 16th 2017 12:24:38Error
   at Calamari.Deployment.ConventionProcessor.RunInstallConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 60
January 16th 2017 12:24:38Error
   at Calamari.Deployment.ConventionProcessor.RunConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 28
January 16th 2017 12:24:38Error
Running rollback conventions...
January 16th 2017 12:24:38Error
Microsoft.Web.Deployment.DeploymentDetailedException: Connected to the remote computer ("xxx.scm.xxx.xxx") using the specified process ("Web Management Service"), but could not verify the server's certificate. If you trust the server, connect again and allow untrusted certificates.  Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_CERTIFICATE_VALIDATION_FAILED. ---> System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
January 16th 2017 12:24:38Error
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
January 16th 2017 12:24:38Error
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
January 16th 2017 12:24:38Error
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
January 16th 2017 12:24:38Error
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
January 16th 2017 12:24:38Error
   at System.Net.ConnectStream.WriteHeaders(Boolean async)
January 16th 2017 12:24:38Error
   --- End of inner exception stack trace ---
January 16th 2017 12:24:38Error
   at System.Net.HttpWebRequest.GetResponse()
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponseHelper(HttpWebRequest request)
January 16th 2017 12:24:38Error
   --- End of inner exception stack trace ---
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponseHelper(HttpWebRequest request)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.GetHttpResponse(HttpWebRequest request)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider.PerformHeadRequestHelper(Boolean getVersionInfo, Version& maximumSupportedVersion, Version& minimumSupportedVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.AgentClientProvider..ctor(DeploymentProviderContext providerContext, DeploymentBaseContext baseContext, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentManager.CreateObjectPrivate(DeploymentProviderContext providerContext, DeploymentBaseOptions baseOptions, DeploymentObject sourceObject, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentManager.CreateDestinationObject(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentObject sourceObject, String serverVersion)
January 16th 2017 12:24:38Error
   at Microsoft.Web.Deployment.DeploymentObject.SyncTo(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentSyncOptions syncOptions)
January 16th 2017 12:24:38Error
   at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.Install(RunningDeployment deployment) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 63
January 16th 2017 12:24:38Error
   at Calamari.Deployment.ConventionProcessor.RunInstallConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 60
January 16th 2017 12:24:38Error
   at Calamari.Deployment.ConventionProcessor.RunConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 50
January 16th 2017 12:24:38Error
   at Calamari.Azure.Commands.DeployAzureWebCommand.Execute(String[] commandLineArguments) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Commands\DeployAzureWebCommand.cs:line 86
January 16th 2017 12:24:38Error
   at Calamari.Program.Execute(String[] args) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Program.cs:line 45

Any ideas would be greatly appreciated as this is becoming very frustrating.

Cheers,
James

I ended up adding the following code to a custom version of Calamari:

if (deployment.Variables.GetFlag("AllowUntrustedCertificate"))
{
    Log.Info("Bypassing SSL validation check");
    System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => true;
}

I put this just above the call to DeploymentManager.CreateObject in the AzureWebAppConvention.cs file (line 37 in the master branch).

I don’t really want to run with a custom version of Calamari long term, even though it’s only a small patch.

Hi James,

Thanks for getting in touch.

Glad to see you came up with a fix for this. We agree, and have made a GitHub issue here that you can track to be notified when this feature has been added. Thanks for the detailed information about where you’ve applied your fix. We’ll review this when implementing the feature.

Cheers
Mark