sjkp / letsencrypt-siteextension

Azure Web App Site Extension for easy installation and configuration of Let's Encrypt issued SSL certifcates for custom domain names.
744 stars 76 forks source link

Auto Renew Fails #345

Open mmsigi opened 4 years ago

mmsigi commented 4 years ago

I have the Let's Encrypt extension (v1.0.4) installed on an Azure Web App. Manually renewing a certificate works, but the auto renew always fails.

At first, it seemed like it may have been due to a second slot we use, because the extension seemed to be getting moved around when we swapped slots. I installed the Lets Encrypt extension on the secondary slot, and added a Configuration setting of "WEBJOBS_STOPPED" with value "1", but that does not seem to be helping.

The connection strings are pointed at a "StorageV2 (general purpose v2)" storage account.

The two errors I could find are included below. Any help would be greatly appreciated.

Error from WebJobs:

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Functions.RenewCertificate ---> System.NullReferenceException : Object reference not set to an instance of an object. at async LetsEncrypt.Azure.Core.CertificateManager.RenewCertificate(Boolean skipInstallCertificate,Int32 renewXNumberOfDaysBeforeExpiration) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 158 at async LetsEncrypt.SiteExtension.Functions.RenewCertificate(TimerInfo timerInfo) at D:\a\1\s\LetsEncrypt.SiteExtension.WebJob\Functions.cs : 68 at async Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker2.InvokeAsync[TReflected,TReturnType](TReflected instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.InvokeAsync[TReflected,TReturnValue](Object instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker,ParameterHelper parameterHelper,CancellationTokenSource timeoutTokenSource,CancellationTokenSource functionCancellationTokenSource,Boolean throwOnTimeout,TimeSpan timerInterval,IFunctionInstance instance) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance,ParameterHelper parameterHelper,TraceWriter traceWriter,CancellationTokenSource functionCancellationTokenSource) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) End of inner exception at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance,CancellationToken cancellationToken)

Error from Swagger:

LetsEncrypt.SiteExtension - Invalid. {"schemaValidationMessages":[{"level":"error","message":"Can't read from file https://*****/letsencrypt/swagger/docs/2017-09-01"}]}

Marcel0024 commented 4 years ago

I just notice we are also having this problem. No renewals are working. Also running on v1.0.4

pritch90 commented 4 years ago

We are also having this issue on version 1.0.4.

Great extension, thanks for all the hard work on it!

Marcel0024 commented 4 years ago

Seems my case the connectionStrings AzureWebJobsDashboard and AzureWebJobs simply went missing.

image

Readding them seems to have done the trick. I have no idea how they disappeared

mmsigi commented 4 years ago

I have both of those connection strings and the auto renew still fails.

Any update on this?

alexmaie commented 4 years ago

First of all, good job on this extension :)

Same problem for me. after installing 1.0.4 on a brand new webapp. The webjob is trying to generate a certificate for a subdomain.

Error from webjob:

Exception while executing function: Functions.RenewCertificate Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Functions.RenewCertificate ---> System.NullReferenceException : Object reference not set to an instance of an object. at Certes.AcmeContext.<>c.b__19_0(Directory d) at async Certes.IAcmeContextExtensions.GetResourceUri(IAcmeContext context,Func2 getter,Boolean optional) at async Certes.AcmeContext.NewOrder(IList1 identifiers,Nullable1 notBefore,Nullable1 notAfter) at async LetsEncrypt.Azure.Core.Services.AcmeService.RequestCertificate() at D:\a\1\s\LetsEncrypt.SiteExtension.Core\Services\AcmeService.cs : 53 at async LetsEncrypt.Azure.Core.CertificateManager.RequestInternalAsync(IAcmeConfig config) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 206 at async LetsEncrypt.Azure.Core.CertificateManager.RequestAndInstallInternalAsync(IAcmeConfig config) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 230 at async LetsEncrypt.Azure.Core.CertificateManager.RenewCertificate(Boolean skipInstallCertificate,Int32 renewXNumberOfDaysBeforeExpiration) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 172 at async LetsEncrypt.SiteExtension.Functions.RenewCertificate(TimerInfo timerInfo) at D:\a\1\s\LetsEncrypt.SiteExtension.WebJob\Functions.cs : 68 at async Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker2.InvokeAsync[TReflected,TReturnType](TReflected instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.InvokeAsync[TReflected,TReturnValue](Object instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker,ParameterHelper parameterHelper,CancellationTokenSource timeoutTokenSource,CancellationTokenSource functionCancellationTokenSource,Boolean throwOnTimeout,TimeSpan timerInterval,IFunctionInstance instance) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance,ParameterHelper parameterHelper,TraceWriter traceWriter,CancellationTokenSource functionCancellationTokenSource) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) End of inner exception

jeremytbrun commented 4 years ago

Same issue here as well. Running v 1.0.5 of the extension and getting the following error in the RenewCertificate WebJob.

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Functions.RenewCertificate ---> System.NullReferenceException : Object reference not set to an instance of an object. at Certes.AcmeContext.<>c.b__19_0(Directory d) at async Certes.IAcmeContextExtensions.GetResourceUri(IAcmeContext context,Func2 getter,Boolean optional) at async Certes.AcmeContext.NewOrder(IList1 identifiers,Nullable1 notBefore,Nullable1 notAfter) at async LetsEncrypt.Azure.Core.Services.AcmeService.RequestCertificate() at D:\a\1\s\LetsEncrypt.SiteExtension.Core\Services\AcmeService.cs : 53 at async LetsEncrypt.Azure.Core.CertificateManager.RequestInternalAsync(IAcmeConfig config) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 206 at async LetsEncrypt.Azure.Core.CertificateManager.RequestAndInstallInternalAsync(IAcmeConfig config) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 230 at async LetsEncrypt.Azure.Core.CertificateManager.RenewCertificate(Boolean skipInstallCertificate,Int32 renewXNumberOfDaysBeforeExpiration) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 172 at async LetsEncrypt.SiteExtension.Functions.RenewCertificate(TimerInfo timerInfo) at D:\a\1\s\LetsEncrypt.SiteExtension.WebJob\Functions.cs : 68 at async Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker2.InvokeAsync[TReflected,TReturnType](TReflected instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.InvokeAsync[TReflected,TReturnValue](Object instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker,ParameterHelper parameterHelper,CancellationTokenSource timeoutTokenSource,CancellationTokenSource functionCancellationTokenSource,Boolean throwOnTimeout,TimeSpan timerInterval,IFunctionInstance instance) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance,ParameterHelper parameterHelper,TraceWriter traceWriter,CancellationTokenSource functionCancellationTokenSource) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) End of inner exception at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance,CancellationToken cancellationToken)

jeremytbrun commented 4 years ago

Interestingly I found that if I changed my letsencrypt:AcmeBaseUri app config property to "https://acme-v02.api.letsencrypt.org/directory" instead of " https://acme-v02.api.letsencrypt.org" then it seemed to start working. Is anyone else able to test this?

alexmaie commented 4 years ago

We have added in our app settings "https://acme-v02.api.letsencrypt.org/directory" and it looks like the webjob is working properly now

mmsigi commented 4 years ago

I don't even have the setting "letsencrypt:AcmeBaseUri." Here are the ones I have:

letsencrypt:ClientId letsencrypt:ClientSecret letsencrypt:ResourceGroupName letsencrypt:ServicePlanResourceGroupName letsencrypt:SiteSlot letsencrypt:SubscriptionId letsencrypt:Tenant letsencrypt:UseIPBasedSSL

Can you tell me if any other settings are missing, and what values you're using for them? In the meantime, I'll add "letsencrypt:AcmeBaseUri" to see if that helps.

jeremytbrun commented 4 years ago

I would expect that some (perhaps many) of the settings are optional and have defaults. The AcmeBaseUri property may be one of them. Here is what I have configured though.

image

Here is an example ARM template that has most, if not all, of the config settings.

https://github.com/sjkp/letsencrypt-siteextension/blob/master/LetsEncrypt.ResourceGroup/Templates/azuredeploy.json

And here is a link to the README that talks about each one of them.

https://github.com/sjkp/letsencrypt-siteextension#fully-automated-installation

Interestingly enough since I last looked at it the repo author updated the AcmeBaseUri documenation to the Acme v2 API endpoints AND added the "/directory" part.

The change was made on October 9.

https://github.com/sjkp/letsencrypt-siteextension/commit/6268ad22fe896fde9a34ccec9c7a4d96948dbab1#diff-04c6e90faac2675aa89e2176d2eec7d8

Marcel0024 commented 4 years ago

@jeremytbrun

That's only the README.md

The real change was on oct 12: https://github.com/sjkp/letsencrypt-siteextension/commit/65aea2c9d1e8f2dbe99abf738d4855789031bc84#diff-d6035c681564b3359fd24aa3ea500d9f

These are .json tho. I wonder we should have seen the renewals errors earlier then? When did you install the extension? Is upgrading not updating the .json files? Or did Let's Encrypt change something on their side?

sjkp commented 4 years ago

The october update moved the extension to the ACME V2 endpoints from the V1 endpoints, that are now deprecated, as part of that change i forgot to put the correct letsencrypt:AcmeBaseUri in the readme at first. The correct url should be: https://acme-v02.api.letsencrypt.org/directory if you are targeting the production environment. If you leave it blank/or not set at all it should also be fine, as the extension then uses whatever you picked the last time you did a manual config. However if you had this app setting set from an earlier version of the of the extension pointing to v1, then it will cause problems.

The problem encounter originally by @mmsigi however is not related to the letsencrypt:AcmeBaseUri , it fails earlier. I think that error is due to a missing email. Could you try to set the letsencrypt:Email setting?

Just for clarification, normally it shouldn't be necessary as the web job reads a file that gets written when you do the manual installation, but if that file for some reason has been deleted (e.g. when swapping), then the web job will fail, with the nullreference exception that you reported, obviously that is a bug that I should handled better.

tiagonmas commented 3 years ago

Also on v 1.0.5 and have the NullReferenceException when webjob tries renewal.

Configuration Settings:

Exception: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Functions.RenewCertificate ---> System.NullReferenceException : Object reference not set to an instance of an object. at async LetsEncrypt.Azure.Core.CertificateManager.RenewCertificate(Boolean skipInstallCertificate,Int32 renewXNumberOfDaysBeforeExpiration) at D:\a\1\s\LetsEncrypt.SiteExtension.Core\CertificateManager.cs : 158 at async LetsEncrypt.SiteExtension.Functions.RenewCertificate(TimerInfo timerInfo) at D:\a\1\s\LetsEncrypt.SiteExtension.WebJob\Functions.cs : 68 at async Microsoft.Azure.WebJobs.Host.Executors.VoidTaskMethodInvoker2.InvokeAsync[TReflected,TReturnType](TReflected instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.InvokeAsync[TReflected,TReturnValue](Object instance,Object[] arguments) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker,ParameterHelper parameterHelper,CancellationTokenSource timeoutTokenSource,CancellationTokenSource functionCancellationTokenSource,Boolean throwOnTimeout,TimeSpan timerInterval,IFunctionInstance instance) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstance instance,ParameterHelper parameterHelper,TraceWriter traceWriter,CancellationTokenSource functionCancellationTokenSource) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) End of inner exception at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(??) at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance,CancellationToken cancellationToken)

tiagonmas commented 3 years ago

Adding letsencrypt:Email setting in app configuration seemed to have solved the exception :)