Skip to content
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

If Proxy is set, DNS should not be resolved by the client #1335

Open
Snurppa opened this issue Jun 27, 2023 · 2 comments
Open

If Proxy is set, DNS should not be resolved by the client #1335

Snurppa opened this issue Jun 27, 2023 · 2 comments

Comments

@Snurppa
Copy link

Snurppa commented Jun 27, 2023

Describe the bug
When client side is using proxy via WebSocketClient.setProxy, the default DnsResolver will force hostname resolution.

But I think when behind a proxy, the resolving of hostnames should be done by the proxy, not by the client, living in a possibly constrained network, which might not have access to public DNS.

We bumped into this in production when a customer was using a proxy and the host running the app had no access to DNS.
Establishing the connection would crash in WebSocketClient.connect with java.net.UnknownHostException: public.example.com: Name or service not known.

To Reproduce
Steps to reproduce the behavior:

  1. Setup proxy. I used mitmproxy running in host, the JVM app was running in Docker container.
  2. Configure the WebSocketClient to direct comms to that proxy. For me proxy host was host.docker.internal:8080 as I was running JVM inside a container. Also the target server was running in host OS, port 3200.
    • I was using Basic authentication in proxy and had set global java.net.Authenticator with java.net.Authenticator.setDefault so JVM will pass the credentials
  3. Depending on your level of commitment, start something like tcpflow to inspect what is happening, in this case between container and the host: docker run --net="container:<your-container-id-or-name>" byfcz/tcpflow -p -c
  4. Start the WS client
  5. You will see that when Java-WebSocket client issues CONNECT request to the proxy, it has already resolved the target's hostname host.docker.internal to IP address (the host IP from Docker perspective). In my case, host was resolved to 192.168.065.254:
172.017.000.002.33974-192.168.065.254.08080: CONNECT 192.168.65.254:3200 HTTP/1.1
User-Agent: Java/18.0.2
Host: 192.168.65.254:3200              <------------------------------------
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Proxy-Connection: keep-alive
  1. Now when mitmproxy receives this, it can't reach 192.168.065.254. I had 127.0.0.1 host.docker.internal configured in /etc/hosts, so if it would have let the Host header be untouched, it would have worked. Now after some internal timeout mitmproxy responds with 502 Bad Gateway

Example application to reproduce the issue

Expected behavior

I was thinking, when a proxy is set, the client should not do DNS resolution by default?

We were able to patch the issue by calling setDnsResolver(null).
After that, the Host header was left intact and the Proxy would take it and resolve it.

Should this null DnsResolver be default in the library, maybe done by the setProxy?

Debug log

Environment(please complete the following information):

  • Version used: 1.5.3
  • Java version: 18.0.2
  • Operating System and version: local macOS & Docker 23.0.5 + Debian Linux & Docker 20+ in customer premises.

Additional context
JVM app running in container, using PROXY_HOST + PROXY_PORT and the java.net.Authenticator.getPasswordAuthentication implemented to return credentials + applied globally with java.net.Authenticator.setDefault.
The exchange of the credentials works correctly between WebSocketClient and the Proxy server.
Customer network where app was running needs to route everything through proxy, there is no public DNS available.

The issue is just the DNS resolution, either it crashes with UnknownHostException or the Host header might be wrong (in the case of using something like host.docker.internal at least).

@PhilipRoman
Copy link
Collaborator

Just to clarify, you can completely work around this by doing setDnsResolver(null) and then it works fine for you?

I just want to understand how high priority this issue is.

@Snurppa
Copy link
Author

Snurppa commented Jun 27, 2023

Just to clarify, you can completely work around this by doing setDnsResolver(null) and then it works fine for you?

I just want to understand how high priority this issue is.

Sorry, that was not clear enough. The answer is yes, setting setDnsResolver(null) is enough to fix the issue.

I guess the question is, should the same be done by default in the setProxy method or not 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants