Opened 10 years ago
Last modified 9 years ago
#5345 new Bug
UDP dns request 'reported' on all interfaces even after binding transmission to a specific IP
Reported by: | DogJohnson | Owned by: | |
---|---|---|---|
Priority: | Normal | Milestone: | None Set |
Component: | Daemon | Version: | 2.77+ |
Severity: | Normal | Keywords: | DNS UDP bind interface VPN leak |
Cc: |
Description
I have successfully bound transmission to only use a specific IP address in the settings.json file. This seems to work well for actual torrenting traffic, but when I issue the command 'netstat -ulnp' I get:
udp 0 0 10.0.0.2:33333 0.0.0.0:* 15127/transmission-daemon udp 0 0 0.0.0.0:35685 0.0.0.0:* 15127/transmission-daemon
While I see that port 33333 (my forwarded port for transmission) is bound to 10.0.0.2 (my tun0 adapter of my VPN), the other port 35685 is a random UDP port not bound to any interface. Using tcpdump (tcpdump -n -i tun0) I was able to determine that this random UDP port originates as an outbound DNS request. My concern is that this '0.0.0.0' could mean that transmission-daemon is able to send out udp dns requests on all interfaces and not just the one it is bound to.
I believe that this DNS request is only using the correct tun0 interface (my firewall log doesn't show any blocked or audit reports of attempts to send DNS queries on any other interface, nor does tcpdump of eth0 for port 53 show any activity), but this could be because of how my internal routing is set up and might not the same for everyone.
I would like to be certain that DNS requests are also bound to the designated interface, evidenced by transmission never showing '0.0.0.0' as its ip if using the bind function. Worst-case scenario being that I am torrenting behind a VPN where my non-vpn'd interface is used to resolve tracker hostnames. This would seem to defeat the purpose.
DJ
Change History (5)
comment:1 Changed 9 years ago by jaseg
comment:2 Changed 9 years ago by DogJohnson
I thought this bug was lost forever. That is interesting that it is leaking for you. It is still not for me (that I can see) despite the potential. But if this is true, it I think I should change it to HIGH priority, as it defeats the whole purpose of binding and a VPN.
Two things first:
I am assuming eth0 is not ip 10.8.0.190? I think this is obvious but just to double check...
And then if you did a 'tcpdump -n -i eth0 port 53' (-n to not resolve hostnames) that is definitely shows eth0 as the source ip for the DNS request despite transmission being bound to another interface?
DJ
comment:3 Changed 9 years ago by rb07
The problem is that libcurl is used to communicate with trackers (and other operations, like testing if the peer port is open), and the corresponding option for binding the address used for DNS queries is not used.
From the Curl documentation:
CURLOPT_DNS_INTERFACE Pass a char * as parameter. Set the name of the network interface that the DNS resolver should bind to. This must be an interface name (not an address). Set this option to NULL to use the default setting (don't bind to a specific interface).
This option requires that libcurl was built with a resolver backend that supports this operation. The c-ares backend is the only such one.
(Added in 7.33.0)
CURLOPT_DNS_LOCAL_IP4 Set the local IPv4 address that the resolver should bind to. The argument should be of type char * and contain a single IPv4 address as a string. Set this option to NULL to use the default setting (don't bind to a specific IP address).
This option requires that libcurl was built with a resolver backend that supports this operation. The c-ares backend is the only such one.
(Added in 7.33.0)
CURLOPT_DNS_LOCAL_IP6 Set the local IPv6 address that the resolver should bind to. The argument should be of type char * and contain a single IPv6 address as a string. Set this option to NULL to use the default setting (don't bind to a specific IP address).
This option requires that libcurl was built with a resolver backend that supports this operation. The c-ares backend is the only such one.
Note that using one of these options also means you must use c-ares, which is something Transmission doesn't (can't) force. That means using a special build, not just adding the corresponding option in web.c with the parameter from the settings.
comment:4 Changed 9 years ago by x190
Possible workaround:
use openDNS, e.g. 208.67.220.220, and/or G::gle, e.g. 8.8.4.4, set via network settings, not router. VPN must be disconnected and the openVPN daemon stopped first. If your VPN connection app has a 'route all traffic through the VPN' option, check that as well. https://www.dnsleaktest.com, (extended test) will only see their nameservers and eth0, or en0 (os x), should be clean for port 53.
comment:5 Changed 9 years ago by jaseg
Another workaround would be to set up a separarte routing table for the VPN and send all traffic from transmission-daemon's UID through that table using some iptables magic.
I can confirm that this actually does not send the DNS requests over the interface transmission is bound to, as can be seen in the following tcpdump output:
I run transmission as follows:
I think this can be considered a bug since a) it leaks information if using a VPN and b) it allows DNS-level censoring of torrent trackers.
The remaining traffic is sent nicely encrypted through my VPN.