Part of this boils down to how proxychains works in general. In order to proxy traffic from arbitrary programs (that may or may not have proxy support), proxychains uses the LD_PRELOAD
environment variable to load itself as a shared library into the program that is being called. Since it is "pre"-loaded, the functions exposed by the proxychains library take precedence over others, e.g. libc. This allows it to hook certain network related functions.
For example, when the program calls connect()
on a TCP socket, proxychains has replaced the real connect()
function with its own, one that instead knows how to shove the traffic through your configured proxies.
The same applies for DNS, although it is a slightly special case. The application will make a call to gethostbyname()
(obsolete) or getaddrinfo()
to perform DNS resolution. If the proxy_dns
option is not specified in the configuration file, proxychains will call the unaltered libc function, resolving DNS normally through your system. If the proxy_dns
option is present, it will instead redirect both functions ultimately to a modified version of gethostbyname()
that is fairly more complicated.
This modified version actually doesn't do any DNS resolution at all. Instead, it creates a fake IP address in the reserved 224.x.x.x or 225.x.x.x range, and maps your requested hostname to it in a table (e.g. 224.1.2.3 --> www.example.com
). This will come in handy later.
The application then makes a connection to the fake address returned above (224.1.2.3). Proxychain's hooked connect
will then set up a connection to the configured proxy. It will then look up the fake IP address in the DNS table to retrieve the original hostname that you were requesting (proxychains says: `224.1.2.3? That was "www.example.com"). Depending on the type of proxy in use, it will request a connection to the original hostname through the proxy. The proxy performs the DNS requests on your behalf since it is the one making a connection to the real destination.
Specifically in your case, if you were to run:
$ proxychains curl https://example.com
The Tor SOCKS5 server will receive a request from proxychains such as:
Hello server! Connect me to www.example.com:443
The Tor SOCKS5 server will then handle everything; performing DNS resolution and sending your packets over the Tor network.
TL;DR: When the proxy_dns
setting is enabled, no real DNS requests are made (or needed) from your end.
Source: Read the source code at https://github.com/haad/proxychains/