...
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
13
14 CertificatesPerName = "certificates_per_domain_per_account"
15
16
17
18 RegistrationsPerIP = "registrations_per_ip"
19
20
21
22 RegistrationsPerIPRange = "registrations_per_ipv6_range"
23
24
25
26
27 PendingAuthorizationsPerAccount = "pending_authorizations_per_account"
28
29
30
31
32 InvalidAuthorizationsPerAccount = "failed_authorizations_per_account"
33
34
35
36 CertificatesPerFQDNSet = "certificates_per_fqdn_set_per_account"
37
38
39
40 CertificatesPerFQDNSetFast = "certificates_per_fqdn_set_per_account_fast"
41
42
43
44 NewOrdersPerAccount = "new_orders_per_account"
45 )
46
47
48
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
62
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
124
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
140
141 type rateLimitConfig struct {
142
143
144
145 CertificatesPerName RateLimitPolicy `yaml:"certificatesPerName"`
146
147
148
149 RegistrationsPerIP RateLimitPolicy `yaml:"registrationsPerIP"`
150
151
152
153
154
155 RegistrationsPerIPRange RateLimitPolicy `yaml:"registrationsPerIPRange"`
156
157
158 PendingAuthorizationsPerAccount RateLimitPolicy `yaml:"pendingAuthorizationsPerAccount"`
159
160
161
162
163 InvalidAuthorizationsPerAccount RateLimitPolicy `yaml:"invalidAuthorizationsPerAccount"`
164
165
166 NewOrdersPerAccount RateLimitPolicy `yaml:"newOrdersPerAccount"`
167
168
169 CertificatesPerFQDNSet RateLimitPolicy `yaml:"certificatesPerFQDNSet"`
170
171
172
173 CertificatesPerFQDNSetFast RateLimitPolicy `yaml:"certificatesPerFQDNSetFast"`
174 }
175
176
177 type RateLimitPolicy struct {
178
179 Window config.Duration `yaml:"window"`
180
181
182 Threshold int64 `yaml:"threshold"`
183
184
185
186
187
188
189
190 Overrides map[string]int64 `yaml:"overrides"`
191
192
193
194
195
196 RegistrationOverrides map[int64]int64 `yaml:"registrationOverrides"`
197 }
198
199
200 func (rlp *RateLimitPolicy) Enabled() bool {
201 return rlp.Threshold != 0
202 }
203
204
205
206
207
208
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
215 return regOverride, strconv.FormatInt(regID, 10)
216 } else if !regOverrideExists && keyOverrideExists {
217
218 return keyOverride, key
219 } else if regOverrideExists && keyOverrideExists {
220
221 if regOverride > keyOverride {
222 return regOverride, strconv.FormatInt(regID, 10)
223 } else {
224 return keyOverride, key
225 }
226 }
227
228
229
230 return rlp.Threshold, ""
231 }
232
233
234
235 func (rlp *RateLimitPolicy) WindowBegin(windowEnd time.Time) time.Time {
236 return windowEnd.Add(-1 * rlp.Window.Duration)
237 }
238
View as plain text