Skip to content

Commit 8461e08

Browse files
committed
Make server and client handle resolv.conf differently.
The server should just read from resolv.conf to find DNS servers to use. This restores this behavior after the previous commit changed it. The client now reads both /etc/resolv.conf and /run/systemd/resolve/resolv.conf. The latter is required to more reliably intercept regular DNS requests that systemd-resolved makes.
1 parent 502960d commit 8461e08

File tree

4 files changed

+29
-15
lines changed

4 files changed

+29
-15
lines changed

sshuttle/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ def main(listenip_v6, listenip_v4,
589589
# redirect packets outgoing to this server to the remote host
590590
# instead.
591591
if dns:
592-
nslist += resolvconf_nameservers()
592+
nslist += resolvconf_nameservers(True)
593593
if to_nameserver is not None:
594594
to_nameserver = "%s@%s" % tuple(to_nameserver[1:])
595595
else:

sshuttle/helpers.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,29 +48,39 @@ class Fatal(Exception):
4848
pass
4949

5050

51-
def resolvconf_nameservers():
52-
"""Retrieves a list of tuples (address type, address as a string) that
53-
the current system uses to resolve hostnames from /etc/resolv.conf
54-
and possibly other files.
51+
def resolvconf_nameservers(systemd_resolved):
52+
"""Retrieves a list of tuples (address type, address as a string) of
53+
the DNS servers used by the system to resolve hostnames.
54+
55+
If parameter is False, DNS servers are retrieved from only
56+
/etc/resolv.conf. This behavior makes sense for the sshuttle
57+
server.
58+
59+
If parameter is True, we retrieve information from both
60+
/etc/resolv.conf and /run/systemd/resolve/resolv.conf (if it
61+
exists). This behavior makes sense for the sshuttle client.
62+
5563
"""
5664

5765
# Historically, we just needed to read /etc/resolv.conf.
5866
#
5967
# If systemd-resolved is active, /etc/resolv.conf will point to
6068
# localhost and the actual DNS servers that systemd-resolved uses
6169
# are stored in /run/systemd/resolve/resolv.conf. For programs
62-
# that use the localhost DNS server, only reading /etc/resolv.conf
63-
# is sufficient. However, resolved provides other ways of
64-
# resolving hostnames (such as via dbus) that may not route
65-
# requests through localhost. So, we retrieve a list of DNS
70+
# that use the localhost DNS server, having sshuttle read
71+
# /etc/resolv.conf is sufficient. However, resolved provides other
72+
# ways of resolving hostnames (such as via dbus) that may not
73+
# route requests through localhost. So, we retrieve a list of DNS
6674
# servers that resolved uses so we can intercept those as well.
6775
#
6876
# For more information about systemd-resolved, see:
6977
# https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html
7078
#
7179
# On machines without systemd-resolved, we expect opening the
7280
# second file will fail.
73-
files = ['/etc/resolv.conf', '/run/systemd/resolve/resolv.conf']
81+
files = ['/etc/resolv.conf']
82+
if systemd_resolved:
83+
files += ['/run/systemd/resolve/resolv.conf']
7484

7585
nsservers = []
7686
for f in files:
@@ -90,8 +100,12 @@ def resolvconf_nameservers():
90100
return nsservers
91101

92102

93-
def resolvconf_random_nameserver():
94-
lines = resolvconf_nameservers()
103+
def resolvconf_random_nameserver(systemd_resolved):
104+
"""Return a random nameserver selected from servers produced by
105+
resolvconf_nameservers(). See documentation for
106+
resolvconf_nameservers() for a description of the parameter.
107+
"""
108+
lines = resolvconf_nameservers(systemd_resolved)
95109
if lines:
96110
if len(lines) > 1:
97111
# don't import this unless we really need it

sshuttle/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def try_send(self):
205205
self.tries += 1
206206

207207
if self.to_nameserver is None:
208-
_, peer = resolvconf_random_nameserver()
208+
_, peer = resolvconf_random_nameserver(False)
209209
port = 53
210210
else:
211211
peer = self.to_ns_peer

tests/client/test_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_resolvconf_nameservers(mock_open):
131131
nameserver 2404:6800:4004:80c::4
132132
""")
133133

134-
ns = sshuttle.helpers.resolvconf_nameservers()
134+
ns = sshuttle.helpers.resolvconf_nameservers(False)
135135
assert ns == [
136136
(AF_INET, u'192.168.1.1'), (AF_INET, u'192.168.2.1'),
137137
(AF_INET, u'192.168.3.1'), (AF_INET, u'192.168.4.1'),
@@ -156,7 +156,7 @@ def test_resolvconf_random_nameserver(mock_open):
156156
nameserver 2404:6800:4004:80c::3
157157
nameserver 2404:6800:4004:80c::4
158158
""")
159-
ns = sshuttle.helpers.resolvconf_random_nameserver()
159+
ns = sshuttle.helpers.resolvconf_random_nameserver(False)
160160
assert ns in [
161161
(AF_INET, u'192.168.1.1'), (AF_INET, u'192.168.2.1'),
162162
(AF_INET, u'192.168.3.1'), (AF_INET, u'192.168.4.1'),

0 commit comments

Comments
 (0)