-
Notifications
You must be signed in to change notification settings - Fork 649
Implement X-Forwarded-For
header processing
#7359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This adjusts the `process_xff_headers()` to our current deployment reality of the app being reachable either directly on Heroku or with CloudFront in front. It also adds a work around for some broken Heroku behavior.
…eader values This is supposed to eventually replace the `X-Real-IP` header usage once production traffic has shown that our implementation is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainly, two major comments:
- String comparisons on a flat vec for something per-request is very slow, it'd be beneficial to use
cidr
in an appropriate integer-sized hashmap for lookups. - Should we even allow direct calls via heroku, or should we just start banishing all requests not using a CDN?
Since this is purely additive and the performance concerns have been addressed, I'll go ahead and merge this to test it out on staging and then deploy it to production. |
// The Heroku router has a bug where it currently (2023-10-25) appends | ||
// the connecting IP to the **first** header instead of the last. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for context: heroku/roadmap#238
This PR essentially implements http://nginx.org/en/docs/http/ngx_http_realip_module.html inside of our axum server, as another step towards removing the nginx wrapper.
… but there is a twist. Heroku is somewhat broken. Their broken handles the header incorrectly in case the original request contains multiple
X-Forwarded-For
headers. Instead of adding the connecting IP to the last header, or merging the headers, it adds the IP to the first header 😱I've reported this to Heroku in the form of a support ticket, but while that is being processed we will unfortunately have to use a workaround. Luckily CloudFront merges these headers, so if we get multiple headers we can know for certain that the request did not come from CloudFront.
On the bright side, we only use the value for logging at the moment. The PR adds another field to the logs with the IP addressed that was parsed from the
X-Forwarded-For
headers. It also adds a log marker in case the IP is different from the one that nginx supplies us in theX-Real-IP
header. This will allow us to see if there are differences to the nginx algorithm once production traffic hits this code. Spoiler alert: yes, the Heroku workaround is a difference, but for regular, non-malicious traffic this should not matter.