Add new option for overriding destination DNS server.

This commit is contained in:
Itamar Turner-Trauring 2017-07-14 15:50:26 -04:00 committed by Brian May
parent cdbb379910
commit d2e97a60f7
5 changed files with 40 additions and 15 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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...')

View File

@ -146,6 +146,15 @@ parser.add_argument(
capture and forward DNS requests made to the following servers
"""
)
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"],

View File

@ -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