Draft: Avoid blocking DNS lookup when selecting HTTP proxy
What does this MR do and why?
Ruby's URI::Generic#find_proxy resolves the destination hostname via
IPSocket.getaddress before deciding whether to route a request through the
configured proxy. On a self-managed host that can only resolve public
hostnames through the proxy (not natively via /etc/resolv.conf), that
lookup stalls for the OS DNS timeout on every outbound request. Because the
GitLab Duo health check fans out into many synchronous outbound calls, the
stalls compound past the request timeout and the health check, GitLab Credits
dashboard, and model list render blank.
This reworks the proxy_uri override in gitlab-http to select the proxy
without resolving the destination hostname. This is safe: SSRF /
DNS-rebinding enforcement is already skipped for proxied requests, so the
pre-proxy resolution served no security purpose.
Related to #602538.
Behavior change
no_proxy CIDR entries now match only literal-IP targets; they no longer
match hostnames that would resolve into the range (that match is what
required the DNS lookup we are removing). Domain and domain-suffix no_proxy
entries keep matching hostnames as before.
Out of scope
The Duo Agent Platform probe to duo-workflow-svc.runway.gitlab.net uses
gRPC, which performs its own name resolution and proxy handling and is not
affected by this change. Tracked as a follow-up on the issue.
How to test
Configure https_proxy + no_proxy and confirm proxy selection no longer
triggers IPSocket.getaddress (see added specs in
net_http_connect_patch_spec.rb).
References
Screenshots or screen recordings
| Before | After |
|---|---|
How to set up and validate locally
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.