diff options
Diffstat (limited to 'sshuttle')
-rw-r--r-- | sshuttle/assembler.py | 2 | ||||
-rw-r--r-- | sshuttle/client.py | 30 | ||||
-rw-r--r-- | sshuttle/cmdline.py | 5 | ||||
-rw-r--r-- | sshuttle/firewall.py | 13 | ||||
-rw-r--r-- | sshuttle/linux.py | 22 | ||||
-rw-r--r-- | sshuttle/methods/__init__.py | 2 | ||||
-rw-r--r-- | sshuttle/methods/ipfw.py | 8 | ||||
-rw-r--r-- | sshuttle/methods/nat.py | 20 | ||||
-rw-r--r-- | sshuttle/methods/nft.py | 10 | ||||
-rw-r--r-- | sshuttle/methods/pf.py | 2 | ||||
-rw-r--r-- | sshuttle/methods/tproxy.py | 10 | ||||
-rw-r--r-- | sshuttle/options.py | 11 | ||||
-rw-r--r-- | sshuttle/server.py | 14 | ||||
-rw-r--r-- | sshuttle/ssnet.py | 2 |
14 files changed, 43 insertions, 108 deletions
diff --git a/sshuttle/assembler.py b/sshuttle/assembler.py index 2d09a50..011baa2 100644 --- a/sshuttle/assembler.py +++ b/sshuttle/assembler.py @@ -42,4 +42,4 @@ import sshuttle.cmdline_options as options # noqa: E402 from sshuttle.server import main # noqa: E402 main(options.latency_control, options.latency_buffer_size, options.auto_hosts, options.to_nameserver, - options.auto_nets, options.ttl) + options.auto_nets) diff --git a/sshuttle/client.py b/sshuttle/client.py index ef4f36b..23fde6b 100644 --- a/sshuttle/client.py +++ b/sshuttle/client.py @@ -44,6 +44,7 @@ def got_signal(signum, frame): sys.exit(1) +# Filename of the pidfile created by the sshuttle client. _pidname = None @@ -198,7 +199,7 @@ class MultiListener: class FirewallClient: - def __init__(self, method_name, sudo_pythonpath, ttl): + def __init__(self, method_name, sudo_pythonpath): self.auto_nets = [] argvbase = ([sys.executable, sys.argv[0]] + @@ -260,7 +261,7 @@ class FirewallClient: def setup(self, subnets_include, subnets_exclude, nslist, redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4, udp, - user, ttl, tmark): + user, tmark): self.subnets_include = subnets_include self.subnets_exclude = subnets_exclude self.nslist = nslist @@ -271,7 +272,6 @@ class FirewallClient: self.udp = udp self.user = user self.tmark = tmark - self.ttl = ttl def check(self): rv = self.p.poll() @@ -310,9 +310,8 @@ class FirewallClient: else: user = b'%d' % self.user - self.pfile.write(b'GO %d %s %d %s\n' % - (udp, user, self.ttl, - bytes(self.tmark, 'ascii'))) + self.pfile.write(b'GO %d %s %s\n' % + (udp, user, bytes(self.tmark, 'ascii'))) self.pfile.flush() line = self.pfile.readline() @@ -457,7 +456,7 @@ def ondns(listener, method, mux, handlers): def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_control, latency_buffer_size, dns_listener, seed_hosts, auto_hosts, auto_nets, daemon, - to_nameserver, ttl): + to_nameserver): helpers.logprefix = 'c : ' debug1('Starting client with Python version %s' @@ -476,8 +475,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, latency_buffer_size=latency_buffer_size, auto_hosts=auto_hosts, to_nameserver=to_nameserver, - auto_nets=auto_nets, - ttl=ttl)) + auto_nets=auto_nets)) except socket.error as e: if e.args[0] == errno.EPIPE: raise Fatal("failed to establish ssh session (1)") @@ -587,6 +585,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, % (expected, initstring)) log('Connected to server.') sys.stdout.flush() + if daemon: daemonize() log('daemonizing (%s).' % _pidname) @@ -673,12 +672,11 @@ def main(listenip_v6, listenip_v4, latency_buffer_size, dns, nslist, method_name, seed_hosts, auto_hosts, auto_nets, subnets_include, subnets_exclude, daemon, to_nameserver, pidfile, - user, sudo_pythonpath, tmark, ttl): + user, sudo_pythonpath, tmark): if not remotename: - print("WARNING: You must specify -r/--remote to securely route " - "traffic to a remote machine. Running without -r/--remote " - "is only recommended for testing.") + raise Fatal("You must use -r/--remote to specify a remote " + "host to route traffic through.") if daemon: try: @@ -689,7 +687,7 @@ def main(listenip_v6, listenip_v4, debug1('Starting sshuttle proxy (version %s).' % __version__) helpers.logprefix = 'c : ' - fw = FirewallClient(method_name, sudo_pythonpath, ttl) + fw = FirewallClient(method_name, sudo_pythonpath) # nslist is the list of name severs to intercept. If --dns is # used, we add all DNS servers in resolv.conf. Otherwise, the list @@ -1006,14 +1004,14 @@ def main(listenip_v6, listenip_v4, # start the firewall fw.setup(subnets_include, subnets_exclude, nslist, redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4, - required.udp, user, ttl, tmark) + required.udp, user, tmark) # start the client process try: return _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, python, latency_control, latency_buffer_size, dns_listener, seed_hosts, auto_hosts, auto_nets, - daemon, to_nameserver, ttl) + daemon, to_nameserver) finally: try: if daemon: diff --git a/sshuttle/cmdline.py b/sshuttle/cmdline.py index e792e22..2295d36 100644 --- a/sshuttle/cmdline.py +++ b/sshuttle/cmdline.py @@ -43,7 +43,7 @@ def main(): if opt.firewall: if opt.subnets or opt.subnets_file: parser.error('exactly zero arguments expected') - return firewall.main(opt.method, opt.syslog, opt.ttl) + return firewall.main(opt.method, opt.syslog) elif opt.hostwatch: return hostwatch.hw_main(opt.subnets, opt.auto_hosts) else: @@ -116,8 +116,7 @@ def main(): opt.pidfile, opt.user, opt.sudo_pythonpath, - opt.tmark, - opt.ttl) + opt.tmark) if return_code == 0: log('Normal exit code, exiting...') diff --git a/sshuttle/firewall.py b/sshuttle/firewall.py index 031454c..a2aedfd 100644 --- a/sshuttle/firewall.py +++ b/sshuttle/firewall.py @@ -121,7 +121,7 @@ def flush_systemd_dns_cache(): # exit. In case that fails, it's not the end of the world; future runs will # supercede it in the transproxy list, at least, so the leftover rules # are hopefully harmless. -def main(method_name, syslog, ttl): +def main(method_name, syslog): helpers.logprefix = 'fw: ' stdin, stdout = setup_daemon() hostmap = {} @@ -223,13 +223,12 @@ def main(method_name, syslog, ttl): raise Fatal('expected GO but got %r' % line) _, _, args = line.partition(" ") - udp, user, ttl, tmark = args.strip().split(" ", 3) + udp, user, tmark = args.strip().split(" ", 2) udp = bool(int(udp)) if user == '-': user = None - ttl = int(ttl) - debug2('Got udp: %r, user: %r, ttl: %s, tmark: %s' % - (udp, user, ttl, tmark)) + debug2('Got udp: %r, user: %r, tmark: %s' % + (udp, user, tmark)) subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6] nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6] @@ -244,14 +243,14 @@ def main(method_name, syslog, ttl): method.setup_firewall( port_v6, dnsport_v6, nslist_v6, socket.AF_INET6, subnets_v6, udp, - user, ttl, tmark) + user, tmark) if subnets_v4 or nslist_v4: debug2('setting up IPv4.') method.setup_firewall( port_v4, dnsport_v4, nslist_v4, socket.AF_INET, subnets_v4, udp, - user, ttl, tmark) + user, tmark) flush_systemd_dns_cache() stdout.write('STARTED\n') diff --git a/sshuttle/linux.py b/sshuttle/linux.py index 7b0a471..5055fc0 100644 --- a/sshuttle/linux.py +++ b/sshuttle/linux.py @@ -49,25 +49,3 @@ def nft(family, table, action, *args): rv = ssubprocess.call(argv, env=get_env()) if rv: raise Fatal('%r returned %d' % (argv, rv)) - - -_no_ttl_module = False - - -def ipt_ttl(family, *args): - global _no_ttl_module - if not _no_ttl_module: - # we avoid infinite loops by generating server-side connections - # with ttl 63. This makes the client side not recapture those - # connections, in case client == server. - try: - argsplus = list(args) - ipt(family, *argsplus) - except Fatal: - ipt(family, *args) - # we only get here if the non-ttl attempt succeeds - log('WARNING: your iptables is missing ' - 'the ttl module.') - _no_ttl_module = True - else: - ipt(family, *args) diff --git a/sshuttle/methods/__init__.py b/sshuttle/methods/__init__.py index 0e4c49d..f8a77a9 100644 --- a/sshuttle/methods/__init__.py +++ b/sshuttle/methods/__init__.py @@ -91,7 +91,7 @@ class BaseMethod(object): (key, self.name)) def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): raise NotImplementedError() def restore_firewall(self, port, family, udp, user): diff --git a/sshuttle/methods/ipfw.py b/sshuttle/methods/ipfw.py index bda8968..0a3c44e 100644 --- a/sshuttle/methods/ipfw.py +++ b/sshuttle/methods/ipfw.py @@ -177,7 +177,6 @@ class Method(BaseMethod): sender.setsockopt(socket.SOL_IP, IP_BINDANY, 1) sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - sender.setsockopt(socket.SOL_IP, socket.IP_TTL, 63) sender.bind(srcip) sender.sendto(data, dstip) sender.close() @@ -189,7 +188,12 @@ class Method(BaseMethod): # udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVDSTADDR, 1) def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): + # TODO: The ttl hack to allow the host and server to run on + # the same machine has been removed but this method hasn't + # been updated yet. + ttl = 63 + # IPv6 not supported if family not in [socket.AF_INET]: raise Exception( diff --git a/sshuttle/methods/nat.py b/sshuttle/methods/nat.py index a7a661c..076d880 100644 --- a/sshuttle/methods/nat.py +++ b/sshuttle/methods/nat.py @@ -1,7 +1,7 @@ import socket from sshuttle.firewall import subnet_weight from sshuttle.helpers import family_to_string, which, debug2 -from sshuttle.linux import ipt, ipt_ttl, ipt_chain_exists, nonfatal +from sshuttle.linux import ipt, ipt_chain_exists, nonfatal from sshuttle.methods import BaseMethod @@ -13,7 +13,7 @@ class Method(BaseMethod): # recently-started one will win (because we use "-I OUTPUT 1" instead of # "-A OUTPUT"). def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): if family != socket.AF_INET and family != socket.AF_INET6: raise Exception( 'Address family "%s" unsupported by nat method_name' @@ -25,9 +25,6 @@ class Method(BaseMethod): def _ipt(*args): return ipt(family, table, *args) - def _ipt_ttl(*args): - return ipt_ttl(family, table, *args) - def _ipm(*args): return ipt(family, "mangle", *args) @@ -48,16 +45,6 @@ class Method(BaseMethod): _ipt('-I', 'OUTPUT', '1', *args) _ipt('-I', 'PREROUTING', '1', *args) - # This TTL hack allows the client and server to run on the - # same host. The connections the sshuttle server makes will - # have TTL set to 63. - if family == socket.AF_INET: - _ipt_ttl('-A', chain, '-j', 'RETURN', '-m', 'ttl', '--ttl', - '%s' % ttl) - else: # ipv6, ttl is renamed to 'hop limit' - _ipt_ttl('-A', chain, '-j', 'RETURN', '-m', 'hl', '--hl-eq', - '%s' % ttl) - # Redirect DNS traffic as requested. This includes routing traffic # to localhost DNS servers through sshuttle. for _, ip in [i for i in nslist if i[0] == family]: @@ -102,9 +89,6 @@ class Method(BaseMethod): def _ipt(*args): return ipt(family, table, *args) - def _ipt_ttl(*args): - return ipt_ttl(family, table, *args) - def _ipm(*args): return ipt(family, "mangle", *args) diff --git a/sshuttle/methods/nft.py b/sshuttle/methods/nft.py index 8f54c86..64ab3a6 100644 --- a/sshuttle/methods/nft.py +++ b/sshuttle/methods/nft.py @@ -13,7 +13,7 @@ class Method(BaseMethod): # recently-started one will win (because we use "-I OUTPUT 1" instead of # "-A OUTPUT"). def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): if udp: raise Exception("UDP not supported by nft") @@ -45,14 +45,6 @@ class Method(BaseMethod): else: _nft('add rule', chain, 'meta', 'nfproto', '!=', 'ipv6', 'return') - # This TTL hack allows the client and server to run on the - # same host. The connections the sshuttle server makes will - # have TTL set to 63. - if family == socket.AF_INET: - _nft('add rule', chain, 'ip ttl == 63 return') - elif family == socket.AF_INET6: - _nft('add rule', chain, 'ip6 hoplimit == 63 return') - # Strings to use below to simplify our code if family == socket.AF_INET: ip_version_l = 'ipv4' diff --git a/sshuttle/methods/pf.py b/sshuttle/methods/pf.py index dd8e245..c8fe3fd 100644 --- a/sshuttle/methods/pf.py +++ b/sshuttle/methods/pf.py @@ -448,7 +448,7 @@ class Method(BaseMethod): return sock.getsockname() def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): if family not in [socket.AF_INET, socket.AF_INET6]: raise Exception( 'Address family "%s" unsupported by pf method_name' diff --git a/sshuttle/methods/tproxy.py b/sshuttle/methods/tproxy.py index eb337fe..6c8fab0 100644 --- a/sshuttle/methods/tproxy.py +++ b/sshuttle/methods/tproxy.py @@ -1,7 +1,7 @@ import struct from sshuttle.firewall import subnet_weight from sshuttle.helpers import family_to_string -from sshuttle.linux import ipt, ipt_ttl, ipt_chain_exists +from sshuttle.linux import ipt, ipt_chain_exists from sshuttle.methods import BaseMethod from sshuttle.helpers import debug1, debug2, debug3, Fatal, which @@ -151,7 +151,7 @@ class Method(BaseMethod): udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVORIGDSTADDR, 1) def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, - user, ttl, tmark): + user, tmark): if family not in [socket.AF_INET, socket.AF_INET6]: raise Exception( 'Address family "%s" unsupported by tproxy method' @@ -162,9 +162,6 @@ class Method(BaseMethod): def _ipt(*args): return ipt(family, table, *args) - def _ipt_ttl(*args): - return ipt_ttl(family, table, *args) - def _ipt_proto_ports(proto, fport, lport): return proto + ('--dport', '%d:%d' % (fport, lport)) \ if fport else proto @@ -279,9 +276,6 @@ class Method(BaseMethod): def _ipt(*args): return ipt(family, table, *args) - def _ipt_ttl(*args): - return ipt_ttl(family, table, *args) - mark_chain = 'sshuttle-m-%s' % port tproxy_chain = 'sshuttle-t-%s' % port divert_chain = 'sshuttle-d-%s' % port diff --git a/sshuttle/options.py b/sshuttle/options.py index 0a311aa..a0a06c3 100644 --- a/sshuttle/options.py +++ b/sshuttle/options.py @@ -173,7 +173,7 @@ class MyArgumentParser(ArgumentParser): parser = MyArgumentParser( prog="sshuttle", - usage="%(prog)s [-l [ip:]port] [-r [user@]sshserver[:port]] <subnets...>", + usage="%(prog)s [-l [ip:]port] -r [user@]sshserver[:port] <subnets...>", fromfile_prefix_chars="@" ) parser.add_argument( @@ -390,15 +390,6 @@ parser.add_argument( """ ) parser.add_argument( - "--ttl", - type=int, - default=63, - help=""" - Override the TTL for the connections made by the sshuttle server. - Default is 63. - """ -) -parser.add_argument( "--hostwatch", action="store_true", help=""" diff --git a/sshuttle/server.py b/sshuttle/server.py index 645252b..b0c4367 100644 --- a/sshuttle/server.py +++ b/sshuttle/server.py @@ -152,7 +152,7 @@ class Hostwatch: class DnsProxy(Handler): - def __init__(self, mux, chan, request, to_nameserver, ttl): + def __init__(self, mux, chan, request, to_nameserver): Handler.__init__(self, []) self.timeout = time.time() + 30 self.mux = mux @@ -162,7 +162,6 @@ class DnsProxy(Handler): self.peers = {} self.to_ns_peer = None self.to_ns_port = None - self.ttl = ttl if to_nameserver is None: self.to_nameserver = None else: @@ -192,7 +191,6 @@ class DnsProxy(Handler): family, sockaddr = self._addrinfo(peer, port) sock = socket.socket(family, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_IP, socket.IP_TTL, self.ttl) sock.connect(sockaddr) self.peers[sock] = peer @@ -241,15 +239,13 @@ class DnsProxy(Handler): class UdpProxy(Handler): - def __init__(self, mux, chan, family, ttl): + def __init__(self, mux, chan, family): sock = socket.socket(family, socket.SOCK_DGRAM) Handler.__init__(self, [sock]) self.timeout = time.time() + 30 self.mux = mux self.chan = chan self.sock = sock - if family == socket.AF_INET: - self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl) def send(self, dstip, data): debug2('UDP: sending to %r port %d' % dstip) @@ -273,7 +269,7 @@ class UdpProxy(Handler): def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver, - auto_nets, ttl): + auto_nets): try: helpers.logprefix = ' s: ' debug1('Starting server with Python version %s' @@ -350,7 +346,7 @@ def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver, def dns_req(channel, data): debug2('Incoming DNS request channel=%d.' % channel) - h = DnsProxy(mux, channel, data, to_nameserver, ttl) + h = DnsProxy(mux, channel, data, to_nameserver) handlers.append(h) dnshandlers[channel] = h mux.got_dns_req = dns_req @@ -381,7 +377,7 @@ def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver, raise Fatal('UDP connection channel %d already open' % channel) else: - h = UdpProxy(mux, channel, family, ttl) + h = UdpProxy(mux, channel, family) handlers.append(h) udphandlers[channel] = h mux.got_udp_open = udp_open diff --git a/sshuttle/ssnet.py b/sshuttle/ssnet.py index b120d61..eebe227 100644 --- a/sshuttle/ssnet.py +++ b/sshuttle/ssnet.py @@ -586,7 +586,7 @@ class MuxWrapper(SockWrapper): def connect_dst(family, ip, port): debug2('Connecting to %s:%d' % (ip, port)) outsock = socket.socket(family) - outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 63) + return SockWrapper(outsock, outsock, connect_to=(ip, port), peername='%s:%d' % (ip, port)) |