mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-04-23 10:49:35 +02:00
Merge pull request #108 from vieira/pf-ipv6
IPv6 support for OSX and BSDs
This commit is contained in:
commit
1ffc3f52a1
@ -549,6 +549,7 @@ def main(listenip_v6, listenip_v4,
|
|||||||
listenip_v6 = None
|
listenip_v6 = None
|
||||||
|
|
||||||
required.ipv6 = len(subnets_v6) > 0 or listenip_v6 is not None
|
required.ipv6 = len(subnets_v6) > 0 or listenip_v6 is not None
|
||||||
|
required.ipv4 = len(subnets_v4) > 0 or listenip_v4 is not None
|
||||||
required.udp = avail.udp
|
required.udp = avail.udp
|
||||||
required.dns = len(nslist) > 0
|
required.dns = len(nslist) > 0
|
||||||
|
|
||||||
@ -571,6 +572,14 @@ def main(listenip_v6, listenip_v4,
|
|||||||
if listenip_v4 == "auto":
|
if listenip_v4 == "auto":
|
||||||
listenip_v4 = ('127.0.0.1', 0)
|
listenip_v4 = ('127.0.0.1', 0)
|
||||||
|
|
||||||
|
if required.ipv4 and \
|
||||||
|
not any(listenip_v4[0] == sex[1] for sex in subnets_v4):
|
||||||
|
subnets_exclude.append((socket.AF_INET, listenip_v4[0], 32))
|
||||||
|
|
||||||
|
if required.ipv6 and \
|
||||||
|
not any(listenip_v6[0] == sex[1] for sex in subnets_v6):
|
||||||
|
subnets_exclude.append((socket.AF_INET6, listenip_v6[0], 128))
|
||||||
|
|
||||||
if listenip_v6 and listenip_v6[1] and listenip_v4 and listenip_v4[1]:
|
if listenip_v6 and listenip_v6[1] and listenip_v4 and listenip_v4[1]:
|
||||||
# if both ports given, no need to search for a spare port
|
# if both ports given, no need to search for a spare port
|
||||||
ports = [0, ]
|
ports = [0, ]
|
||||||
|
@ -11,7 +11,7 @@ from sshuttle.helpers import debug1, debug2, debug3, Fatal, family_to_string
|
|||||||
from sshuttle.methods import BaseMethod
|
from sshuttle.methods import BaseMethod
|
||||||
|
|
||||||
|
|
||||||
_pf_context = {'started_by_sshuttle': False, 'Xtoken': None}
|
_pf_context = {'started_by_sshuttle': False, 'Xtoken': []}
|
||||||
_pf_fd = None
|
_pf_fd = None
|
||||||
|
|
||||||
|
|
||||||
@ -121,18 +121,19 @@ class Generic(object):
|
|||||||
'I', self.PF_CHANGE_ADD_TAIL), 4) # action = PF_CHANGE_ADD_TAIL
|
'I', self.PF_CHANGE_ADD_TAIL), 4) # action = PF_CHANGE_ADD_TAIL
|
||||||
ioctl(pf_get_dev(), pf.DIOCCHANGERULE, pr)
|
ioctl(pf_get_dev(), pf.DIOCCHANGERULE, pr)
|
||||||
|
|
||||||
|
def _inet_version(self, family):
|
||||||
|
return b'inet' if family == socket.AF_INET else b'inet6'
|
||||||
|
|
||||||
|
def _lo_addr(self, family):
|
||||||
|
return b'127.0.0.1' if family == socket.AF_INET else b'::1'
|
||||||
|
|
||||||
def add_rules(self, anchor, rules):
|
def add_rules(self, anchor, rules):
|
||||||
assert isinstance(rules, bytes)
|
assert isinstance(rules, bytes)
|
||||||
debug3("rules:\n" + rules.decode("ASCII"))
|
debug3("rules:\n" + rules.decode("ASCII"))
|
||||||
pfctl('-a %s -f /dev/stdin' % anchor, rules)
|
pfctl('-a %s -f /dev/stdin' % anchor, rules)
|
||||||
|
|
||||||
def has_running_instances(self):
|
def has_skip_loopback(self):
|
||||||
# This should cover most scenarios.
|
return b'skip' in pfctl('-s Interfaces -i lo -v')[0]
|
||||||
p = ssubprocess.Popen(['pgrep', '-f', 'python.*sshuttle'],
|
|
||||||
stdout=ssubprocess.PIPE,
|
|
||||||
stderr=ssubprocess.PIPE)
|
|
||||||
o, e = p.communicate()
|
|
||||||
return len(o.splitlines()) > 0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -178,17 +179,20 @@ class FreeBsd(Generic):
|
|||||||
memmove(addressof(pr) + self.POOL_TICKET_OFFSET, ppa[4:8], 4)
|
memmove(addressof(pr) + self.POOL_TICKET_OFFSET, ppa[4:8], 4)
|
||||||
super(FreeBsd, self)._add_anchor_rule(type, name, pr=pr)
|
super(FreeBsd, self)._add_anchor_rule(type, name, pr=pr)
|
||||||
|
|
||||||
def add_rules(self, anchor, includes, port, dnsport, nslist):
|
def add_rules(self, anchor, includes, port, dnsport, nslist, family):
|
||||||
|
inet_version = self._inet_version(family)
|
||||||
|
lo_addr = self._lo_addr(family)
|
||||||
|
|
||||||
tables = [
|
tables = [
|
||||||
b'table <forward_subnets> {%s}' % b','.join(includes)
|
b'table <forward_subnets> {%s}' % b','.join(includes)
|
||||||
]
|
]
|
||||||
translating_rules = [
|
translating_rules = [
|
||||||
b'rdr pass on lo0 proto tcp '
|
b'rdr pass on lo0 %s proto tcp to <forward_subnets> '
|
||||||
b'to <forward_subnets> -> 127.0.0.1 port %r' % port
|
b'-> %s port %r' % (inet_version, lo_addr, port)
|
||||||
]
|
]
|
||||||
filtering_rules = [
|
filtering_rules = [
|
||||||
b'pass out route-to lo0 inet proto tcp '
|
b'pass out route-to lo0 %s proto tcp '
|
||||||
b'to <forward_subnets> keep state'
|
b'to <forward_subnets> keep state' % inet_version
|
||||||
]
|
]
|
||||||
|
|
||||||
if len(nslist) > 0:
|
if len(nslist) > 0:
|
||||||
@ -196,11 +200,11 @@ class FreeBsd(Generic):
|
|||||||
b'table <dns_servers> {%s}' %
|
b'table <dns_servers> {%s}' %
|
||||||
b','.join([ns[1].encode("ASCII") for ns in nslist]))
|
b','.join([ns[1].encode("ASCII") for ns in nslist]))
|
||||||
translating_rules.append(
|
translating_rules.append(
|
||||||
b'rdr pass on lo0 proto udp to '
|
b'rdr pass on lo0 %s proto udp to <dns_servers> '
|
||||||
b'<dns_servers> port 53 -> 127.0.0.1 port %r' % dnsport)
|
b'port 53 -> %s port %r' % (inet_version, lo_addr, dnsport))
|
||||||
filtering_rules.append(
|
filtering_rules.append(
|
||||||
b'pass out route-to lo0 inet proto udp to '
|
b'pass out route-to lo0 %s proto udp to '
|
||||||
b'<dns_servers> port 53 keep state')
|
b'<dns_servers> port 53 keep state' % inet_version)
|
||||||
|
|
||||||
rules = b'\n'.join(tables + translating_rules + filtering_rules) \
|
rules = b'\n'.join(tables + translating_rules + filtering_rules) \
|
||||||
+ b'\n'
|
+ b'\n'
|
||||||
@ -239,21 +243,24 @@ class OpenBsd(Generic):
|
|||||||
# before adding anchors and rules we must override the skip lo
|
# before adding anchors and rules we must override the skip lo
|
||||||
# that comes by default in openbsd pf.conf so the rules we will add,
|
# that comes by default in openbsd pf.conf so the rules we will add,
|
||||||
# which rely on translating/filtering packets on lo, can work
|
# which rely on translating/filtering packets on lo, can work
|
||||||
if not self.has_running_instances():
|
if self.has_skip_loopback():
|
||||||
pfctl('-f /dev/stdin', b'match on lo\n')
|
pfctl('-f /dev/stdin', b'match on lo\n')
|
||||||
super(OpenBsd, self).add_anchors(anchor)
|
super(OpenBsd, self).add_anchors(anchor)
|
||||||
|
|
||||||
def add_rules(self, anchor, includes, port, dnsport, nslist):
|
def add_rules(self, anchor, includes, port, dnsport, nslist, family):
|
||||||
|
inet_version = self._inet_version(family)
|
||||||
|
lo_addr = self._lo_addr(family)
|
||||||
|
|
||||||
tables = [
|
tables = [
|
||||||
b'table <forward_subnets> {%s}' % b','.join(includes)
|
b'table <forward_subnets> {%s}' % b','.join(includes)
|
||||||
]
|
]
|
||||||
translating_rules = [
|
translating_rules = [
|
||||||
b'pass in on lo0 inet proto tcp '
|
b'pass in on lo0 %s proto tcp to <forward_subnets> '
|
||||||
b'to <forward_subnets> divert-to 127.0.0.1 port %r' % port
|
b'divert-to %s port %r' % (inet_version, lo_addr, port)
|
||||||
]
|
]
|
||||||
filtering_rules = [
|
filtering_rules = [
|
||||||
b'pass out inet proto tcp '
|
b'pass out %s proto tcp to <forward_subnets> '
|
||||||
b'to <forward_subnets> route-to lo0 keep state'
|
b'route-to lo0 keep state' % inet_version
|
||||||
]
|
]
|
||||||
|
|
||||||
if len(nslist) > 0:
|
if len(nslist) > 0:
|
||||||
@ -261,11 +268,11 @@ class OpenBsd(Generic):
|
|||||||
b'table <dns_servers> {%s}' %
|
b'table <dns_servers> {%s}' %
|
||||||
b','.join([ns[1].encode("ASCII") for ns in nslist]))
|
b','.join([ns[1].encode("ASCII") for ns in nslist]))
|
||||||
translating_rules.append(
|
translating_rules.append(
|
||||||
b'pass in on lo0 inet proto udp to <dns_servers>'
|
b'pass in on lo0 %s proto udp to <dns_servers> port 53 '
|
||||||
b'port 53 rdr-to 127.0.0.1 port %r' % dnsport)
|
b'rdr-to %s port %r' % (inet_version, lo_addr, dnsport))
|
||||||
filtering_rules.append(
|
filtering_rules.append(
|
||||||
b'pass out inet proto udp to '
|
b'pass out %s proto udp to <dns_servers> port 53 '
|
||||||
b'<dns_servers> port 53 route-to lo0 keep state')
|
b'route-to lo0 keep state' % inet_version)
|
||||||
|
|
||||||
rules = b'\n'.join(tables + translating_rules + filtering_rules) \
|
rules = b'\n'.join(tables + translating_rules + filtering_rules) \
|
||||||
+ b'\n'
|
+ b'\n'
|
||||||
@ -303,19 +310,18 @@ class Darwin(FreeBsd):
|
|||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
o = pfctl('-E')
|
o = pfctl('-E')
|
||||||
_pf_context['Xtoken'] = \
|
_pf_context['Xtoken'].append(re.search(b'Token : (.+)', o[1]).group(1))
|
||||||
re.search(b'Token : (.+)', o[1]).group(1)
|
|
||||||
|
|
||||||
def disable(self, anchor):
|
def disable(self, anchor):
|
||||||
pfctl('-a %s -F all' % anchor)
|
pfctl('-a %s -F all' % anchor)
|
||||||
if _pf_context['Xtoken'] is not None:
|
if _pf_context['Xtoken']:
|
||||||
pfctl('-X %s' % _pf_context['Xtoken'].decode("ASCII"))
|
pfctl('-X %s' % _pf_context['Xtoken'].pop().decode("ASCII"))
|
||||||
|
|
||||||
def add_anchors(self, anchor):
|
def add_anchors(self, anchor):
|
||||||
# before adding anchors and rules we must override the skip lo
|
# before adding anchors and rules we must override the skip lo
|
||||||
# that in some cases ends up in the chain so the rules we will add,
|
# that in some cases ends up in the chain so the rules we will add,
|
||||||
# which rely on translating/filtering packets on lo, can work
|
# which rely on translating/filtering packets on lo, can work
|
||||||
if not self.has_running_instances():
|
if self.has_skip_loopback():
|
||||||
pfctl('-f /dev/stdin', b'pass on lo\n')
|
pfctl('-f /dev/stdin', b'pass on lo\n')
|
||||||
super(Darwin, self).add_anchors(anchor)
|
super(Darwin, self).add_anchors(anchor)
|
||||||
|
|
||||||
@ -362,9 +368,17 @@ def pf_get_dev():
|
|||||||
return _pf_fd
|
return _pf_fd
|
||||||
|
|
||||||
|
|
||||||
|
def pf_get_anchor(family, port):
|
||||||
|
return 'sshuttle%s-%d' % ('' if family == socket.AF_INET else '6', port)
|
||||||
|
|
||||||
|
|
||||||
class Method(BaseMethod):
|
class Method(BaseMethod):
|
||||||
|
|
||||||
|
def get_supported_features(self):
|
||||||
|
result = super(Method, self).get_supported_features()
|
||||||
|
result.ipv6 = True
|
||||||
|
return result
|
||||||
|
|
||||||
def get_tcp_dstip(self, sock):
|
def get_tcp_dstip(self, sock):
|
||||||
pfile = self.firewall.pfile
|
pfile = self.firewall.pfile
|
||||||
|
|
||||||
@ -390,7 +404,7 @@ class Method(BaseMethod):
|
|||||||
translating_rules = []
|
translating_rules = []
|
||||||
filtering_rules = []
|
filtering_rules = []
|
||||||
|
|
||||||
if family != socket.AF_INET:
|
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'
|
||||||
% family_to_string(family))
|
% family_to_string(family))
|
||||||
@ -409,20 +423,20 @@ class Method(BaseMethod):
|
|||||||
snet.encode("ASCII"),
|
snet.encode("ASCII"),
|
||||||
swidth))
|
swidth))
|
||||||
|
|
||||||
anchor = 'sshuttle-%d' % port
|
anchor = pf_get_anchor(family, port)
|
||||||
pf.add_anchors(anchor)
|
pf.add_anchors(anchor)
|
||||||
pf.add_rules(anchor, includes, port, dnsport, nslist)
|
pf.add_rules(anchor, includes, port, dnsport, nslist, family)
|
||||||
pf.enable()
|
pf.enable()
|
||||||
|
|
||||||
def restore_firewall(self, port, family, udp):
|
def restore_firewall(self, port, family, udp):
|
||||||
if family != socket.AF_INET:
|
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'
|
||||||
% family_to_string(family))
|
% family_to_string(family))
|
||||||
if udp:
|
if udp:
|
||||||
raise Exception("UDP not supported by pf method_name")
|
raise Exception("UDP not supported by pf method_name")
|
||||||
|
|
||||||
pf.disable('sshuttle-%d' % port)
|
pf.disable(pf_get_anchor(family, port))
|
||||||
|
|
||||||
def firewall_command(self, line):
|
def firewall_command(self, line):
|
||||||
if line.startswith('QUERY_PF_NAT '):
|
if line.startswith('QUERY_PF_NAT '):
|
||||||
|
@ -187,7 +187,7 @@ parser.add_argument(
|
|||||||
"-x", "--exclude",
|
"-x", "--exclude",
|
||||||
metavar="IP/MASK",
|
metavar="IP/MASK",
|
||||||
action="append",
|
action="append",
|
||||||
default=[parse_subnet('127.0.0.1/8')],
|
default=[],
|
||||||
type=parse_subnet,
|
type=parse_subnet,
|
||||||
help="""
|
help="""
|
||||||
exclude this subnet (can be used more than once)
|
exclude this subnet (can be used more than once)
|
||||||
|
@ -286,6 +286,12 @@ def main(latency_control, auto_hosts):
|
|||||||
def new_channel(channel, data):
|
def new_channel(channel, data):
|
||||||
(family, dstip, dstport) = data.decode("ASCII").split(',', 2)
|
(family, dstip, dstport) = data.decode("ASCII").split(',', 2)
|
||||||
family = int(family)
|
family = int(family)
|
||||||
|
# AF_INET is the same constant on Linux and BSD but AF_INET6
|
||||||
|
# is different. As the client and server can be running on
|
||||||
|
# different platforms we can not just set the socket family
|
||||||
|
# to what comes in the wire.
|
||||||
|
if family != socket.AF_INET:
|
||||||
|
family = socket.AF_INET6
|
||||||
dstport = int(dstport)
|
dstport = int(dstport)
|
||||||
outwrap = ssnet.connect_dst(family, dstip, dstport)
|
outwrap = ssnet.connect_dst(family, dstip, dstport)
|
||||||
handlers.append(Proxy(MuxWrapper(mux, channel), outwrap))
|
handlers.append(Proxy(MuxWrapper(mux, channel), outwrap))
|
||||||
|
@ -10,7 +10,7 @@ from sshuttle.methods.pf import FreeBsd, Darwin, OpenBsd
|
|||||||
def test_get_supported_features():
|
def test_get_supported_features():
|
||||||
method = get_method('pf')
|
method = get_method('pf')
|
||||||
features = method.get_supported_features()
|
features = method.get_supported_features()
|
||||||
assert not features.ipv6
|
assert features.ipv6
|
||||||
assert not features.udp
|
assert not features.udp
|
||||||
assert features.dns
|
assert features.dns
|
||||||
|
|
||||||
@ -155,6 +155,8 @@ def test_firewall_command_openbsd(mock_pf_get_dev, mock_ioctl, mock_stdout):
|
|||||||
|
|
||||||
|
|
||||||
def pfctl(args, stdin=None):
|
def pfctl(args, stdin=None):
|
||||||
|
if args == '-s Interfaces -i lo -v':
|
||||||
|
return (b'lo0 (skip)',)
|
||||||
if args == '-s all':
|
if args == '-s all':
|
||||||
return (b'INFO:\nStatus: Disabled\nanother mary had a little lamb\n',
|
return (b'INFO:\nStatus: Disabled\nanother mary had a little lamb\n',
|
||||||
b'little lamb\n')
|
b'little lamb\n')
|
||||||
@ -174,19 +176,45 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
method = get_method('pf')
|
method = get_method('pf')
|
||||||
assert method.name == 'pf'
|
assert method.name == 'pf'
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
# IPV6
|
||||||
method.setup_firewall(
|
|
||||||
1024, 1026,
|
method.setup_firewall(
|
||||||
[(10, u'2404:6800:4004:80c::33')],
|
1024, 1026,
|
||||||
10,
|
[(10, u'2404:6800:4004:80c::33')],
|
||||||
[(10, 64, False, u'2404:6800:4004:80c::'),
|
10,
|
||||||
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
[(10, 64, False, u'2404:6800:4004:80c::'),
|
||||||
True)
|
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
||||||
assert str(excinfo.value) \
|
False)
|
||||||
== 'Address family "AF_INET6" unsupported by pf method_name'
|
assert mock_ioctl.mock_calls == [
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
||||||
assert mock_ioctl.mock_calls == []
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
assert mock_pfctl.mock_calls == []
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
|
call(mock_pf_get_dev(), 0xC4704433, ANY),
|
||||||
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
|
]
|
||||||
|
assert mock_pfctl.mock_calls == [
|
||||||
|
call('-s Interfaces -i lo -v'),
|
||||||
|
call('-f /dev/stdin', b'pass on lo\n'),
|
||||||
|
call('-s all'),
|
||||||
|
call('-a sshuttle6-1024 -f /dev/stdin',
|
||||||
|
b'table <forward_subnets> {'
|
||||||
|
b'!2404:6800:4004:80c::101f/128,2404:6800:4004:80c::/64'
|
||||||
|
b'}\n'
|
||||||
|
b'table <dns_servers> {2404:6800:4004:80c::33}\n'
|
||||||
|
b'rdr pass on lo0 inet6 proto tcp '
|
||||||
|
b'to <forward_subnets> -> ::1 port 1024\n'
|
||||||
|
b'rdr pass on lo0 inet6 proto udp '
|
||||||
|
b'to <dns_servers> port 53 -> ::1 port 1026\n'
|
||||||
|
b'pass out route-to lo0 inet6 proto tcp '
|
||||||
|
b'to <forward_subnets> keep state\n'
|
||||||
|
b'pass out route-to lo0 inet6 proto udp '
|
||||||
|
b'to <dns_servers> port 53 keep state\n'),
|
||||||
|
call('-E'),
|
||||||
|
]
|
||||||
|
mock_pf_get_dev.reset_mock()
|
||||||
|
mock_ioctl.reset_mock()
|
||||||
|
mock_pfctl.reset_mock()
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
with pytest.raises(Exception) as excinfo:
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
@ -215,14 +243,15 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
call(mock_pf_get_dev(), 0xCC20441A, ANY),
|
||||||
]
|
]
|
||||||
assert mock_pfctl.mock_calls == [
|
assert mock_pfctl.mock_calls == [
|
||||||
|
call('-s Interfaces -i lo -v'),
|
||||||
call('-f /dev/stdin', b'pass on lo\n'),
|
call('-f /dev/stdin', b'pass on lo\n'),
|
||||||
call('-s all'),
|
call('-s all'),
|
||||||
call('-a sshuttle-1025 -f /dev/stdin',
|
call('-a sshuttle-1025 -f /dev/stdin',
|
||||||
b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
|
b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
|
||||||
b'table <dns_servers> {1.2.3.33}\n'
|
b'table <dns_servers> {1.2.3.33}\n'
|
||||||
b'rdr pass on lo0 proto tcp '
|
b'rdr pass on lo0 inet proto tcp '
|
||||||
b'to <forward_subnets> -> 127.0.0.1 port 1025\n'
|
b'to <forward_subnets> -> 127.0.0.1 port 1025\n'
|
||||||
b'rdr pass on lo0 proto udp '
|
b'rdr pass on lo0 inet proto udp '
|
||||||
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
|
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
|
||||||
b'pass out route-to lo0 inet proto tcp '
|
b'pass out route-to lo0 inet proto tcp '
|
||||||
b'to <forward_subnets> keep state\n'
|
b'to <forward_subnets> keep state\n'
|
||||||
@ -256,19 +285,34 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
method = get_method('pf')
|
method = get_method('pf')
|
||||||
assert method.name == 'pf'
|
assert method.name == 'pf'
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
method.setup_firewall(
|
||||||
method.setup_firewall(
|
1024, 1026,
|
||||||
1024, 1026,
|
[(10, u'2404:6800:4004:80c::33')],
|
||||||
[(10, u'2404:6800:4004:80c::33')],
|
10,
|
||||||
10,
|
[(10, 64, False, u'2404:6800:4004:80c::'),
|
||||||
[(10, 64, False, u'2404:6800:4004:80c::'),
|
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
||||||
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
False)
|
||||||
True)
|
|
||||||
assert str(excinfo.value) \
|
assert mock_pfctl.mock_calls == [
|
||||||
== 'Address family "AF_INET6" unsupported by pf method_name'
|
call('-s all'),
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
call('-a sshuttle6-1024 -f /dev/stdin',
|
||||||
assert mock_ioctl.mock_calls == []
|
b'table <forward_subnets> {'
|
||||||
assert mock_pfctl.mock_calls == []
|
b'!2404:6800:4004:80c::101f/128,2404:6800:4004:80c::/64'
|
||||||
|
b'}\n'
|
||||||
|
b'table <dns_servers> {2404:6800:4004:80c::33}\n'
|
||||||
|
b'rdr pass on lo0 inet6 proto tcp '
|
||||||
|
b'to <forward_subnets> -> ::1 port 1024\n'
|
||||||
|
b'rdr pass on lo0 inet6 proto udp '
|
||||||
|
b'to <dns_servers> port 53 -> ::1 port 1026\n'
|
||||||
|
b'pass out route-to lo0 inet6 proto tcp '
|
||||||
|
b'to <forward_subnets> keep state\n'
|
||||||
|
b'pass out route-to lo0 inet6 proto udp '
|
||||||
|
b'to <dns_servers> port 53 keep state\n'),
|
||||||
|
call('-e'),
|
||||||
|
]
|
||||||
|
mock_pf_get_dev.reset_mock()
|
||||||
|
mock_ioctl.reset_mock()
|
||||||
|
mock_pfctl.reset_mock()
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
with pytest.raises(Exception) as excinfo:
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
@ -301,9 +345,9 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
call('-a sshuttle-1025 -f /dev/stdin',
|
call('-a sshuttle-1025 -f /dev/stdin',
|
||||||
b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
|
b'table <forward_subnets> {!1.2.3.66/32,1.2.3.0/24}\n'
|
||||||
b'table <dns_servers> {1.2.3.33}\n'
|
b'table <dns_servers> {1.2.3.33}\n'
|
||||||
b'rdr pass on lo0 proto tcp '
|
b'rdr pass on lo0 inet proto tcp '
|
||||||
b'to <forward_subnets> -> 127.0.0.1 port 1025\n'
|
b'to <forward_subnets> -> 127.0.0.1 port 1025\n'
|
||||||
b'rdr pass on lo0 proto udp '
|
b'rdr pass on lo0 inet proto udp '
|
||||||
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
|
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
|
||||||
b'pass out route-to lo0 inet proto tcp '
|
b'pass out route-to lo0 inet proto tcp '
|
||||||
b'to <forward_subnets> keep state\n'
|
b'to <forward_subnets> keep state\n'
|
||||||
@ -337,19 +381,40 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
method = get_method('pf')
|
method = get_method('pf')
|
||||||
assert method.name == 'pf'
|
assert method.name == 'pf'
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
method.setup_firewall(
|
||||||
method.setup_firewall(
|
1024, 1026,
|
||||||
1024, 1026,
|
[(10, u'2404:6800:4004:80c::33')],
|
||||||
[(10, u'2404:6800:4004:80c::33')],
|
10,
|
||||||
10,
|
[(10, 64, False, u'2404:6800:4004:80c::'),
|
||||||
[(10, 64, False, u'2404:6800:4004:80c::'),
|
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
||||||
(10, 128, True, u'2404:6800:4004:80c::101f')],
|
False)
|
||||||
True)
|
|
||||||
assert str(excinfo.value) \
|
assert mock_ioctl.mock_calls == [
|
||||||
== 'Address family "AF_INET6" unsupported by pf method_name'
|
call(mock_pf_get_dev(), 0xcd48441a, ANY),
|
||||||
assert mock_pf_get_dev.mock_calls == []
|
call(mock_pf_get_dev(), 0xcd48441a, ANY),
|
||||||
assert mock_ioctl.mock_calls == []
|
]
|
||||||
assert mock_pfctl.mock_calls == []
|
assert mock_pfctl.mock_calls == [
|
||||||
|
call('-s Interfaces -i lo -v'),
|
||||||
|
call('-f /dev/stdin', b'match on lo\n'),
|
||||||
|
call('-s all'),
|
||||||
|
call('-a sshuttle6-1024 -f /dev/stdin',
|
||||||
|
b'table <forward_subnets> {'
|
||||||
|
b'!2404:6800:4004:80c::101f/128,2404:6800:4004:80c::/64'
|
||||||
|
b'}\n'
|
||||||
|
b'table <dns_servers> {2404:6800:4004:80c::33}\n'
|
||||||
|
b'pass in on lo0 inet6 proto tcp to '
|
||||||
|
b'<forward_subnets> divert-to ::1 port 1024\n'
|
||||||
|
b'pass in on lo0 inet6 proto udp '
|
||||||
|
b'to <dns_servers> port 53 rdr-to ::1 port 1026\n'
|
||||||
|
b'pass out inet6 proto tcp to '
|
||||||
|
b'<forward_subnets> route-to lo0 keep state\n'
|
||||||
|
b'pass out inet6 proto udp to '
|
||||||
|
b'<dns_servers> port 53 route-to lo0 keep state\n'),
|
||||||
|
call('-e'),
|
||||||
|
]
|
||||||
|
mock_pf_get_dev.reset_mock()
|
||||||
|
mock_ioctl.reset_mock()
|
||||||
|
mock_pfctl.reset_mock()
|
||||||
|
|
||||||
with pytest.raises(Exception) as excinfo:
|
with pytest.raises(Exception) as excinfo:
|
||||||
method.setup_firewall(
|
method.setup_firewall(
|
||||||
@ -374,6 +439,7 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
call(mock_pf_get_dev(), 0xcd48441a, ANY),
|
call(mock_pf_get_dev(), 0xcd48441a, ANY),
|
||||||
]
|
]
|
||||||
assert mock_pfctl.mock_calls == [
|
assert mock_pfctl.mock_calls == [
|
||||||
|
call('-s Interfaces -i lo -v'),
|
||||||
call('-f /dev/stdin', b'match on lo\n'),
|
call('-f /dev/stdin', b'match on lo\n'),
|
||||||
call('-s all'),
|
call('-s all'),
|
||||||
call('-a sshuttle-1025 -f /dev/stdin',
|
call('-a sshuttle-1025 -f /dev/stdin',
|
||||||
@ -381,7 +447,7 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
|
|||||||
b'table <dns_servers> {1.2.3.33}\n'
|
b'table <dns_servers> {1.2.3.33}\n'
|
||||||
b'pass in on lo0 inet proto tcp to <forward_subnets> divert-to 127.0.0.1 port 1025\n'
|
b'pass in on lo0 inet proto tcp to <forward_subnets> divert-to 127.0.0.1 port 1025\n'
|
||||||
b'pass in on lo0 inet proto udp to '
|
b'pass in on lo0 inet proto udp to '
|
||||||
b'<dns_servers>port 53 rdr-to 127.0.0.1 port 1027\n'
|
b'<dns_servers> port 53 rdr-to 127.0.0.1 port 1027\n'
|
||||||
b'pass out inet proto tcp to '
|
b'pass out inet proto tcp to '
|
||||||
b'<forward_subnets> route-to lo0 keep state\n'
|
b'<forward_subnets> route-to lo0 keep state\n'
|
||||||
b'pass out inet proto udp to '
|
b'pass out inet proto udp to '
|
||||||
|
Loading…
Reference in New Issue
Block a user