diff options
author | Itamar Turner-Trauring <itamar@datawire.io> | 2017-07-14 15:50:26 -0400 |
---|---|---|
committer | Brian May <brian@linuxpenguins.xyz> | 2017-07-18 17:15:03 +1000 |
commit | d2e97a60f78ffc5ec11390934352bc7a52651e8d (patch) | |
tree | 9f387205d3ef8bf72a6d6b340196d16770d84f1a | |
parent | cdbb3799102882a3087a56997ae2402393cf655d (diff) |
Add new option for overriding destination DNS server.
-rw-r--r-- | sshuttle/assembler.py | 2 | ||||
-rw-r--r-- | sshuttle/client.py | 12 | ||||
-rw-r--r-- | sshuttle/cmdline.py | 4 | ||||
-rw-r--r-- | sshuttle/options.py | 9 | ||||
-rw-r--r-- | sshuttle/server.py | 28 |
5 files changed, 40 insertions, 15 deletions
diff --git a/sshuttle/assembler.py b/sshuttle/assembler.py index c063dc6..a9a4098 100644 --- a/sshuttle/assembler.py +++ b/sshuttle/assembler.py @@ -34,4 +34,4 @@ sshuttle.helpers.verbose = verbosity import sshuttle.cmdline_options as options from sshuttle.server import main -main(options.latency_control, options.auto_hosts) +main(options.latency_control, options.auto_hosts, options.to_nameserver) diff --git a/sshuttle/client.py b/sshuttle/client.py index d366db8..373e320 100644 --- a/sshuttle/client.py +++ b/sshuttle/client.py @@ -415,7 +415,8 @@ def ondns(listener, method, mux, handlers): def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_control, - dns_listener, seed_hosts, auto_hosts, auto_nets, daemon): + dns_listener, seed_hosts, auto_hosts, auto_nets, daemon, + to_nameserver): debug1('Starting client with Python version %s\n' % platform.python_version()) @@ -434,7 +435,8 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, ssh_cmd, remotename, python, stderr=ssyslog._p and ssyslog._p.stdin, options=dict(latency_control=latency_control, - auto_hosts=auto_hosts)) + auto_hosts=auto_hosts, + to_nameserver=to_nameserver)) except socket.error as e: if e.args[0] == errno.EPIPE: raise Fatal("failed to establish ssh session (1)") @@ -534,7 +536,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, def main(listenip_v6, listenip_v4, ssh_cmd, remotename, python, latency_control, dns, nslist, method_name, seed_hosts, auto_hosts, auto_nets, - subnets_include, subnets_exclude, daemon, pidfile): + subnets_include, subnets_exclude, daemon, to_nameserver, pidfile): if daemon: try: @@ -549,6 +551,8 @@ def main(listenip_v6, listenip_v4, # Get family specific subnet lists if dns: nslist += resolvconf_nameservers() + if to_nameserver is not None: + to_nameserver = "%s@%s" % tuple(to_nameserver[1:]) subnets = subnets_include + subnets_exclude # we don't care here subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6] @@ -741,7 +745,7 @@ def main(listenip_v6, listenip_v4, try: return _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_control, dns_listener, - seed_hosts, auto_hosts, auto_nets, daemon) + seed_hosts, auto_hosts, auto_nets, daemon, to_nameserver) finally: try: if daemon: diff --git a/sshuttle/cmdline.py b/sshuttle/cmdline.py index 7b34267..ecb01e3 100644 --- a/sshuttle/cmdline.py +++ b/sshuttle/cmdline.py @@ -73,7 +73,9 @@ def main(): opt.auto_nets, includes, excludes, - opt.daemon, opt.pidfile) + opt.daemon, + opt.to_ns, + opt.pidfile) if return_code == 0: log('Normal exit code, exiting...') diff --git a/sshuttle/options.py b/sshuttle/options.py index 659c014..f4647b1 100644 --- a/sshuttle/options.py +++ b/sshuttle/options.py @@ -147,6 +147,15 @@ parser.add_argument( """ ) parser.add_argument( + "--to-ns", + metavar="IP[:PORT]", + type=parse_ipport, + help=""" + the DNS server to forward requests to; defaults to servers in /etc/resolv.conf on remote side if not given. + """ +) + +parser.add_argument( "--method", choices=["auto", "nat", "tproxy", "pf", "ipfw"], metavar="TYPE", diff --git a/sshuttle/server.py b/sshuttle/server.py index c324eed..92e3c99 100644 --- a/sshuttle/server.py +++ b/sshuttle/server.py @@ -160,7 +160,7 @@ class Hostwatch: class DnsProxy(Handler): - def __init__(self, mux, chan, request): + def __init__(self, mux, chan, request, to_nameserver): Handler.__init__(self, []) self.timeout = time.time() + 30 self.mux = mux @@ -168,6 +168,15 @@ class DnsProxy(Handler): self.tries = 0 self.request = request self.peers = {} + if to_nameserver is None: + self.to_nameserver = None + else: + peer, port = to_nameserver.split("@") + port = int(port) + if port == 0: + port = 53 + family = socket.AF_INET6 if ":" in peer else socket.AF_INET + self.to_nameserver = family, peer, port self.try_send() def try_send(self): @@ -175,18 +184,19 @@ class DnsProxy(Handler): return self.tries += 1 - family, peer = resolvconf_random_nameserver() + if self.to_nameserver is None: + family, peer = resolvconf_random_nameserver() + port = 53 + else: + family, peer, port = self.to_nameserver sock = socket.socket(family, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42) - # Connect to custom DNS server running in the Telepresence pod: - # XXX eventually this should be configured via command-line - # option and submitted to upstream as improvement. - sock.connect(('127.0.0.1', 9053)) + sock.connect((peer, port)) self.peers[sock] = peer - debug2('DNS: sending to %r (try %d)\n' % (peer, self.tries)) + debug2('DNS: sending to %r:%d (try %d)\n' % (peer, port, self.tries)) try: sock.send(self.request) self.socks.append(sock) @@ -261,7 +271,7 @@ class UdpProxy(Handler): self.mux.send(self.chan, ssnet.CMD_UDP_DATA, hdr + data) -def main(latency_control, auto_hosts): +def main(latency_control, auto_hosts, to_nameserver): debug1('Starting server with Python version %s\n' % platform.python_version()) @@ -335,7 +345,7 @@ def main(latency_control, auto_hosts): def dns_req(channel, data): debug2('Incoming DNS request channel=%d.\n' % channel) - h = DnsProxy(mux, channel, data) + h = DnsProxy(mux, channel, data, to_nameserver) handlers.append(h) dnshandlers[channel] = h mux.got_dns_req = dns_req |