Return accurate error description for invalid authz limit (#3156)
Fixes #3144
This commit is contained in:
parent
9c9c6f3739
commit
e83480f86b
|
@ -0,0 +1,150 @@
|
|||
package ra
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
core "github.com/letsencrypt/boulder/core/proto"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sapb.StorageAuthorityClient = &mockInvalidAuthorizationsAuthority{}
|
||||
)
|
||||
|
||||
type mockInvalidAuthorizationsAuthority struct {
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetRegistration(ctx context.Context, in *sapb.RegistrationID, opts ...grpc.CallOption) (*core.Registration, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetRegistrationByKey(ctx context.Context, in *sapb.JSONWebKey, opts ...grpc.CallOption) (*core.Registration, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetAuthorization(ctx context.Context, in *sapb.AuthorizationID, opts ...grpc.CallOption) (*core.Authorization, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetPendingAuthorization(ctx context.Context, in *sapb.GetPendingAuthorizationRequest, opts ...grpc.CallOption) (*core.Authorization, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetValidAuthorizations(ctx context.Context, in *sapb.GetValidAuthorizationsRequest, opts ...grpc.CallOption) (*sapb.ValidAuthorizations, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetCertificate(ctx context.Context, in *sapb.Serial, opts ...grpc.CallOption) (*core.Certificate, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetCertificateStatus(ctx context.Context, in *sapb.Serial, opts ...grpc.CallOption) (*sapb.CertificateStatus, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountCertificatesRange(ctx context.Context, in *sapb.Range, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountCertificatesByNames(ctx context.Context, in *sapb.CountCertificatesByNamesRequest, opts ...grpc.CallOption) (*sapb.CountByNames, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountCertificatesByExactNames(ctx context.Context, in *sapb.CountCertificatesByNamesRequest, opts ...grpc.CallOption) (*sapb.CountByNames, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountRegistrationsByIP(ctx context.Context, in *sapb.CountRegistrationsByIPRequest, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountRegistrationsByIPRange(ctx context.Context, in *sapb.CountRegistrationsByIPRequest, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountPendingAuthorizations(ctx context.Context, in *sapb.RegistrationID, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
return &sapb.Count{
|
||||
Count: new(int64),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountInvalidAuthorizations(ctx context.Context, in *sapb.CountInvalidAuthorizationsRequest, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
count := int64(1)
|
||||
return &sapb.Count{
|
||||
Count: &count,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetSCTReceipt(ctx context.Context, in *sapb.GetSCTReceiptRequest, opts ...grpc.CallOption) (*sapb.SignedCertificateTimestamp, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) CountFQDNSets(ctx context.Context, in *sapb.CountFQDNSetsRequest, opts ...grpc.CallOption) (*sapb.Count, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) FQDNSetExists(ctx context.Context, in *sapb.FQDNSetExistsRequest, opts ...grpc.CallOption) (*sapb.Exists, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) NewRegistration(ctx context.Context, in *core.Registration, opts ...grpc.CallOption) (*core.Registration, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) UpdateRegistration(ctx context.Context, in *core.Registration, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) NewPendingAuthorization(ctx context.Context, in *core.Authorization, opts ...grpc.CallOption) (*core.Authorization, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) UpdatePendingAuthorization(ctx context.Context, in *core.Authorization, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) FinalizeAuthorization(ctx context.Context, in *core.Authorization, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) MarkCertificateRevoked(ctx context.Context, in *sapb.MarkCertificateRevokedRequest, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) AddCertificate(ctx context.Context, in *sapb.AddCertificateRequest, opts ...grpc.CallOption) (*sapb.AddCertificateResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) AddSCTReceipt(ctx context.Context, in *sapb.SignedCertificateTimestamp, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) RevokeAuthorizationsByDomain(ctx context.Context, in *sapb.RevokeAuthorizationsByDomainRequest, opts ...grpc.CallOption) (*sapb.RevokeAuthorizationsByDomainResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) DeactivateRegistration(ctx context.Context, in *sapb.RegistrationID, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) DeactivateAuthorization(ctx context.Context, in *sapb.AuthorizationID, opts ...grpc.CallOption) (*core.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) NewOrder(ctx context.Context, in *core.Order, opts ...grpc.CallOption) (*core.Order, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetOrder(ctx context.Context, in *sapb.OrderRequest, opts ...grpc.CallOption) (*core.Order, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) GetAuthorizations(ctx context.Context, in *sapb.GetAuthorizationsRequest, opts ...grpc.CallOption) (*sapb.Authorizations, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (sa *mockInvalidAuthorizationsAuthority) AddPendingAuthorizations(ctx context.Context, in *sapb.AddPendingAuthorizationsRequest, opts ...grpc.CallOption) (*sapb.AuthorizationIDs, error) {
|
||||
return nil, nil
|
||||
}
|
2
ra/ra.go
2
ra/ra.go
|
@ -461,7 +461,7 @@ func (ra *RegistrationAuthorityImpl) checkInvalidAuthorizationLimit(ctx context.
|
|||
noKey := ""
|
||||
if *count.Count >= int64(limit.GetThreshold(noKey, regID)) {
|
||||
ra.log.Info(fmt.Sprintf("Rate limit exceeded, InvalidAuthorizationsByRegID, regID: %d", regID))
|
||||
return berrors.RateLimitError("Too many invalid authorizations recently.")
|
||||
return berrors.RateLimitError("Too many failed authorizations recently.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
"github.com/letsencrypt/boulder/features"
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
sagrpc "github.com/letsencrypt/boulder/grpc"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/mocks"
|
||||
|
@ -1135,6 +1136,25 @@ func TestAuthzRateLimiting(t *testing.T) {
|
|||
test.AssertNotError(t, err, "NewAuthorization failed")
|
||||
}
|
||||
|
||||
func TestAuthzFailedRateLimiting(t *testing.T) {
|
||||
_, _, ra, _, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
|
||||
ra.rlPolicies = &dummyRateLimitConfig{
|
||||
InvalidAuthorizationsPerAccountPolicy: ratelimit.RateLimitPolicy{
|
||||
Threshold: 1,
|
||||
Window: cmd.ConfigDuration{Duration: 1 * time.Hour},
|
||||
},
|
||||
}
|
||||
|
||||
// override with our mockInvalidAuthorizationsAuthority for this specific test
|
||||
ra.SA = sagrpc.NewStorageAuthorityClient(&mockInvalidAuthorizationsAuthority{})
|
||||
// Should trigger rate limit
|
||||
_, err := ra.NewAuthorization(ctx, AuthzRequest, Registration.ID)
|
||||
test.AssertError(t, err, "NewAuthorization did not encounter expected rate limit error")
|
||||
test.AssertEquals(t, err.Error(), "Too many failed authorizations recently.")
|
||||
}
|
||||
|
||||
func TestDomainsForRateLimiting(t *testing.T) {
|
||||
domains, err := domainsForRateLimiting([]string{})
|
||||
test.AssertNotError(t, err, "failed on empty")
|
||||
|
|
Loading…
Reference in New Issue