natemcmaster / LettuceEncrypt

Free, automatic HTTPS certificate generation for ASP.NET Core web apps
https://nuget.org/packages/LettuceEncrypt
Apache License 2.0
1.55k stars 152 forks source link

Allow delay before validating challenge #254

Closed h3rmanj closed 1 year ago

h3rmanj commented 2 years ago

Is your feature request related to a problem? Please describe. I am trying to deploy my application to OpenShift. I've set up routes correctly, but i keep getting this error;

[13:41:13 ERR] Failed to validate ownership of domainName 'xxx'. Reason: urn:ietf:params:acme:error:unauthorized: x.x.x.x: Invalid response from http://xxx/.well-known/acme-challenge/xxx: 503, Code = Forbidden

However, when I try the link myself I get a success status response. I think the library is calling ValidateChallengeAsync too quickly. While my app is ready to receive HTTP requests, OpenShift hasn't started to redirect traffic to the pod.

Describe the solution you'd like I'd like to be able to specify an option to delay the call of ValidateChallengeAsync in https://github.com/natemcmaster/LettuceEncrypt/blob/main/src/LettuceEncrypt/Internal/Http01DomainValidator.cs#L56 .

Something like

{
  "LettuceEncrypt": {
    "ValidationDelayMs": 5000
  }
}

And in the validator it would use the variable

_logger.LogTrace("Waiting for server to start accepting HTTP requests");
await _appStarted.Task;

if (_config.ValidationDelayMs > 0) {
  _logger.LogTrace("Waiting for user-specified time before validating");
  await Task.Delay(_config.ValidationDelayMs);
}

_logger.LogTrace("Requesting server to validate HTTP challenge");
await _client.ValidateChallengeAsync(httpChallenge);

Additional context I have manually tested by adding a await Task.Delay() and injected the nupkgs in my pipeline, and it works. I'll gladly make a PR, but I need some guidance of how to access the LettuceEncryptOptions from Http01DomainValidator.cs (or the TlsAlpn01 validator), as it's manually created by AcmeCertificateFactory, and not registered in DI.

h3rmanj commented 2 years ago

While delaying x amount could work in my scenario, it is a workaround and probably not an optimal solution to add to the library. I think a better solution would be to have a shared validation challenge store, which instances of my application could read and write to, no matter which one requested the domain validation.

After looking through the internals of this library, I think IHttpChallengeResponseStore might be a good place to hook into. It's internal right now, but making it public (and async) would allow consumers to implement their custom store, and also let it be implemented in the Azure integration.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

github-actions[bot] commented 1 year ago

Closing due to inactivity. If you are looking at this issue in the future and think it should be reopened, please make a commented here and mention natemcmaster so he sees the notification.