-
Notifications
You must be signed in to change notification settings - Fork 4.5k
delegatingresolver: avoid proxy for resolved addresses in NO_PROXY env #8329
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
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #8329 +/- ##
==========================================
+ Coverage 82.19% 82.29% +0.09%
==========================================
Files 419 419
Lines 42025 42048 +23
==========================================
+ Hits 34543 34603 +60
+ Misses 6012 5986 -26
+ Partials 1470 1459 -11
🚀 New features to boost your workflow:
|
I think release notes should mention the bug fix. How about something like |
@@ -241,7 +253,7 @@ func (r *delegatingResolver) updateClientConnStateLocked() error { | |||
var addresses []resolver.Address | |||
for _, targetAddr := range (*r.targetResolverState).Addresses { | |||
// Avoid proxy when network is not tcp. | |||
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" { | |||
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" || !isProxyNeeded(targetAddr.Addr) { |
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.
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" || !isProxyNeeded(targetAddr.Addr) { | |
!isProxyNeeded(targetAddr.Addr) { | |
addresses = append(addresses, targetAddr) | |
continue | |
} | |
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" { | |
addresses = append(addresses, targetAddr) | |
continue | |
} |
to avoid checking network type if proxy is anyway not needed?
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.
You can also combine both the network type check and NO_PROXY check in the same helper function
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.
Done.
@@ -259,7 +271,7 @@ func (r *delegatingResolver) updateClientConnStateLocked() error { | |||
var addrs []resolver.Address | |||
for _, targetAddr := range endpt.Addresses { | |||
// Avoid proxy when network is not tcp. | |||
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" { | |||
if networkType := networkTypeFromAddr(targetAddr); networkType != "tcp" || !isProxyNeeded(targetAddr.Addr) { |
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.
same suggestion as above
@@ -210,6 +210,18 @@ func isTCPAddressPresent(state *resolver.State) bool { | |||
return false | |||
} | |||
|
|||
func isProxyNeeded(address string) bool { |
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.
how about skipProxy
?
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.
Done
Host: envProxyAddr, | ||
}, nil | ||
} | ||
originalhpfe := delegatingresolver.HTTPSProxyFromEnvironment |
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.
i don't have much context but is it possible to set the NO_PROXY env var for this test instead of just overriding from here? That would be a more reliable test.
I found one example here https://github.com/grpc/grpc-go/blob/master/stats/opentelemetry/csm/pluginoption_test.go#L437
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.
Also might be good to verify putting in the IP range as mention in the bug?
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.
I remember having some problem with using the proxy environment variable and so we switched to replacing the function.
SOmething on the lines that the function used to retrieve proxy address uses Do.Once function and that gets done the first time we run the test suite and so every time we do not get the value set in proxy environments and so we decided to replace the function in tests.
I don't have much knowledge about the recent changes here. So I will defer to @easwars and @arjan-bal |
internal/resolver/delegatingresolver/delegatingresolver_ext_test.go
Outdated
Show resolved
Hide resolved
return true | ||
} | ||
// Avoid proxy when network is not tcp. | ||
if networkType := networkTypeFromAddr(address); networkType != "tcp" { |
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.
We can make isTCPAddressPresent
use skipProxy
instead and inline networkTypeFromAddr
. isTCPAddressPresent
would also need to be renamed to something more appropriate then. This would unify the checks in both places.
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.
Done.
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.
Can we inline networkTypeFromAddr
since there is only one caller now? This would also prevent people from accidentally bypassing the "ignore proxy" check in the future.
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.
Right! Missed that. Done!
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.
LGTM
Please open a flake for the failing advancedtls test and assign it to someone from the security team. https://github.com/grpc/grpc-go/actions/runs/15105499577/job/42453426886?pr=8329 |
FWIW, I think it is worth mentioning that this behavior is probably non-idiomatic and is really only being put in for backwards compatibility. For example, it would not make sense for There is potential for inconsistent behavior here: For example, this would mean that |
IMO including IP addresses in the NO_PROXY environment variable should not be considered inconsistent behavior. The Go proxy configuration explicitly supports IP addresses in |
I agree we should support IP addresses, but it seems we should also support domain names here, too. If the primary resolver is DNS and NO_PROXY includes the hostname we are looking up, we should not use a proxy. |
Right! That is there, I have not changed that! Just added another check for IP address also after the addresses are resolved. |
I see. So this is happening later in the process, after addresses are resolved, when we are doing local resolution. And since our behavior for many years had been to respect This is basically use case 2 from gRFC A1. And I think as long as we are doing local name resolution, then it is pretty reasonable to check |
// If no addresses returned by resolver have network type as tcp , do not | ||
// wait for proxy update. |
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.
Please update.
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.
Done.
@@ -177,14 +177,10 @@ func (s) TestDelegatingResolverwithDNSAndProxyWithTargetResolution(t *testing.T) | |||
resolvedProxyTestAddr1 = "11.11.11.11:7687" | |||
) | |||
hpfe := func(req *http.Request) (*url.URL, error) { |
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.
There seems to be a lot of repetition of this, which required you to change it in many many places. Can you factor this out and share it between the test cases since it seems to be identical every time?
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.
Done.
// the delegating resolver doesn't add proxyatrribute to adresses excluded , but | ||
// adds the proxyattribute to all other addresses. |
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.
Please make sure you don't have spaces before commas. (I've noticed this elsewhere, too.)
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.
Done.
internal/transport/proxy_ext_test.go
Outdated
@@ -97,14 +97,10 @@ func (s) TestGRPCDialWithProxy(t *testing.T) { | |||
|
|||
// Overwrite the function in the test and restore them in defer. | |||
hpfe := func(req *http.Request) (*url.URL, error) { |
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.
Same comments for this file re: re-use.
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.
Done.
Fixes: #8327
Add a check for resolved addresses to avoid proxy for addresses mentioned in NO_PROXY environment variable. We only had a check for unresolved addresses.
RELEASE NOTES:
NO_PROXY
environment variable when connecting to locally-resolved addresses. This fixes a regression and restores historical grpc-go behavior (use case 2 from gRFC A1 ).