Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
beautifulentropy committed Oct 23, 2024
1 parent e5edb70 commit b9748fe
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 20 deletions.
36 changes: 30 additions & 6 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,26 +179,50 @@ func RateLimitError(retryAfter time.Duration, msg string, args ...interface{}) e
}
}

func DuplicateCertificateError(retryAfter time.Duration, msg string, args ...interface{}) error {
func RegistrationsPerIPAddressError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/duplicate-certificate-limit/", args...),
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#new-registrations-per-ip-address", args...),
RetryAfter: retryAfter,
}
}

func FailedValidationError(retryAfter time.Duration, msg string, args ...interface{}) error {
func RegistrationsPerIPv6RangeError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/failed-validation-limit/", args...),
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#new-registrations-per-ipv6-range", args...),
RetryAfter: retryAfter,
}
}

func RegistrationsPerIPError(retryAfter time.Duration, msg string, args ...interface{}) error {
func NewOrdersPerAccountError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/too-many-registrations-for-this-ip/", args...),
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#new-orders-per-account", args...),
RetryAfter: retryAfter,
}
}

func CertificatesPerDomainError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#new-certificates-per-registered-domain", args...),
RetryAfter: retryAfter,
}
}

func CertificatesPerFQDNSetError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#new-certificates-per-exact-set-of-hostnames", args...),
RetryAfter: retryAfter,
}
}

func FailedAuthorizationsPerDomainPerAccountError(retryAfter time.Duration, msg string, args ...interface{}) error {
return &BoulderError{
Type: RateLimit,
Detail: fmt.Sprintf(msg+": see https://letsencrypt.org/docs/rate-limits/#authorization-failures-per-hostname-per-account", args...),
RetryAfter: retryAfter,
}
}
Expand Down
14 changes: 7 additions & 7 deletions ra/ra.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ func (ra *RegistrationAuthorityImpl) checkRegistrationIPLimit(ctx context.Contex

threshold, overrideKey := limit.GetThreshold(ip.String(), noRegistrationID)
if count.Count >= threshold {
return berrors.RegistrationsPerIPError(0, "too many registrations for this IP")
return berrors.RegistrationsPerIPAddressError(0, "too many registrations for this IP")
}
if overrideKey != "" {
// We do not support overrides for the NewRegistrationsPerIPRange limit.
Expand Down Expand Up @@ -598,7 +598,7 @@ func (ra *RegistrationAuthorityImpl) checkInvalidAuthorizationLimit(ctx context.
threshold, overrideKey := limit.GetThreshold(noKey, regID)
if count.Count >= threshold {
ra.log.Infof("Rate limit exceeded, InvalidAuthorizationsByRegID, regID: %d", regID)
return berrors.FailedValidationError(0, "too many failed authorizations recently")
return berrors.FailedAuthorizationsPerDomainPerAccountError(0, "too many failed authorizations recently")
}
if overrideKey != "" {
utilization := float64(count.Count) / float64(threshold)
Expand Down Expand Up @@ -626,7 +626,7 @@ func (ra *RegistrationAuthorityImpl) checkNewOrdersPerAccountLimit(ctx context.C
noKey := ""
threshold, overrideKey := limit.GetThreshold(noKey, acctID)
if count.Count >= threshold {
return berrors.RateLimitError(0, "too many new orders recently")
return berrors.NewOrdersPerAccountError(0, "too many new orders recently")
}
if overrideKey != "" {
utilization := float64(count.Count+1) / float64(threshold)
Expand Down Expand Up @@ -1473,12 +1473,12 @@ func (ra *RegistrationAuthorityImpl) checkCertificatesPerNameLimit(ctx context.C
for _, name := range namesOutOfLimit {
subErrors = append(subErrors, berrors.SubBoulderError{
Identifier: identifier.NewDNS(name),
BoulderError: berrors.RateLimitError(retryAfter, "too many certificates already issued. Retry after %s", retryString).(*berrors.BoulderError),
BoulderError: berrors.NewOrdersPerAccountError(retryAfter, "too many certificates already issued. Retry after %s", retryString).(*berrors.BoulderError),
})
}
return berrors.RateLimitError(retryAfter, "too many certificates already issued for multiple names (%q and %d others). Retry after %s", namesOutOfLimit[0], len(namesOutOfLimit), retryString).(*berrors.BoulderError).WithSubErrors(subErrors)
return berrors.NewOrdersPerAccountError(retryAfter, "too many certificates already issued for multiple names (%q and %d others). Retry after %s", namesOutOfLimit[0], len(namesOutOfLimit), retryString).(*berrors.BoulderError).WithSubErrors(subErrors)
}
return berrors.RateLimitError(retryAfter, "too many certificates already issued for %q. Retry after %s", namesOutOfLimit[0], retryString)
return berrors.NewOrdersPerAccountError(retryAfter, "too many certificates already issued for %q. Retry after %s", namesOutOfLimit[0], retryString)
}

return nil
Expand Down Expand Up @@ -1535,7 +1535,7 @@ func (ra *RegistrationAuthorityImpl) checkCertificatesPerFQDNSetLimit(ctx contex
}
retryTime := prevIssuances.Timestamps[0].AsTime().Add(time.Duration(nsPerToken))
retryAfter := retryTime.Sub(now)
return berrors.DuplicateCertificateError(
return berrors.CertificatesPerFQDNSetError(
retryAfter,
"too many certificates (%d) already issued for this exact set of domains in the last %.0f hours: %s, retry after %s",
threshold, limit.Window.Duration.Hours(), strings.Join(names, ","), retryTime.Format(time.RFC3339),
Expand Down
14 changes: 7 additions & 7 deletions ratelimits/limiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (d *Decision) Result(now time.Time) error {

switch d.transaction.limit.name {
case NewRegistrationsPerIPAddress:
return berrors.RegistrationsPerIPError(
return berrors.RegistrationsPerIPAddressError(
retryAfter,
"too many new registrations (%d) from this IP address in the last %s, retry after %s",
d.transaction.limit.Burst,
Expand All @@ -121,15 +121,15 @@ func (d *Decision) Result(now time.Time) error {
)

case NewRegistrationsPerIPv6Range:
return berrors.RateLimitError(
return berrors.RegistrationsPerIPv6RangeError(
retryAfter,
"too many new registrations (%d) from this /48 block of IPv6 addresses in the last %s, retry after %s",
"too many new registrations (%d) from this /48 subnet of IPv6 addresses in the last %s, retry after %s",
d.transaction.limit.Burst,
d.transaction.limit.Period.Duration,
retryAfterTs,
)
case NewOrdersPerAccount:
return berrors.RateLimitError(
return berrors.NewOrdersPerAccountError(
retryAfter,
"too many new orders (%d) from this account in the last %s, retry after %s",
d.transaction.limit.Burst,
Expand All @@ -144,7 +144,7 @@ func (d *Decision) Result(now time.Time) error {
return berrors.InternalServerError("unrecognized bucket key while generating error")
}
domain := d.transaction.bucketKey[idx+1:]
return berrors.FailedValidationError(
return berrors.FailedAuthorizationsPerDomainPerAccountError(
retryAfter,
"too many failed authorizations (%d) for %q in the last %s, retry after %s",
d.transaction.limit.Burst,
Expand All @@ -160,7 +160,7 @@ func (d *Decision) Result(now time.Time) error {
return berrors.InternalServerError("unrecognized bucket key while generating error")
}
domain := d.transaction.bucketKey[idx+1:]
return berrors.RateLimitError(
return berrors.CertificatesPerDomainError(
retryAfter,
"too many certificates (%d) already issued for %q in the last %s, retry after %s",
d.transaction.limit.Burst,
Expand All @@ -170,7 +170,7 @@ func (d *Decision) Result(now time.Time) error {
)

case CertificatesPerFQDNSet:
return berrors.DuplicateCertificateError(
return berrors.CertificatesPerFQDNSetError(
retryAfter,
"too many certificates (%d) already issued for this exact set of domains in the last %s, retry after %s",
d.transaction.limit.Burst,
Expand Down

0 comments on commit b9748fe

Please sign in to comment.