Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ run:

`PEBBLE_VA_ALWAYS_VALID=1 pebble`

### Just-in-Time Validation

When creating a new order, Pebble MAY perform an immediate DNS lookup
for _validation-persist TXT records at the Validation Domain Name
corresponding to the requested domain identifier. If this check succeed,
Auth for that domain will move to valid state directly without client
request asking to do so.

To make pebble to try dns-persist-01 challenge at order creation time:

`PEBBLE_WFE_JITVALIDATION=1 pebble`

### Invalid Anti-Replay Nonce Errors

The `urn:ietf:params:acme:error:badNonce` error type is meant to be retry-able.
Expand Down
21 changes: 21 additions & 0 deletions va/va.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,27 @@ func (va VAImpl) ValidateChallenge(ident acme.Identifier, chal *core.Challenge,
va.tasks <- task
}

func (va VAImpl) JITValidateChallenge(ident acme.Identifier, chal *core.Challenge, acct *core.Account, acctURL string, wildcard bool) {
task := &vaTask{
Identifier: ident,
Challenge: chal,
Account: acct,
AccountURL: acctURL,
Wildcard: wildcard,
}
va.log.Printf("try Just-in-time validation for identifier %s", ident)
result := va.validateDNSPersist01(task)
va.log.Print(result)
if va.alwaysValid || result.Error == nil {
va.log.Printf("JIT validation succied for identifier %s", ident)
va.setAuthzValid(chal.Authz, chal)
} else {
chal.Lock()
chal.Validated = ""
chal.Unlock()
}
}

func (va VAImpl) processTasks() {
for task := range va.tasks {
go va.process(task)
Expand Down
24 changes: 24 additions & 0 deletions wfe/wfe.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ const (
// valid authorization exists or not for each identifier in an order.
authzReuseEnvVar = "PEBBLE_AUTHZREUSE"

// jitEnvVar defines an environment variable name used to wether if wfe
// should ask VA if there is valid dns-persist-01 record at order creation time
jitEnvVar = "PEBBLE_WFE_JITVALIDATION"

// The default value when PEBBLE_WFE_AUTHZREUSE is not set, how often to try
// and reuse valid authorizations.
defaultAuthzReuse = 50
Expand Down Expand Up @@ -173,6 +177,7 @@ type WebFrontEndImpl struct {
caaIdentities []string
strict bool
requireEAB bool
jitValidation bool
retryAfterAuthz int
retryAfterOrder int
}
Expand Down Expand Up @@ -218,6 +223,14 @@ func New(
log.Printf("Configured to attempt authz reuse for each identifier %d%% of the time",
authzReusePercent)

jitvalidation := false
jitvar := os.Getenv(jitEnvVar)
switch jitvar {
case "1", "true", "True", "TRUE":
jitvalidation = true
log.Printf("enabling JIT validation requests. WFE will request dns-persist-01 lookup at order creation time")
}

// Read the number of orders per page that should be returned.
ordersPerPageVal := os.Getenv(ordersPerPageEnvVar)
var ordersPerPage int
Expand All @@ -241,6 +254,7 @@ func New(
ordersPerPage: ordersPerPage,
va: va,
ca: ca,
jitValidation: jitvalidation,
strict: strict,
requireEAB: requireEAB,
retryAfterAuthz: retryAfterAuthz,
Expand Down Expand Up @@ -1584,6 +1598,16 @@ func (wfe *WebFrontEndImpl) makeAuthorizations(order *core.Order, request *http.
if err != nil {
return err
}

wfe.log.Print("trying jit validation for ", ident)
// try dns-persist-01 JIT validation
for _, chal := range authz.Challenges {
if chal.Type == acme.ChallengeDNSPersist01 {
wfe.va.JITValidateChallenge(ident, chal, nil, order.AccountID, authz.Wildcard)
// dns-persist-01 validation doesn't care about account key so we can leave it emmpty
}
}

wfe.log.Printf("There are now %d authorizations in the db\n", count)
}

Expand Down
Loading