mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-05-17 06:30:55 +02:00
Merge pull request #661 from skuhl/no-ttl
Remove ttl hack & require -r option.
This commit is contained in:
commit
bd00a530dd
@ -4,7 +4,7 @@ sshuttle
|
|||||||
|
|
||||||
Synopsis
|
Synopsis
|
||||||
--------
|
--------
|
||||||
**sshuttle** [*options*] [**-r** *[username@]sshserver[:port]*] \<*subnets* ...\>
|
**sshuttle** [*options*] **-r** *[username@]sshserver[:port]* \<*subnets* ...\>
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
@ -441,9 +441,7 @@ Example configuration file::
|
|||||||
Discussion
|
Discussion
|
||||||
----------
|
----------
|
||||||
When it starts, :program:`sshuttle` creates an ssh session to the
|
When it starts, :program:`sshuttle` creates an ssh session to the
|
||||||
server specified by the ``-r`` option. If ``-r`` is omitted,
|
server specified by the ``-r`` option.
|
||||||
it will start both its client and server locally, which is
|
|
||||||
sometimes useful for testing.
|
|
||||||
|
|
||||||
After connecting to the remote server, :program:`sshuttle` uploads its
|
After connecting to the remote server, :program:`sshuttle` uploads its
|
||||||
(python) source code to the remote end and executes it
|
(python) source code to the remote end and executes it
|
||||||
|
@ -20,7 +20,7 @@ Supports:
|
|||||||
|
|
||||||
Requires:
|
Requires:
|
||||||
|
|
||||||
* iptables DNAT, REDIRECT, and ttl modules. ip6tables for IPv6.
|
* iptables DNAT and REDIRECT modules. ip6tables for IPv6.
|
||||||
|
|
||||||
Linux with nft method
|
Linux with nft method
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -42,4 +42,4 @@ import sshuttle.cmdline_options as options # noqa: E402
|
|||||||
from sshuttle.server import main # noqa: E402
|
from sshuttle.server import main # noqa: E402
|
||||||
main(options.latency_control, options.latency_buffer_size,
|
main(options.latency_control, options.latency_buffer_size,
|
||||||
options.auto_hosts, options.to_nameserver,
|
options.auto_hosts, options.to_nameserver,
|
||||||
options.auto_nets, options.ttl)
|
options.auto_nets)
|
||||||
|
@ -44,6 +44,7 @@ def got_signal(signum, frame):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# Filename of the pidfile created by the sshuttle client.
|
||||||
_pidname = None
|
_pidname = None
|
||||||
|
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ class MultiListener:
|
|||||||
|
|
||||||
class FirewallClient:
|
class FirewallClient:
|
||||||
|
|
||||||
def __init__(self, method_name, sudo_pythonpath, ttl):
|
def __init__(self, method_name, sudo_pythonpath):
|
||||||
self.auto_nets = []
|
self.auto_nets = []
|
||||||
|
|
||||||
argvbase = ([sys.executable, sys.argv[0]] +
|
argvbase = ([sys.executable, sys.argv[0]] +
|
||||||
@ -260,7 +261,7 @@ class FirewallClient:
|
|||||||
|
|
||||||
def setup(self, subnets_include, subnets_exclude, nslist,
|
def setup(self, subnets_include, subnets_exclude, nslist,
|
||||||
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4, udp,
|
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4, udp,
|
||||||
user, ttl, tmark):
|
user, tmark):
|
||||||
self.subnets_include = subnets_include
|
self.subnets_include = subnets_include
|
||||||
self.subnets_exclude = subnets_exclude
|
self.subnets_exclude = subnets_exclude
|
||||||
self.nslist = nslist
|
self.nslist = nslist
|
||||||
@ -271,7 +272,6 @@ class FirewallClient:
|
|||||||
self.udp = udp
|
self.udp = udp
|
||||||
self.user = user
|
self.user = user
|
||||||
self.tmark = tmark
|
self.tmark = tmark
|
||||||
self.ttl = ttl
|
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
rv = self.p.poll()
|
rv = self.p.poll()
|
||||||
@ -310,9 +310,8 @@ class FirewallClient:
|
|||||||
else:
|
else:
|
||||||
user = b'%d' % self.user
|
user = b'%d' % self.user
|
||||||
|
|
||||||
self.pfile.write(b'GO %d %s %d %s\n' %
|
self.pfile.write(b'GO %d %s %s\n' %
|
||||||
(udp, user, self.ttl,
|
(udp, user, bytes(self.tmark, 'ascii')))
|
||||||
bytes(self.tmark, 'ascii')))
|
|
||||||
self.pfile.flush()
|
self.pfile.flush()
|
||||||
|
|
||||||
line = self.pfile.readline()
|
line = self.pfile.readline()
|
||||||
@ -457,7 +456,7 @@ def ondns(listener, method, mux, handlers):
|
|||||||
def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
|
def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
|
||||||
python, latency_control, latency_buffer_size,
|
python, latency_control, latency_buffer_size,
|
||||||
dns_listener, seed_hosts, auto_hosts, auto_nets, daemon,
|
dns_listener, seed_hosts, auto_hosts, auto_nets, daemon,
|
||||||
to_nameserver, ttl):
|
to_nameserver):
|
||||||
|
|
||||||
helpers.logprefix = 'c : '
|
helpers.logprefix = 'c : '
|
||||||
debug1('Starting client with Python version %s'
|
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,
|
latency_buffer_size=latency_buffer_size,
|
||||||
auto_hosts=auto_hosts,
|
auto_hosts=auto_hosts,
|
||||||
to_nameserver=to_nameserver,
|
to_nameserver=to_nameserver,
|
||||||
auto_nets=auto_nets,
|
auto_nets=auto_nets))
|
||||||
ttl=ttl))
|
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.args[0] == errno.EPIPE:
|
if e.args[0] == errno.EPIPE:
|
||||||
raise Fatal("failed to establish ssh session (1)")
|
raise Fatal("failed to establish ssh session (1)")
|
||||||
@ -587,6 +585,7 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
|
|||||||
% (expected, initstring))
|
% (expected, initstring))
|
||||||
log('Connected to server.')
|
log('Connected to server.')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
if daemon:
|
if daemon:
|
||||||
daemonize()
|
daemonize()
|
||||||
log('daemonizing (%s).' % _pidname)
|
log('daemonizing (%s).' % _pidname)
|
||||||
@ -673,12 +672,11 @@ def main(listenip_v6, listenip_v4,
|
|||||||
latency_buffer_size, dns, nslist,
|
latency_buffer_size, dns, nslist,
|
||||||
method_name, seed_hosts, auto_hosts, auto_nets,
|
method_name, seed_hosts, auto_hosts, auto_nets,
|
||||||
subnets_include, subnets_exclude, daemon, to_nameserver, pidfile,
|
subnets_include, subnets_exclude, daemon, to_nameserver, pidfile,
|
||||||
user, sudo_pythonpath, tmark, ttl):
|
user, sudo_pythonpath, tmark):
|
||||||
|
|
||||||
if not remotename:
|
if not remotename:
|
||||||
print("WARNING: You must specify -r/--remote to securely route "
|
raise Fatal("You must use -r/--remote to specify a remote "
|
||||||
"traffic to a remote machine. Running without -r/--remote "
|
"host to route traffic through.")
|
||||||
"is only recommended for testing.")
|
|
||||||
|
|
||||||
if daemon:
|
if daemon:
|
||||||
try:
|
try:
|
||||||
@ -689,7 +687,7 @@ def main(listenip_v6, listenip_v4,
|
|||||||
debug1('Starting sshuttle proxy (version %s).' % __version__)
|
debug1('Starting sshuttle proxy (version %s).' % __version__)
|
||||||
helpers.logprefix = 'c : '
|
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
|
# nslist is the list of name severs to intercept. If --dns is
|
||||||
# used, we add all DNS servers in resolv.conf. Otherwise, the list
|
# 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
|
# start the firewall
|
||||||
fw.setup(subnets_include, subnets_exclude, nslist,
|
fw.setup(subnets_include, subnets_exclude, nslist,
|
||||||
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4,
|
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4,
|
||||||
required.udp, user, ttl, tmark)
|
required.udp, user, tmark)
|
||||||
|
|
||||||
# start the client process
|
# start the client process
|
||||||
try:
|
try:
|
||||||
return _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
|
return _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
|
||||||
python, latency_control, latency_buffer_size,
|
python, latency_control, latency_buffer_size,
|
||||||
dns_listener, seed_hosts, auto_hosts, auto_nets,
|
dns_listener, seed_hosts, auto_hosts, auto_nets,
|
||||||
daemon, to_nameserver, ttl)
|
daemon, to_nameserver)
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
if daemon:
|
if daemon:
|
||||||
|
@ -43,7 +43,7 @@ def main():
|
|||||||
if opt.firewall:
|
if opt.firewall:
|
||||||
if opt.subnets or opt.subnets_file:
|
if opt.subnets or opt.subnets_file:
|
||||||
parser.error('exactly zero arguments expected')
|
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:
|
elif opt.hostwatch:
|
||||||
return hostwatch.hw_main(opt.subnets, opt.auto_hosts)
|
return hostwatch.hw_main(opt.subnets, opt.auto_hosts)
|
||||||
else:
|
else:
|
||||||
@ -116,8 +116,7 @@ def main():
|
|||||||
opt.pidfile,
|
opt.pidfile,
|
||||||
opt.user,
|
opt.user,
|
||||||
opt.sudo_pythonpath,
|
opt.sudo_pythonpath,
|
||||||
opt.tmark,
|
opt.tmark)
|
||||||
opt.ttl)
|
|
||||||
|
|
||||||
if return_code == 0:
|
if return_code == 0:
|
||||||
log('Normal exit code, exiting...')
|
log('Normal exit code, exiting...')
|
||||||
|
@ -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
|
# 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
|
# supercede it in the transproxy list, at least, so the leftover rules
|
||||||
# are hopefully harmless.
|
# are hopefully harmless.
|
||||||
def main(method_name, syslog, ttl):
|
def main(method_name, syslog):
|
||||||
helpers.logprefix = 'fw: '
|
helpers.logprefix = 'fw: '
|
||||||
stdin, stdout = setup_daemon()
|
stdin, stdout = setup_daemon()
|
||||||
hostmap = {}
|
hostmap = {}
|
||||||
@ -223,13 +223,12 @@ def main(method_name, syslog, ttl):
|
|||||||
raise Fatal('expected GO but got %r' % line)
|
raise Fatal('expected GO but got %r' % line)
|
||||||
|
|
||||||
_, _, args = line.partition(" ")
|
_, _, args = line.partition(" ")
|
||||||
udp, user, ttl, tmark = args.strip().split(" ", 3)
|
udp, user, tmark = args.strip().split(" ", 2)
|
||||||
udp = bool(int(udp))
|
udp = bool(int(udp))
|
||||||
if user == '-':
|
if user == '-':
|
||||||
user = None
|
user = None
|
||||||
ttl = int(ttl)
|
debug2('Got udp: %r, user: %r, tmark: %s' %
|
||||||
debug2('Got udp: %r, user: %r, ttl: %s, tmark: %s' %
|
(udp, user, tmark))
|
||||||
(udp, user, ttl, tmark))
|
|
||||||
|
|
||||||
subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6]
|
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]
|
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(
|
method.setup_firewall(
|
||||||
port_v6, dnsport_v6, nslist_v6,
|
port_v6, dnsport_v6, nslist_v6,
|
||||||
socket.AF_INET6, subnets_v6, udp,
|
socket.AF_INET6, subnets_v6, udp,
|
||||||
user, ttl, tmark)
|
user, tmark)
|
||||||
|
|
||||||
if subnets_v4 or nslist_v4:
|
if subnets_v4 or nslist_v4:
|
||||||
debug2('setting up IPv4.')
|
debug2('setting up IPv4.')
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
port_v4, dnsport_v4, nslist_v4,
|
port_v4, dnsport_v4, nslist_v4,
|
||||||
socket.AF_INET, subnets_v4, udp,
|
socket.AF_INET, subnets_v4, udp,
|
||||||
user, ttl, tmark)
|
user, tmark)
|
||||||
|
|
||||||
flush_systemd_dns_cache()
|
flush_systemd_dns_cache()
|
||||||
stdout.write('STARTED\n')
|
stdout.write('STARTED\n')
|
||||||
|
@ -49,25 +49,3 @@ def nft(family, table, action, *args):
|
|||||||
rv = ssubprocess.call(argv, env=get_env())
|
rv = ssubprocess.call(argv, env=get_env())
|
||||||
if rv:
|
if rv:
|
||||||
raise Fatal('%r returned %d' % (argv, 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)
|
|
||||||
|
@ -91,7 +91,7 @@ class BaseMethod(object):
|
|||||||
(key, self.name))
|
(key, self.name))
|
||||||
|
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
||||||
user, ttl, tmark):
|
user, tmark):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def restore_firewall(self, port, family, udp, user):
|
def restore_firewall(self, port, family, udp, user):
|
||||||
|
@ -177,7 +177,6 @@ class Method(BaseMethod):
|
|||||||
sender.setsockopt(socket.SOL_IP, IP_BINDANY, 1)
|
sender.setsockopt(socket.SOL_IP, IP_BINDANY, 1)
|
||||||
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
||||||
sender.setsockopt(socket.SOL_IP, socket.IP_TTL, 63)
|
|
||||||
sender.bind(srcip)
|
sender.bind(srcip)
|
||||||
sender.sendto(data, dstip)
|
sender.sendto(data, dstip)
|
||||||
sender.close()
|
sender.close()
|
||||||
@ -189,7 +188,12 @@ class Method(BaseMethod):
|
|||||||
# udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVDSTADDR, 1)
|
# udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVDSTADDR, 1)
|
||||||
|
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
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
|
# IPv6 not supported
|
||||||
if family not in [socket.AF_INET]:
|
if family not in [socket.AF_INET]:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import socket
|
import socket
|
||||||
from sshuttle.firewall import subnet_weight
|
from sshuttle.firewall import subnet_weight
|
||||||
from sshuttle.helpers import family_to_string, which, debug2
|
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
|
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
|
# recently-started one will win (because we use "-I OUTPUT 1" instead of
|
||||||
# "-A OUTPUT").
|
# "-A OUTPUT").
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
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:
|
if family != socket.AF_INET and family != socket.AF_INET6:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'Address family "%s" unsupported by nat method_name'
|
'Address family "%s" unsupported by nat method_name'
|
||||||
@ -25,9 +25,6 @@ class Method(BaseMethod):
|
|||||||
def _ipt(*args):
|
def _ipt(*args):
|
||||||
return ipt(family, table, *args)
|
return ipt(family, table, *args)
|
||||||
|
|
||||||
def _ipt_ttl(*args):
|
|
||||||
return ipt_ttl(family, table, *args)
|
|
||||||
|
|
||||||
def _ipm(*args):
|
def _ipm(*args):
|
||||||
return ipt(family, "mangle", *args)
|
return ipt(family, "mangle", *args)
|
||||||
|
|
||||||
@ -48,16 +45,6 @@ class Method(BaseMethod):
|
|||||||
_ipt('-I', 'OUTPUT', '1', *args)
|
_ipt('-I', 'OUTPUT', '1', *args)
|
||||||
_ipt('-I', 'PREROUTING', '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
|
# Redirect DNS traffic as requested. This includes routing traffic
|
||||||
# to localhost DNS servers through sshuttle.
|
# to localhost DNS servers through sshuttle.
|
||||||
for _, ip in [i for i in nslist if i[0] == family]:
|
for _, ip in [i for i in nslist if i[0] == family]:
|
||||||
@ -102,9 +89,6 @@ class Method(BaseMethod):
|
|||||||
def _ipt(*args):
|
def _ipt(*args):
|
||||||
return ipt(family, table, *args)
|
return ipt(family, table, *args)
|
||||||
|
|
||||||
def _ipt_ttl(*args):
|
|
||||||
return ipt_ttl(family, table, *args)
|
|
||||||
|
|
||||||
def _ipm(*args):
|
def _ipm(*args):
|
||||||
return ipt(family, "mangle", *args)
|
return ipt(family, "mangle", *args)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ class Method(BaseMethod):
|
|||||||
# recently-started one will win (because we use "-I OUTPUT 1" instead of
|
# recently-started one will win (because we use "-I OUTPUT 1" instead of
|
||||||
# "-A OUTPUT").
|
# "-A OUTPUT").
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
||||||
user, ttl, tmark):
|
user, tmark):
|
||||||
if udp:
|
if udp:
|
||||||
raise Exception("UDP not supported by nft")
|
raise Exception("UDP not supported by nft")
|
||||||
|
|
||||||
@ -45,14 +45,6 @@ class Method(BaseMethod):
|
|||||||
else:
|
else:
|
||||||
_nft('add rule', chain, 'meta', 'nfproto', '!=', 'ipv6', 'return')
|
_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
|
# Strings to use below to simplify our code
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET:
|
||||||
ip_version_l = 'ipv4'
|
ip_version_l = 'ipv4'
|
||||||
|
@ -448,7 +448,7 @@ class Method(BaseMethod):
|
|||||||
return sock.getsockname()
|
return sock.getsockname()
|
||||||
|
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
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]:
|
if family not in [socket.AF_INET, socket.AF_INET6]:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'Address family "%s" unsupported by pf method_name'
|
'Address family "%s" unsupported by pf method_name'
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import struct
|
import struct
|
||||||
from sshuttle.firewall import subnet_weight
|
from sshuttle.firewall import subnet_weight
|
||||||
from sshuttle.helpers import family_to_string
|
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.methods import BaseMethod
|
||||||
from sshuttle.helpers import debug1, debug2, debug3, Fatal, which
|
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)
|
udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVORIGDSTADDR, 1)
|
||||||
|
|
||||||
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
|
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]:
|
if family not in [socket.AF_INET, socket.AF_INET6]:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'Address family "%s" unsupported by tproxy method'
|
'Address family "%s" unsupported by tproxy method'
|
||||||
@ -162,9 +162,6 @@ class Method(BaseMethod):
|
|||||||
def _ipt(*args):
|
def _ipt(*args):
|
||||||
return ipt(family, table, *args)
|
return ipt(family, table, *args)
|
||||||
|
|
||||||
def _ipt_ttl(*args):
|
|
||||||
return ipt_ttl(family, table, *args)
|
|
||||||
|
|
||||||
def _ipt_proto_ports(proto, fport, lport):
|
def _ipt_proto_ports(proto, fport, lport):
|
||||||
return proto + ('--dport', '%d:%d' % (fport, lport)) \
|
return proto + ('--dport', '%d:%d' % (fport, lport)) \
|
||||||
if fport else proto
|
if fport else proto
|
||||||
@ -279,9 +276,6 @@ class Method(BaseMethod):
|
|||||||
def _ipt(*args):
|
def _ipt(*args):
|
||||||
return ipt(family, table, *args)
|
return ipt(family, table, *args)
|
||||||
|
|
||||||
def _ipt_ttl(*args):
|
|
||||||
return ipt_ttl(family, table, *args)
|
|
||||||
|
|
||||||
mark_chain = 'sshuttle-m-%s' % port
|
mark_chain = 'sshuttle-m-%s' % port
|
||||||
tproxy_chain = 'sshuttle-t-%s' % port
|
tproxy_chain = 'sshuttle-t-%s' % port
|
||||||
divert_chain = 'sshuttle-d-%s' % port
|
divert_chain = 'sshuttle-d-%s' % port
|
||||||
|
@ -173,7 +173,7 @@ class MyArgumentParser(ArgumentParser):
|
|||||||
|
|
||||||
parser = MyArgumentParser(
|
parser = MyArgumentParser(
|
||||||
prog="sshuttle",
|
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="@"
|
fromfile_prefix_chars="@"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@ -389,15 +389,6 @@ parser.add_argument(
|
|||||||
(internal use only)
|
(internal use only)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
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(
|
parser.add_argument(
|
||||||
"--hostwatch",
|
"--hostwatch",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
@ -152,7 +152,7 @@ class Hostwatch:
|
|||||||
|
|
||||||
class DnsProxy(Handler):
|
class DnsProxy(Handler):
|
||||||
|
|
||||||
def __init__(self, mux, chan, request, to_nameserver, ttl):
|
def __init__(self, mux, chan, request, to_nameserver):
|
||||||
Handler.__init__(self, [])
|
Handler.__init__(self, [])
|
||||||
self.timeout = time.time() + 30
|
self.timeout = time.time() + 30
|
||||||
self.mux = mux
|
self.mux = mux
|
||||||
@ -162,7 +162,6 @@ class DnsProxy(Handler):
|
|||||||
self.peers = {}
|
self.peers = {}
|
||||||
self.to_ns_peer = None
|
self.to_ns_peer = None
|
||||||
self.to_ns_port = None
|
self.to_ns_port = None
|
||||||
self.ttl = ttl
|
|
||||||
if to_nameserver is None:
|
if to_nameserver is None:
|
||||||
self.to_nameserver = None
|
self.to_nameserver = None
|
||||||
else:
|
else:
|
||||||
@ -192,7 +191,6 @@ class DnsProxy(Handler):
|
|||||||
|
|
||||||
family, sockaddr = self._addrinfo(peer, port)
|
family, sockaddr = self._addrinfo(peer, port)
|
||||||
sock = socket.socket(family, socket.SOCK_DGRAM)
|
sock = socket.socket(family, socket.SOCK_DGRAM)
|
||||||
sock.setsockopt(socket.SOL_IP, socket.IP_TTL, self.ttl)
|
|
||||||
sock.connect(sockaddr)
|
sock.connect(sockaddr)
|
||||||
|
|
||||||
self.peers[sock] = peer
|
self.peers[sock] = peer
|
||||||
@ -241,15 +239,13 @@ class DnsProxy(Handler):
|
|||||||
|
|
||||||
class UdpProxy(Handler):
|
class UdpProxy(Handler):
|
||||||
|
|
||||||
def __init__(self, mux, chan, family, ttl):
|
def __init__(self, mux, chan, family):
|
||||||
sock = socket.socket(family, socket.SOCK_DGRAM)
|
sock = socket.socket(family, socket.SOCK_DGRAM)
|
||||||
Handler.__init__(self, [sock])
|
Handler.__init__(self, [sock])
|
||||||
self.timeout = time.time() + 30
|
self.timeout = time.time() + 30
|
||||||
self.mux = mux
|
self.mux = mux
|
||||||
self.chan = chan
|
self.chan = chan
|
||||||
self.sock = sock
|
self.sock = sock
|
||||||
if family == socket.AF_INET:
|
|
||||||
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
|
|
||||||
|
|
||||||
def send(self, dstip, data):
|
def send(self, dstip, data):
|
||||||
debug2('UDP: sending to %r port %d' % dstip)
|
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,
|
def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver,
|
||||||
auto_nets, ttl):
|
auto_nets):
|
||||||
try:
|
try:
|
||||||
helpers.logprefix = ' s: '
|
helpers.logprefix = ' s: '
|
||||||
debug1('Starting server with Python version %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):
|
def dns_req(channel, data):
|
||||||
debug2('Incoming DNS request channel=%d.' % channel)
|
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)
|
handlers.append(h)
|
||||||
dnshandlers[channel] = h
|
dnshandlers[channel] = h
|
||||||
mux.got_dns_req = dns_req
|
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' %
|
raise Fatal('UDP connection channel %d already open' %
|
||||||
channel)
|
channel)
|
||||||
else:
|
else:
|
||||||
h = UdpProxy(mux, channel, family, ttl)
|
h = UdpProxy(mux, channel, family)
|
||||||
handlers.append(h)
|
handlers.append(h)
|
||||||
udphandlers[channel] = h
|
udphandlers[channel] = h
|
||||||
mux.got_udp_open = udp_open
|
mux.got_udp_open = udp_open
|
||||||
|
@ -586,7 +586,7 @@ class MuxWrapper(SockWrapper):
|
|||||||
def connect_dst(family, ip, port):
|
def connect_dst(family, ip, port):
|
||||||
debug2('Connecting to %s:%d' % (ip, port))
|
debug2('Connecting to %s:%d' % (ip, port))
|
||||||
outsock = socket.socket(family)
|
outsock = socket.socket(family)
|
||||||
outsock.setsockopt(socket.SOL_IP, socket.IP_TTL, 63)
|
|
||||||
return SockWrapper(outsock, outsock,
|
return SockWrapper(outsock, outsock,
|
||||||
connect_to=(ip, port),
|
connect_to=(ip, port),
|
||||||
peername='%s:%d' % (ip, port))
|
peername='%s:%d' % (ip, port))
|
||||||
|
@ -15,7 +15,7 @@ NSLIST
|
|||||||
{inet},1.2.3.33
|
{inet},1.2.3.33
|
||||||
{inet6},2404:6800:4004:80c::33
|
{inet6},2404:6800:4004:80c::33
|
||||||
PORTS 1024,1025,1026,1027
|
PORTS 1024,1025,1026,1027
|
||||||
GO 1 - 63 0x01
|
GO 1 - 0x01
|
||||||
HOST 1.2.3.3,existing
|
HOST 1.2.3.3,existing
|
||||||
""".format(inet=AF_INET, inet6=AF_INET6))
|
""".format(inet=AF_INET, inet6=AF_INET6))
|
||||||
stdout = Mock()
|
stdout = Mock()
|
||||||
@ -100,7 +100,7 @@ def test_main(mock_get_method, mock_setup_daemon, mock_rewrite_etc_hosts):
|
|||||||
mock_get_method("not_auto").name = "test"
|
mock_get_method("not_auto").name = "test"
|
||||||
mock_get_method.reset_mock()
|
mock_get_method.reset_mock()
|
||||||
|
|
||||||
sshuttle.firewall.main("not_auto", False, 63)
|
sshuttle.firewall.main("not_auto", False)
|
||||||
|
|
||||||
assert mock_rewrite_etc_hosts.mock_calls == [
|
assert mock_rewrite_etc_hosts.mock_calls == [
|
||||||
call({'1.2.3.3': 'existing'}, 1024),
|
call({'1.2.3.3': 'existing'}, 1024),
|
||||||
@ -126,7 +126,7 @@ def test_main(mock_get_method, mock_setup_daemon, mock_rewrite_etc_hosts):
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 80, 80)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 80, 80)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01'),
|
'0x01'),
|
||||||
call().setup_firewall(
|
call().setup_firewall(
|
||||||
1025, 1027,
|
1025, 1027,
|
||||||
[(AF_INET, u'1.2.3.33')],
|
[(AF_INET, u'1.2.3.33')],
|
||||||
@ -135,7 +135,7 @@ def test_main(mock_get_method, mock_setup_daemon, mock_rewrite_etc_hosts):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01'),
|
'0x01'),
|
||||||
call().restore_firewall(1024, AF_INET6, True, None),
|
call().restore_firewall(1024, AF_INET6, True, None),
|
||||||
call().restore_firewall(1025, AF_INET, True, None),
|
call().restore_firewall(1025, AF_INET, True, None),
|
||||||
]
|
]
|
||||||
|
@ -85,15 +85,13 @@ def test_firewall_command():
|
|||||||
|
|
||||||
|
|
||||||
@patch('sshuttle.methods.nat.ipt')
|
@patch('sshuttle.methods.nat.ipt')
|
||||||
@patch('sshuttle.methods.nat.ipt_ttl')
|
|
||||||
@patch('sshuttle.methods.nat.ipt_chain_exists')
|
@patch('sshuttle.methods.nat.ipt_chain_exists')
|
||||||
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt):
|
||||||
mock_ipt_chain_exists.return_value = True
|
mock_ipt_chain_exists.return_value = True
|
||||||
method = get_method('nat')
|
method = get_method('nat')
|
||||||
assert method.name == 'nat'
|
assert method.name == 'nat'
|
||||||
|
|
||||||
assert mock_ipt_chain_exists.mock_calls == []
|
assert mock_ipt_chain_exists.mock_calls == []
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == []
|
assert mock_ipt.mock_calls == []
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
1024, 1026,
|
1024, 1026,
|
||||||
@ -103,15 +101,11 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 80, 80)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 80, 80)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
|
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET6, 'nat', 'sshuttle-1024')
|
call(AF_INET6, 'nat', 'sshuttle-1024')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == [
|
|
||||||
call(AF_INET6, 'nat', '-A', 'sshuttle-1024', '-j', 'RETURN',
|
|
||||||
'-m', 'hl', '--hl-eq', '63')
|
|
||||||
]
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET6, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1024'),
|
call(AF_INET6, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1024'),
|
||||||
call(AF_INET6, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1024'),
|
call(AF_INET6, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1024'),
|
||||||
@ -134,11 +128,9 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
'--to-ports', '1024')
|
'--to-ports', '1024')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
assert mock_ipt_chain_exists.mock_calls == []
|
assert mock_ipt_chain_exists.mock_calls == []
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == []
|
assert mock_ipt.mock_calls == []
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
with pytest.raises(Exception) as excinfo:
|
||||||
@ -150,10 +142,9 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert str(excinfo.value) == 'UDP not supported by nat method_name'
|
assert str(excinfo.value) == 'UDP not supported by nat method_name'
|
||||||
assert mock_ipt_chain_exists.mock_calls == []
|
assert mock_ipt_chain_exists.mock_calls == []
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == []
|
assert mock_ipt.mock_calls == []
|
||||||
|
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
@ -164,14 +155,10 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
(AF_INET, 32, True, u'1.2.3.66', 8080, 8080)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET, 'nat', 'sshuttle-1025')
|
call(AF_INET, 'nat', 'sshuttle-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == [
|
|
||||||
call(AF_INET, 'nat', '-A', 'sshuttle-1025', '-j', 'RETURN',
|
|
||||||
'-m', 'ttl', '--ttl', '63')
|
|
||||||
]
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
|
call(AF_INET, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
|
||||||
call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1025'),
|
call(AF_INET, 'nat', '-D', 'PREROUTING', '-j', 'sshuttle-1025'),
|
||||||
@ -193,14 +180,12 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
'--to-ports', '1025')
|
'--to-ports', '1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
method.restore_firewall(1025, AF_INET, False, None)
|
method.restore_firewall(1025, AF_INET, False, None)
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET, 'nat', 'sshuttle-1025')
|
call(AF_INET, 'nat', 'sshuttle-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET, 'nat', '-D', 'OUTPUT', '-j',
|
call(AF_INET, 'nat', '-D', 'OUTPUT', '-j',
|
||||||
'sshuttle-1025'),
|
'sshuttle-1025'),
|
||||||
@ -210,14 +195,12 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET, 'nat', '-X', 'sshuttle-1025')
|
call(AF_INET, 'nat', '-X', 'sshuttle-1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
method.restore_firewall(1025, AF_INET6, False, None)
|
method.restore_firewall(1025, AF_INET6, False, None)
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET6, 'nat', 'sshuttle-1025')
|
call(AF_INET6, 'nat', 'sshuttle-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET6, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
|
call(AF_INET6, 'nat', '-D', 'OUTPUT', '-j', 'sshuttle-1025'),
|
||||||
call(AF_INET6, 'nat', '-D', 'PREROUTING', '-j',
|
call(AF_INET6, 'nat', '-D', 'PREROUTING', '-j',
|
||||||
@ -226,5 +209,4 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET6, 'nat', '-X', 'sshuttle-1025')
|
call(AF_INET6, 'nat', '-X', 'sshuttle-1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
@ -187,7 +187,7 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ioctl.mock_calls == [
|
assert mock_ioctl.mock_calls == [
|
||||||
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
||||||
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
@ -227,7 +227,7 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
assert mock_pf_get_dev.mock_calls == []
|
||||||
assert mock_ioctl.mock_calls == []
|
assert mock_ioctl.mock_calls == []
|
||||||
@ -241,7 +241,7 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ioctl.mock_calls == [
|
assert mock_ioctl.mock_calls == [
|
||||||
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
||||||
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
@ -302,7 +302,7 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
|
|
||||||
assert mock_pfctl.mock_calls == [
|
assert mock_pfctl.mock_calls == [
|
||||||
call('-s all'),
|
call('-s all'),
|
||||||
@ -335,7 +335,7 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
assert mock_pf_get_dev.mock_calls == []
|
||||||
assert mock_ioctl.mock_calls == []
|
assert mock_ioctl.mock_calls == []
|
||||||
@ -349,7 +349,7 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ioctl.mock_calls == [
|
assert mock_ioctl.mock_calls == [
|
||||||
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
||||||
call(mock_pf_get_dev(), 0xCBE0441A, ANY),
|
call(mock_pf_get_dev(), 0xCBE0441A, ANY),
|
||||||
@ -408,7 +408,7 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
|
|
||||||
assert mock_ioctl.mock_calls == [
|
assert mock_ioctl.mock_calls == [
|
||||||
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
||||||
@ -445,7 +445,7 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
assert str(excinfo.value) == 'UDP not supported by pf method_name'
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
assert mock_pf_get_dev.mock_calls == []
|
||||||
assert mock_ioctl.mock_calls == []
|
assert mock_ioctl.mock_calls == []
|
||||||
@ -459,7 +459,7 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
False,
|
False,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ioctl.mock_calls == [
|
assert mock_ioctl.mock_calls == [
|
||||||
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
||||||
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
call(mock_pf_get_dev(), 0xcd60441a, ANY),
|
||||||
|
@ -92,9 +92,8 @@ def test_firewall_command():
|
|||||||
|
|
||||||
|
|
||||||
@patch('sshuttle.methods.tproxy.ipt')
|
@patch('sshuttle.methods.tproxy.ipt')
|
||||||
@patch('sshuttle.methods.tproxy.ipt_ttl')
|
|
||||||
@patch('sshuttle.methods.tproxy.ipt_chain_exists')
|
@patch('sshuttle.methods.tproxy.ipt_chain_exists')
|
||||||
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
def test_setup_firewall(mock_ipt_chain_exists, mock_ipt):
|
||||||
mock_ipt_chain_exists.return_value = True
|
mock_ipt_chain_exists.return_value = True
|
||||||
method = get_method('tproxy')
|
method = get_method('tproxy')
|
||||||
assert method.name == 'tproxy'
|
assert method.name == 'tproxy'
|
||||||
@ -109,13 +108,12 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
(AF_INET6, 128, True, u'2404:6800:4004:80c::101f', 8080, 8080)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET6, 'mangle', 'sshuttle-m-1024'),
|
call(AF_INET6, 'mangle', 'sshuttle-m-1024'),
|
||||||
call(AF_INET6, 'mangle', 'sshuttle-t-1024'),
|
call(AF_INET6, 'mangle', 'sshuttle-t-1024'),
|
||||||
call(AF_INET6, 'mangle', 'sshuttle-d-1024')
|
call(AF_INET6, 'mangle', 'sshuttle-d-1024')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1024'),
|
call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1024'),
|
||||||
call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1024'),
|
call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1024'),
|
||||||
@ -182,7 +180,6 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
'--on-port', '1024')
|
'--on-port', '1024')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
method.restore_firewall(1025, AF_INET6, True, None)
|
method.restore_firewall(1025, AF_INET6, True, None)
|
||||||
@ -191,7 +188,6 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET6, 'mangle', 'sshuttle-t-1025'),
|
call(AF_INET6, 'mangle', 'sshuttle-t-1025'),
|
||||||
call(AF_INET6, 'mangle', 'sshuttle-d-1025')
|
call(AF_INET6, 'mangle', 'sshuttle-d-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
call(AF_INET6, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
||||||
call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1025'),
|
call(AF_INET6, 'mangle', '-F', 'sshuttle-m-1025'),
|
||||||
@ -203,7 +199,6 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET6, 'mangle', '-X', 'sshuttle-d-1025')
|
call(AF_INET6, 'mangle', '-X', 'sshuttle-d-1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
# IPV4
|
# IPV4
|
||||||
@ -216,13 +211,12 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
(AF_INET, 32, True, u'1.2.3.66', 80, 80)],
|
||||||
True,
|
True,
|
||||||
None,
|
None,
|
||||||
63, '0x01')
|
'0x01')
|
||||||
assert mock_ipt_chain_exists.mock_calls == [
|
assert mock_ipt_chain_exists.mock_calls == [
|
||||||
call(AF_INET, 'mangle', 'sshuttle-m-1025'),
|
call(AF_INET, 'mangle', 'sshuttle-m-1025'),
|
||||||
call(AF_INET, 'mangle', 'sshuttle-t-1025'),
|
call(AF_INET, 'mangle', 'sshuttle-t-1025'),
|
||||||
call(AF_INET, 'mangle', 'sshuttle-d-1025')
|
call(AF_INET, 'mangle', 'sshuttle-d-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
||||||
call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
|
call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
|
||||||
@ -284,7 +278,6 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
'-m', 'udp', '-p', 'udp', '--on-port', '1025')
|
'-m', 'udp', '-p', 'udp', '--on-port', '1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
|
||||||
method.restore_firewall(1025, AF_INET, True, None)
|
method.restore_firewall(1025, AF_INET, True, None)
|
||||||
@ -293,7 +286,6 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET, 'mangle', 'sshuttle-t-1025'),
|
call(AF_INET, 'mangle', 'sshuttle-t-1025'),
|
||||||
call(AF_INET, 'mangle', 'sshuttle-d-1025')
|
call(AF_INET, 'mangle', 'sshuttle-d-1025')
|
||||||
]
|
]
|
||||||
assert mock_ipt_ttl.mock_calls == []
|
|
||||||
assert mock_ipt.mock_calls == [
|
assert mock_ipt.mock_calls == [
|
||||||
call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
call(AF_INET, 'mangle', '-D', 'OUTPUT', '-j', 'sshuttle-m-1025'),
|
||||||
call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
|
call(AF_INET, 'mangle', '-F', 'sshuttle-m-1025'),
|
||||||
@ -305,5 +297,4 @@ def test_setup_firewall(mock_ipt_chain_exists, mock_ipt_ttl, mock_ipt):
|
|||||||
call(AF_INET, 'mangle', '-X', 'sshuttle-d-1025')
|
call(AF_INET, 'mangle', '-X', 'sshuttle-d-1025')
|
||||||
]
|
]
|
||||||
mock_ipt_chain_exists.reset_mock()
|
mock_ipt_chain_exists.reset_mock()
|
||||||
mock_ipt_ttl.reset_mock()
|
|
||||||
mock_ipt.reset_mock()
|
mock_ipt.reset_mock()
|
||||||
|
Loading…
Reference in New Issue
Block a user