...

Source file src/github.com/letsencrypt/boulder/ratelimit/rate-limits.go

Documentation: github.com/letsencrypt/boulder/ratelimit

     1  package ratelimit
     2  
     3  import (
     4  	"strconv"
     5  	"time"
     6  
     7  	"github.com/letsencrypt/boulder/config"
     8  	"github.com/letsencrypt/boulder/strictyaml"
     9  )
    10  
    11  const (
    12  	// CertificatesPerName is the name of the CertificatesPerName rate limit
    13  	// when referenced in metric labels.
    14  	CertificatesPerName = "certificates_per_domain_per_account"
    15  
    16  	// RegistrationsPerIP is the name of the RegistrationsPerIP rate limit when
    17  	// referenced in metric labels.
    18  	RegistrationsPerIP = "registrations_per_ip"
    19  
    20  	// RegistrationsPerIPRange is the name of the RegistrationsPerIPRange rate
    21  	// limit when referenced in metric labels.
    22  	RegistrationsPerIPRange = "registrations_per_ipv6_range"
    23  
    24  	// PendingAuthorizationsPerAccount is the name of the
    25  	// PendingAuthorizationsPerAccount rate limit when referenced in metric
    26  	// labels.
    27  	PendingAuthorizationsPerAccount = "pending_authorizations_per_account"
    28  
    29  	// InvalidAuthorizationsPerAccount is the name of the
    30  	// InvalidAuthorizationsPerAccount rate limit when referenced in metric
    31  	// labels.
    32  	InvalidAuthorizationsPerAccount = "failed_authorizations_per_account"
    33  
    34  	// CertificatesPerFQDNSet is the name of the CertificatesPerFQDNSet rate
    35  	// limit when referenced in metric labels.
    36  	CertificatesPerFQDNSet = "certificates_per_fqdn_set_per_account"
    37  
    38  	// CertificatesPerFQDNSetFast is the name of the CertificatesPerFQDNSetFast
    39  	// rate limit when referenced in metric labels.
    40  	CertificatesPerFQDNSetFast = "certificates_per_fqdn_set_per_account_fast"
    41  
    42  	// NewOrdersPerAccount is the name of the NewOrdersPerAccount rate limit
    43  	// when referenced in metric labels.
    44  	NewOrdersPerAccount = "new_orders_per_account"
    45  )
    46  
    47  // Limits is defined to allow mock implementations be provided during unit
    48  // testing
    49  type Limits interface {
    50  	CertificatesPerName() RateLimitPolicy
    51  	RegistrationsPerIP() RateLimitPolicy
    52  	RegistrationsPerIPRange() RateLimitPolicy
    53  	PendingAuthorizationsPerAccount() RateLimitPolicy
    54  	InvalidAuthorizationsPerAccount() RateLimitPolicy
    55  	CertificatesPerFQDNSet() RateLimitPolicy
    56  	CertificatesPerFQDNSetFast() RateLimitPolicy
    57  	NewOrdersPerAccount() RateLimitPolicy
    58  	LoadPolicies(contents []byte) error
    59  }
    60  
    61  // limitsImpl is an unexported implementation of the Limits interface. It acts
    62  // as a container for a rateLimitConfig.
    63  type limitsImpl struct {
    64  	rlPolicy *rateLimitConfig
    65  }
    66  
    67  func (r *limitsImpl) CertificatesPerName() RateLimitPolicy {
    68  	if r.rlPolicy == nil {
    69  		return RateLimitPolicy{}
    70  	}
    71  	return r.rlPolicy.CertificatesPerName
    72  }
    73  
    74  func (r *limitsImpl) RegistrationsPerIP() RateLimitPolicy {
    75  	if r.rlPolicy == nil {
    76  		return RateLimitPolicy{}
    77  	}
    78  	return r.rlPolicy.RegistrationsPerIP
    79  }
    80  
    81  func (r *limitsImpl) RegistrationsPerIPRange() RateLimitPolicy {
    82  	if r.rlPolicy == nil {
    83  		return RateLimitPolicy{}
    84  	}
    85  	return r.rlPolicy.RegistrationsPerIPRange
    86  }
    87  
    88  func (r *limitsImpl) PendingAuthorizationsPerAccount() RateLimitPolicy {
    89  	if r.rlPolicy == nil {
    90  		return RateLimitPolicy{}
    91  	}
    92  	return r.rlPolicy.PendingAuthorizationsPerAccount
    93  }
    94  
    95  func (r *limitsImpl) InvalidAuthorizationsPerAccount() RateLimitPolicy {
    96  	if r.rlPolicy == nil {
    97  		return RateLimitPolicy{}
    98  	}
    99  	return r.rlPolicy.InvalidAuthorizationsPerAccount
   100  }
   101  
   102  func (r *limitsImpl) CertificatesPerFQDNSet() RateLimitPolicy {
   103  	if r.rlPolicy == nil {
   104  		return RateLimitPolicy{}
   105  	}
   106  	return r.rlPolicy.CertificatesPerFQDNSet
   107  }
   108  
   109  func (r *limitsImpl) CertificatesPerFQDNSetFast() RateLimitPolicy {
   110  	if r.rlPolicy == nil {
   111  		return RateLimitPolicy{}
   112  	}
   113  	return r.rlPolicy.CertificatesPerFQDNSetFast
   114  }
   115  
   116  func (r *limitsImpl) NewOrdersPerAccount() RateLimitPolicy {
   117  	if r.rlPolicy == nil {
   118  		return RateLimitPolicy{}
   119  	}
   120  	return r.rlPolicy.NewOrdersPerAccount
   121  }
   122  
   123  // LoadPolicies loads various rate limiting policies from a byte array of
   124  // YAML configuration.
   125  func (r *limitsImpl) LoadPolicies(contents []byte) error {
   126  	var newPolicy rateLimitConfig
   127  	err := strictyaml.Unmarshal(contents, &newPolicy)
   128  	if err != nil {
   129  		return err
   130  	}
   131  	r.rlPolicy = &newPolicy
   132  	return nil
   133  }
   134  
   135  func New() Limits {
   136  	return &limitsImpl{}
   137  }
   138  
   139  // rateLimitConfig contains all application layer rate limiting policies. It is
   140  // unexported and clients are expected to use the exported container struct
   141  type rateLimitConfig struct {
   142  	// Number of certificates that can be extant containing any given name.
   143  	// These are counted by "base domain" aka eTLD+1, so any entries in the
   144  	// overrides section must be an eTLD+1 according to the publicsuffix package.
   145  	CertificatesPerName RateLimitPolicy `yaml:"certificatesPerName"`
   146  	// Number of registrations that can be created per IP.
   147  	// Note: Since this is checked before a registration is created, setting a
   148  	// RegistrationOverride on it has no effect.
   149  	RegistrationsPerIP RateLimitPolicy `yaml:"registrationsPerIP"`
   150  	// Number of registrations that can be created per fuzzy IP range. Unlike
   151  	// RegistrationsPerIP this will apply to a /48 for IPv6 addresses to help curb
   152  	// abuse from easily obtained IPv6 ranges.
   153  	// Note: Like RegistrationsPerIP, setting a RegistrationOverride has no
   154  	// effect here.
   155  	RegistrationsPerIPRange RateLimitPolicy `yaml:"registrationsPerIPRange"`
   156  	// Number of pending authorizations that can exist per account. Overrides by
   157  	// key are not applied, but overrides by registration are.
   158  	PendingAuthorizationsPerAccount RateLimitPolicy `yaml:"pendingAuthorizationsPerAccount"`
   159  	// Number of invalid authorizations that can be failed per account within the
   160  	// given window. Overrides by key are not applied, but overrides by registration are.
   161  	// Note that this limit is actually "per account, per hostname," but that
   162  	// is too long for the variable name.
   163  	InvalidAuthorizationsPerAccount RateLimitPolicy `yaml:"invalidAuthorizationsPerAccount"`
   164  	// Number of new orders that can be created per account within the given
   165  	// window. Overrides by key are not applied, but overrides by registration are.
   166  	NewOrdersPerAccount RateLimitPolicy `yaml:"newOrdersPerAccount"`
   167  	// Number of certificates that can be extant containing a specific set
   168  	// of DNS names.
   169  	CertificatesPerFQDNSet RateLimitPolicy `yaml:"certificatesPerFQDNSet"`
   170  	// Same as above, but intended to both trigger and reset faster (i.e. a
   171  	// lower threshold and smaller window), so that clients don't have to wait
   172  	// a long time after a small burst of accidental duplicate issuance.
   173  	CertificatesPerFQDNSetFast RateLimitPolicy `yaml:"certificatesPerFQDNSetFast"`
   174  }
   175  
   176  // RateLimitPolicy describes a general limiting policy
   177  type RateLimitPolicy struct {
   178  	// How long to count items for
   179  	Window config.Duration `yaml:"window"`
   180  	// The max number of items that can be present before triggering the rate
   181  	// limit. Zero means "no limit."
   182  	Threshold int64 `yaml:"threshold"`
   183  	// A per-key override setting different limits than the default (higher or lower).
   184  	// The key is defined on a per-limit basis and should match the key it counts on.
   185  	// For instance, a rate limit on the number of certificates per name uses name as
   186  	// a key, while a rate limit on the number of registrations per IP subnet would
   187  	// use subnet as a key. Note that a zero entry in the overrides map does not
   188  	// mean "no limit," it means a limit of zero. An entry of -1 means
   189  	// "no limit", only for the pending authorizations rate limit.
   190  	Overrides map[string]int64 `yaml:"overrides"`
   191  	// A per-registration override setting. This can be used, e.g. if there are
   192  	// hosting providers that we would like to grant a higher rate of issuance
   193  	// than the default. If both key-based and registration-based overrides are
   194  	// available, whichever is larger takes priority. Note that a zero entry in
   195  	// the overrides map does not mean "no limit", it means a limit of zero.
   196  	RegistrationOverrides map[int64]int64 `yaml:"registrationOverrides"`
   197  }
   198  
   199  // Enabled returns true iff the RateLimitPolicy is enabled.
   200  func (rlp *RateLimitPolicy) Enabled() bool {
   201  	return rlp.Threshold != 0
   202  }
   203  
   204  // GetThreshold returns the threshold for this rate limit and the override
   205  // Id/Key if that threshold is the result of an override for the default limit,
   206  // empty-string otherwise. The threshold returned takes into account any
   207  // overrides for `key` or `regID`. If both `key` and `regID` have an override
   208  // the largest of the two will be used.
   209  func (rlp *RateLimitPolicy) GetThreshold(key string, regID int64) (int64, string) {
   210  	regOverride, regOverrideExists := rlp.RegistrationOverrides[regID]
   211  	keyOverride, keyOverrideExists := rlp.Overrides[key]
   212  
   213  	if regOverrideExists && !keyOverrideExists {
   214  		// If there is a regOverride and no keyOverride use the regOverride
   215  		return regOverride, strconv.FormatInt(regID, 10)
   216  	} else if !regOverrideExists && keyOverrideExists {
   217  		// If there is a keyOverride and no regOverride use the keyOverride
   218  		return keyOverride, key
   219  	} else if regOverrideExists && keyOverrideExists {
   220  		// If there is both a regOverride and a keyOverride use whichever is larger.
   221  		if regOverride > keyOverride {
   222  			return regOverride, strconv.FormatInt(regID, 10)
   223  		} else {
   224  			return keyOverride, key
   225  		}
   226  	}
   227  
   228  	// Otherwise there was no regOverride and no keyOverride, use the base
   229  	// Threshold
   230  	return rlp.Threshold, ""
   231  }
   232  
   233  // WindowBegin returns the time that a RateLimitPolicy's window begins, given a
   234  // particular end time (typically the current time).
   235  func (rlp *RateLimitPolicy) WindowBegin(windowEnd time.Time) time.Time {
   236  	return windowEnd.Add(-1 * rlp.Window.Duration)
   237  }
   238  

View as plain text