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

SOCKSification of DNS #49

Open
JeremyRand opened this issue Feb 21, 2023 · 6 comments
Open

SOCKSification of DNS #49

JeremyRand opened this issue Feb 21, 2023 · 6 comments

Comments

@JeremyRand
Copy link
Member

DNS traffic is handled specially by Tor; standard SOCKSification of TCP connections will not work well for DNS traffic. I would suggest the following:

  • The tracer should open a DNS server socket (on both UDP and TCP).
  • The tracer should check whether outgoing TCP/UDP connections from the tracee are destined to the default system DNS resolver.
  • If so, the tracer should redirect their destination IP+port to the tracer's DNS server.

We can support three modes for the tracer's DNS server:

  • Fast mode. The DNS server generates an IP address in the privately routable range, and returns that address to the DNS client, while storing the mapping of that IP to the requested hostname. When the tracer then intercepts a TCP connection to that IP address, it substitutes the hostname when doing a SOCKS5 handshake. This mode will save a round trip through an exit relay, but will not work for applications that are doing DNS requests for reasons other than immediately connecting to the IP that is returned. It should work fine with IPv4 and IPv6. It's similar to what Tor already does for .onion requests through its DNS port.
  • Slow mode. The DNS server sends a RESOLVE command to the SOCKS5 server (this is a nonstandard, Tor-specific extension to the SOCKS5 spec), and returns the resulting IP to the DNS client. This will work for applications that do DNS requests for reasons other than immediately connecting to the IP that is returned, but will incur an extra round trip through an exit relay. I seem to recall that Tor's RESOLVE SOCKS5 command doesn't support IPv6. It's similar to what torsocks already does.
  • Leak mode. The DNS server simply does a DNS lookup itself using the Go standard library. This mode is mainly just for debug purposes, since it lets us verify whether DNS request interception by the tracer is working properly, without worrying about potential bugs in SOCKSification. This one should probably be implemented first since it's simpler.
@JeremyRand
Copy link
Member Author

Potentially useful library for a DNS server: https://github.com/hlandau/madns (it's what we use for ncdns).

@JeremyRand
Copy link
Member Author

Note that using madns verbatim probably won't work since it's designed for authoritative nameservers. But some code can probably be borrowed from madns without issues.

@robertmin1
Copy link
Collaborator

Currently held by the fork system bug

@robertmin1
Copy link
Collaborator

Fixing the bug didn't fix the issue. I still can't see the connect syscalls that contain the DNS connections

@JeremyRand
Copy link
Member Author

We can support three modes for the tracer's DNS server:

A fourth mode: Connect to a public DNS server (over TCP, TLS, or HTTPS), SOCKSified. This approach is necessary for looking up unusual DNS record types such as TLSA records, since Tor doesn't support these.

@handpickencounter
Copy link

handpickencounter commented Nov 4, 2024

Tor already has some of this functionality built in it seems.

When using

AutomapHostsSuffixes .
AutomapHostsOnResolve 1

Both socks5 RESOLVE and DNSPort return an IP immediately, the Tor process maintains a map and has the exit node resolve on connect.

This also seems like the solution that would be just the thing 99.9% of the time.

Perhaps a flag to disable this behavior and have the user figure out TCP DNS if they have some requirements is adequate?

Regarding implementation, listening on a custom port and servicing DNS is probably the simplest and adequate way to do it.
However, I'm not sure what is the best way to redirect UDP traffic.
Tracing sendto() may be sufficient?

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

3 participants