mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-11-21 23:43:18 +01:00
Intercept DNS requests sent by systemd-resolved.
Previously, we would find DNS servers we wish to intercept traffic on by reading /etc/resolv.conf. On systems using systemd-resolved, /etc/resolv.conf points to localhost and then systemd-resolved actually uses the DNS servers listed in /run/systemd/resolve/resolv.conf. Many programs will route the DNS traffic through localhost as /etc/resolv.conf indicates and sshuttle would capture it. However, systemd-resolved also provides other interfaces for programs to resolve hostnames besides the localhost server in /etc/resolv.conf. This patch adds systemd-resolved's servers into the list of DNS servers when --dns is used. Note that sshuttle will continue to fail to intercept any traffic sent to port 853 for DNS over TLS (which systemd-resolved also supports). For more info, see: sshuttle issue #535 https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html https://github.com/systemd/systemd/issues/6076
This commit is contained in:
parent
5c8c707208
commit
502960d796
@ -104,10 +104,12 @@ Options
|
||||
|
||||
Capture local DNS requests and forward to the remote DNS
|
||||
server. All queries to any of the local system's DNS
|
||||
servers (/etc/resolv.conf) will be intercepted and
|
||||
servers (/etc/resolv.conf and, if it exists,
|
||||
/run/systemd/resolve/resolv.conf) will be intercepted and
|
||||
resolved on the remote side of the tunnel instead, there
|
||||
using the DNS specified via the :option:`--to-ns` option,
|
||||
if specified.
|
||||
if specified. Only plain DNS traffic sent to these servers
|
||||
on port 53 are captured.
|
||||
|
||||
.. option:: --ns-hosts=<server1[,server2[,server3[...]]]>
|
||||
|
||||
|
@ -49,12 +49,45 @@ class Fatal(Exception):
|
||||
|
||||
|
||||
def resolvconf_nameservers():
|
||||
lines = []
|
||||
for line in open('/etc/resolv.conf'):
|
||||
words = line.lower().split()
|
||||
if len(words) >= 2 and words[0] == 'nameserver':
|
||||
lines.append(family_ip_tuple(words[1]))
|
||||
return lines
|
||||
"""Retrieves a list of tuples (address type, address as a string) that
|
||||
the current system uses to resolve hostnames from /etc/resolv.conf
|
||||
and possibly other files.
|
||||
"""
|
||||
|
||||
# Historically, we just needed to read /etc/resolv.conf.
|
||||
#
|
||||
# If systemd-resolved is active, /etc/resolv.conf will point to
|
||||
# localhost and the actual DNS servers that systemd-resolved uses
|
||||
# are stored in /run/systemd/resolve/resolv.conf. For programs
|
||||
# that use the localhost DNS server, only reading /etc/resolv.conf
|
||||
# is sufficient. However, resolved provides other ways of
|
||||
# resolving hostnames (such as via dbus) that may not route
|
||||
# requests through localhost. So, we retrieve a list of DNS
|
||||
# servers that resolved uses so we can intercept those as well.
|
||||
#
|
||||
# For more information about systemd-resolved, see:
|
||||
# https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html
|
||||
#
|
||||
# On machines without systemd-resolved, we expect opening the
|
||||
# second file will fail.
|
||||
files = ['/etc/resolv.conf', '/run/systemd/resolve/resolv.conf']
|
||||
|
||||
nsservers = []
|
||||
for f in files:
|
||||
this_file_nsservers = []
|
||||
try:
|
||||
for line in open(f):
|
||||
words = line.lower().split()
|
||||
if len(words) >= 2 and words[0] == 'nameserver':
|
||||
this_file_nsservers.append(family_ip_tuple(words[1]))
|
||||
debug2("Found DNS servers in %s: %s\n" %
|
||||
(f, [n[1] for n in this_file_nsservers]))
|
||||
nsservers += this_file_nsservers
|
||||
except OSError as e:
|
||||
debug3("Failed to read %s when looking for DNS servers: %s\n" %
|
||||
(f, e.strerror))
|
||||
|
||||
return nsservers
|
||||
|
||||
|
||||
def resolvconf_random_nameserver():
|
||||
|
Loading…
Reference in New Issue
Block a user