Backport of 'Log a line for requests the rack middleware blocks'
What does this MR do and why?
Backports !258338 (merged), !265941 (merged), and !266584 (merged) to 19.4.
On 19.4, when every LabKit cohort is enforced, Gitlab::Middleware::LabkitRackRateLimit returns the 429 itself.
Rack::Attack safelists the request, so it writes no Rack_Attack line to auth_json.log.
Grape and lograge never run, so api_json.log has no entry either.
All six rate_limiter_use_labkit_rack_cohort_* flags are default_enabled: true on 19.4, so every 19.4 instance is affected.
Administrators and Support have no log line that shows which rule blocked a request, or which client it blocked.
This MR adds the Rate_Limit_Block line to auth_json.log:
- !258338 (merged) adds the line, with
matched,rule,limit,period_s,count,counted_by, andapplies_to. - !265941 (merged) adds
remote_ip,path, andmethod, with the same key names as theRack_Attackline. - !266584 (merged) removes
applies_toagain. The field has a different shape for different rules, and Elasticsearch drops a line whose shape does not match the index mapping.
The line is sampled: it is written when a client first goes past a rule's limit, then at 2, 4, 8 (and so on) times the limit. The trigger uses the count that LabKit already returned, so a blocked request makes no extra Redis call.
- Issue: #634755
- Feature change lock: https://gitlab.com/gitlab-com/feature-change-locks/-/work_items/128
Why this is a bug fix
On master, !258338 (merged) is ~"type::feature" and !265941 (merged) is ~"type::maintenance".
On 19.4, they fix a functional regression, tracked as a bug in #634755.
Before LabKit enforcement, Rack::Attack wrote a Rack_Attack line to auth_json.log for every blocked request.
LabKit enforcement removed that line and put nothing in its place.
Conflict resolution
!258338 (merged) did not apply cleanly. !265941 (merged) applied cleanly on top of it.
!266584 (merged) did not apply cleanly in the middleware, for the same RateLimitState reason. I kept the 19.4 closing } of the hash and removed only applies_to. Its spec change applied cleanly.
Gitlab::Instrumentation::RateLimitStatedoes not exist on 19.4. I removed theRateLimitState.track(checks)call and the.merge(RateLimitState.payload)call, so the line has norate_limit_statefield on 19.4.runkeeps the 19.4 shape (limiters.all.values.map). Thecheckshash onmasterexists only forRateLimitState.track, so I did not add it.log_blockruns in its ownguard, as onmaster, so a logging error never drops the 429.- In the spec, I removed the
RateLimitState::STATEexpectation and the unusedcounted_evaluationhelper.
Apart from these items, the middleware is the same as the 19.5 backport of !265941 (merged).
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
- This MR is backporting a bug fix, documentation update, or spec fix, previously merged in the default branch.
- The MR that fixed the bug on the default branch has been deployed to GitLab.com (not applicable for documentation or spec changes).
- The MR title is descriptive (e.g. "Backport of 'title of default branch MR'"). This is important, since the title will be copied to the patch blog post.
- Required labels have been applied to this merge request
- severity label and bug subtype labels (if applicable)
- If this MR fixes a bug that affects customers, the customer label has been applied.
- This MR has been approved by a maintainer (only one approval is required).
- Ensure the
e2e:test-on-omnibus-eejob has succeeded, or if it has failed, investigate the failures. If you determine the failures are unrelated, you may proceed. If you need assistance investigating, request help in the #s_developer_experience Slack channel to confirm the failures are unrelated to the merge request.
Note to the merge request author and maintainer
If you have questions about the patch release process, please:
- Refer to the patch release runbook for engineers and maintainers for guidance.
- Ask questions on the
#releasesSlack channel (internal only). - Once the backport has been merged, the commit changes will be automatically deployed to a release environment that can be used for manual validation. See after merging runbook for details.