Compare commits

...

30 Commits

Author SHA1 Message Date
752a953101 Release 0.78.5 2019-01-28 16:28:57 +13:00
61f4cd9de5 Update CHANGES.rst for new release 2019-01-28 11:36:14 +13:00
8e35f049e2 auto-nets: retrieve routes only if using auto-nets
There's a known issue that makes sshuttle crash if there are too
many routes on the remote host (that don't fit in 64KB). This patch
requests the routes only if auto-nets is specified on the command
line.
2019-01-28 08:53:51 +13:00
0e99adc5d1 Fix potential deadlock condition in nft_get_handle
This was susceptible to the same deadlock issue that ipt_chain_exists
had and was fixed in d43db80 where if the command returned a significant
amount of output, it wouldn't all be read in, resulting in the
subprocess hanging waiting for the output to be read.
2019-01-23 18:53:45 +13:00
04849df7e3 Use subprocess.check_output instead of run
subprocess.run only exists for python3, and this needs to also support
python 2.7
2019-01-23 18:53:45 +13:00
531a17c151 docs: document --ns-hosts --to-ns and update --dns
--ns-hosts is available since commit d2ee34d71c
("dns: Added --ns-hosts to tunnel only some requests")
(released as v0.72), but was never documented.

--to-ns is available since commit be559fc78b
("Fix case where there is no --dns.") after several
bugfixes, released as v0.78.4, but was never
documented.
2018-12-29 15:02:18 +11:00
d43db80dec Fix deadlock with iptables with large ruleset
When running sshuttle with a large list of routes it's failing to clean
them up at exit. It returns the following:

$ sshuttle -r user@host.example.com -s /tmp/aws-cidrs.txt
user@host.example.com's password:
client: Connected.
^CAnother app is currently holding the xtables lock; still -9s 0us time ahead to have a chance to grab the lock...
Another app is currently holding the xtables lock; still -19s 0us time ahead to have a chance to grab the lock...
Another app is currently holding the xtables lock; still -29s 0us time ahead to have a chance to grab the lock...

This continues indefinitely. Looking in ps reveals that there are 2
iptables processes running. Killing -9 the first one, allows sshuttle to
continue and clean up successfully.

The problem lies with the use of Popen here. The function currently
returns as soon as it finds a match without consuming everything from
stdout. This means that if there's more output from iptables than will
fit in the buffer it doesn't exit, and therefore doesn't release the
kernel xtables lock.
2018-12-09 18:03:54 +11:00
0b1a260436 Fix typo in docs 2018-12-03 14:34:42 +11:00
efc854c33e Document --version option 2018-11-29 08:02:58 +11:00
ca41026c89 Changes pf exclusion rules precedence
Before this change, in pf, exclusions used a pass out quick which gave
them higher precedence than any other rule independent of subnet width.
As reported in #265 this causes exclusion from one instance of sshuttle
to also take effect on other instances because quick aborts the
evaluation of rules across all anchors.

This commit changes the precedence of rules so quick can now be
dropped. The new order is defined by the following rule, from
subnet_weight:

"We need to go from smaller, more specific, port ranges, to larger,
less-specific, port ranges. At each level, we order by subnet
width, from most-specific subnets (largest swidth) to
least-specific. On ties, excludes come first."
2018-11-03 12:24:32 +11:00
b473b91633 Close stdin, stdout, and stderr when using syslog or forking to daemon (#283)
* Close stdin, stdout, and stderr when using syslog or forking to daemon

Fixes #139

* Ensure we close devnull after use
2018-11-01 09:27:50 +11:00
7a54d12f80 Fixes support for OpenBSD (6.1+) (#282)
* Fixes support for OpenBSD (6.1+)

As reported in #219, new versions of OpenBSD ship with a different
pfioc_rule struct. This commit adjusts the offset to match the new struct.

* Fixes tests for OpenBSD 6.1+
2018-10-23 07:31:29 +11:00
d4bbf3b68d Added coverage report to tests 2018-10-17 20:54:28 +11:00
41f5b3e9c1 replace path /dev/null by os.devnull 2018-10-17 20:53:06 +11:00
c780597de3 updated bandit config 2018-10-17 20:52:04 +11:00
d085a419b2 updated path 2018-10-17 20:52:04 +11:00
842768f9cf Moved sshuttle/tests into tests to.
Having the tests in a `tests` directory in root is the most common
approach. Also moved pytest's conftest.py into `tests` making the
fixture available for client and server tests.
2018-10-17 20:52:04 +11:00
97ed2030f3 Fix missing string formatting argument 2018-10-07 11:30:41 +11:00
6dc368bde8 Merge pull request #271 from usabilla/no-sudo-pythonpath
Add --no-sudo-pythonpath option
2018-09-22 17:57:33 +10:00
f528bb9846 Add --no-sudo-pythonpath option
This provides a way to avoid setting PYTHONPATH when invoking the
privileged part of sshuttle with sudo. This is useful if running
sshuttle as a PEX archive, as Telepresence does, as it enables
sshuttle's sudo access to be securely locked down.

PEX archives will extract themselves into the invoking user's home
directory, which means that the invoking user has full control over
the code in them. This makes restricting sudo access with
PYTHONPATH set completely pointless in this scenario -- an attacker
could put any code into ~/.pex and gain full root access anyway.

On the other hand, if sshuttle is a PEX archive, the privileged
invocation will simply extract itself into /root/.pex anyway, so
there is no need to set PYTHONPATH in this case.
2018-09-21 18:48:31 +02:00
561b648e4b works on ChromeOS with Crostini VM (#262)
* works on ChromeOS with Crostini VM

tested on ASUS C101PA on Dev channel, should also work on Intel machines and Beta channel

* crostini doc, and a note about xterms and VNC

tested on ASUS C101PA on Dev channel, should also work on Intel machines and Beta channel
2018-08-25 10:30:45 +10:00
0dba8a8beb Don't crash if we can't look up peername
Peername is only used for information display messages.

Fixes #259
2018-08-21 08:36:51 +10:00
7b6f082454 Doc Update
Remove reference to autossh per
https://github.com/sshuttle/sshuttle/issues/143
2018-06-29 07:38:55 +10:00
1ec17e1b1b Update README.rst 2018-06-22 16:02:11 +10:00
cecccc2efd Doc: Fix typo 2018-06-07 07:00:17 +10:00
db69ba6d8d Doc: Improve Systemd service recommendation (fixes #238) 2018-06-03 07:38:21 +10:00
2bb92cd6d4 Fix sudo/doas
Fixes #227
2018-05-13 20:35:18 +10:00
ae5bd28dcf Add doas support for client 2018-05-09 17:46:33 +10:00
55bd78fd43 Fix line length for CI. 2018-04-30 07:40:58 +10:00
1f5ed9c66e Fix concatening string to tuple. Allow for forwarding a single port. 2018-04-30 07:40:58 +10:00
32 changed files with 196 additions and 73 deletions

View File

@ -9,6 +9,35 @@ adheres to `Semantic Versioning`_.
.. _`Semantic Versioning`: http://semver.org/
0.78.5 - 2019-01-28
-------------------
Added
-----
* doas support as replacmeent for sudo on OpenBSD.
* Added ChromeOS section to documentation (#262)
* Add --no-sudo-pythonpath option
Fixed
~~~~~
* Fix forwarding to a single port.
* Various updates to documentation.
* Don't crash if we can't look up peername
* Fix missing string formatting argument
* Moved sshuttle/tests into tests.
* Updated bandit config.
* Replace path /dev/null by os.devnull.
* Added coverage report to tests.
* Fixes support for OpenBSD (6.1+) (#282).
* Close stdin, stdout, and stderr when using syslog or forking to daemon (#283).
* Changes pf exclusion rules precedence.
* Fix deadlock with iptables with large ruleset.
* docs: document --ns-hosts --to-ns and update --dns.
* Use subprocess.check_output instead of run.
* Fix potential deadlock condition in nft_get_handle.
* auto-nets: retrieve routes only if using auto-nets.
0.78.4 - 2018-04-02
-------------------

View File

@ -67,7 +67,7 @@ It is also possible to install into a virtualenv as a non-root user.
Documentation
-------------
The documentation for the stable version is available at:
http://sshuttle.readthedocs.org/
https://sshuttle.readthedocs.org/
The documentation for the latest development version is available at:
http://sshuttle.readthedocs.org/en/latest/
https://sshuttle.readthedocs.org/en/latest/

View File

@ -1,5 +1,5 @@
exclude_dirs:
- sshuttle/tests
- tests
skips:
- B101
- B104

12
docs/chromeos.rst Normal file
View File

@ -0,0 +1,12 @@
Google ChromeOS
===============
Currently there is no built in support for running sshuttle directly on
Google ChromeOS/Chromebooks.
What we can really do is to create a Linux VM with Crostini. In the default
stretch/Debian 9 VM, you can then install sshuttle as on any Linux box and
it just works, as do xterms and ssvncviewer etc.
https://www.reddit.com/r/Crostini/wiki/getstarted/crostini-setup-guide

View File

@ -94,7 +94,30 @@ Options
.. option:: --dns
Capture local DNS requests and forward to the remote DNS
server.
server. All queries to any of the local system's DNS
servers (/etc/resolv.conf) will be intercepted and
resolved on the remote side of the tunnel instead, there
using the DNS specified via the :option:`--to-ns=` option,
if specified.
.. option:: --ns-hosts=server1[,server2[,server3[...]]]
Capture local DNS requests to the specified server(s)
and forward to the remote DNS server. Contrary to the
:option:`--dns` option, this flag allows to specify the
DNS server(s) the queries to which to intercept,
instead of intercepting all DNS traffic on the local
machine. This can be useful when only certain DNS
requests should be resolved on the remote side of the
tunnel, e.g. in combination with dnsmasq.
.. option:: --to-ns=server
The DNS to forward requests to when remote DNS
resolution is enabled. If not given, sshuttle will
simply resolve using the system configured resolver on
the remote side (via /etc/resolv.conf on the remote
side).
.. option:: --python
@ -204,17 +227,21 @@ Options
makes it a lot easier to debug and test the :option:`--auto-hosts`
feature.
.. option:: --version
Print program version.
Configuration File
------------------
All the options described above can optionally be specified in a configuration
file.
To run :program:`sshuttle` with options defined in, e.g., `/etc/ssshuttle.conf`
To run :program:`sshuttle` with options defined in, e.g., `/etc/sshuttle.conf`
just pass the path to the file preceded by the `@` character, e.g.
:option:`@/etc/ssshuttle.conf`.
:option:`@/etc/sshuttle.conf`.
When running :program:`sshuttle` with options defined in a configuratio file,
When running :program:`sshuttle` with options defined in a configuration file,
options can still be passed via the command line in addition to what is
defined in the file. If a given option is defined both in the file and in
the command line, the value in the command line will take precedence.

View File

@ -6,5 +6,6 @@ Contents:
.. toctree::
:maxdepth: 2
chromeos
tproxy
windows

View File

@ -73,8 +73,6 @@ possible as support for older versions might be dropped in the future.
Additional Suggested Software
-----------------------------
- You may want to use autossh, available in various package management
systems.
- If you are using systemd, sshuttle can notify it when the connection to
the remote end is established and the firewall rules are installed. For
this feature to work you must configure the process start-up type for the
@ -89,6 +87,7 @@ Additional Suggested Software
[Service]
Type=notify
NotifyAccess=all
ExecStart=/usr/bin/sshuttle --dns --remote <user>@<server> <subnets...>
[Install]

View File

@ -1,4 +1,5 @@
-r requirements.txt
pytest==3.4.2
pytest-cov==2.6.0
mock==2.0.0
flake8==3.5.0

View File

@ -7,3 +7,6 @@ universal = 1
[upload]
sign=true
identity=0x1784577F811F6EAC
[tool:pytest]
addopts = --cov=sshuttle --cov-branch --cov-report=term-missing

View File

@ -57,6 +57,12 @@ setup(
'sshuttle = sshuttle.cmdline:main',
],
},
tests_require=['pytest', 'pytest-runner', 'mock'],
tests_require=[
'pytest',
'pytest-cov',
'pytest-runner',
'mock',
'flake8',
],
keywords="ssh vpn",
)

View File

@ -35,4 +35,5 @@ sshuttle.helpers.verbose = verbosity
import sshuttle.cmdline_options as options
from sshuttle.server import main
main(options.latency_control, options.auto_hosts, options.to_nameserver)
main(options.latency_control, options.auto_hosts, options.to_nameserver,
options.auto_nets)

View File

@ -33,7 +33,7 @@ except AttributeError:
except ImportError:
import socket
_extra_fd = os.open('/dev/null', os.O_RDONLY)
_extra_fd = os.open(os.devnull, os.O_RDONLY)
def got_signal(signum, frame):
@ -93,7 +93,7 @@ def daemonize():
# be deleted.
signal.signal(signal.SIGTERM, got_signal)
si = open('/dev/null', 'r+')
si = open(os.devnull, 'r+')
os.dup2(si.fileno(), 0)
os.dup2(si.fileno(), 1)
si.close()
@ -183,7 +183,13 @@ class MultiListener:
class FirewallClient:
def __init__(self, method_name):
def __init__(self, method_name, sudo_pythonpath):
# Default to sudo unless on OpenBSD in which case use built in `doas`
elevbin = 'sudo'
if platform.platform().startswith('OpenBSD'):
elevbin = 'doas'
self.auto_nets = []
python_path = os.path.dirname(os.path.dirname(__file__))
argvbase = ([sys.executable, sys.argv[0]] +
@ -192,11 +198,13 @@ class FirewallClient:
['--firewall'])
if ssyslog._p:
argvbase += ['--syslog']
argv_tries = [
['sudo', '-p', '[local sudo] Password: ', '/usr/bin/env',
('PYTHONPATH=%s' % python_path)] + argvbase,
argvbase
]
elev_prefix = [part % {'eb': elevbin}
for part in ['%(eb)s', '-p',
'[local %(eb)s] Password: ']]
if sudo_pythonpath:
elev_prefix += ['/usr/bin/env',
'PYTHONPATH=%s' % python_path]
argv_tries = [elev_prefix + argvbase, argvbase]
# we can't use stdin/stdout=subprocess.PIPE here, as we normally would,
# because stupid Linux 'su' requires that stdin be attached to a tty.
@ -347,7 +355,7 @@ def onaccept_tcp(listener, method, mux, handlers):
sock, srcip = listener.accept()
sock.close()
finally:
_extra_fd = os.open('/dev/null', os.O_RDONLY)
_extra_fd = os.open(os.devnull, os.O_RDONLY)
return
else:
raise
@ -445,7 +453,8 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
stderr=ssyslog._p and ssyslog._p.stdin,
options=dict(latency_control=latency_control,
auto_hosts=auto_hosts,
to_nameserver=to_nameserver))
to_nameserver=to_nameserver,
auto_nets=auto_nets))
except socket.error as e:
if e.args[0] == errno.EPIPE:
raise Fatal("failed to establish ssh session (1)")
@ -544,7 +553,7 @@ 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, to_nameserver, pidfile,
user):
user, sudo_pythonpath):
if daemon:
try:
@ -554,7 +563,7 @@ def main(listenip_v6, listenip_v4,
return 5
debug1('Starting sshuttle proxy.\n')
fw = FirewallClient(method_name)
fw = FirewallClient(method_name, sudo_pythonpath)
# Get family specific subnet lists
if dns:

View File

@ -59,6 +59,8 @@ def main():
ipport_v6 = "auto" if not opt.disable_ipv6 else None
if opt.syslog:
ssyslog.start_syslog()
ssyslog.close_stdin()
ssyslog.stdout_to_syslog()
ssyslog.stderr_to_syslog()
return_code = client.main(ipport_v6, ipport_v4,
opt.ssh_cmd,
@ -76,12 +78,13 @@ def main():
opt.daemon,
opt.to_ns,
opt.pidfile,
opt.user)
opt.user,
opt.sudo_pythonpath)
if return_code == 0:
log('Normal exit code, exiting...')
else:
log('Abnormal exit code detected, failing...' % return_code)
log('Abnormal exit code %d detected, failing...' % return_code)
return return_code
except Fatal as e:

View File

@ -21,7 +21,7 @@ _smb_ok = True
hostnames = {}
queue = {}
try:
null = open('/dev/null', 'wb')
null = open(os.devnull, 'wb')
except IOError:
_, e = sys.exc_info()[:2]
log('warning: %s\n' % e)

View File

@ -24,13 +24,13 @@ def ipt_chain_exists(family, table, name):
'PATH': os.environ['PATH'],
'LC_ALL': "C",
}
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, env=env)
for line in p.stdout:
if line.startswith(b'Chain %s ' % name.encode("ASCII")):
return True
rv = p.wait()
if rv:
raise Fatal('%r returned %d' % (argv, rv))
try:
output = ssubprocess.check_output(argv, env=env)
for line in output.decode('ASCII').split('\n'):
if line.startswith('Chain %s ' % name):
return True
except ssubprocess.CalledProcessError as e:
raise Fatal('%r returned %d' % (argv, e.returncode))
def ipt(family, table, *args):
@ -74,13 +74,13 @@ def nft_get_handle(expression, chain):
'PATH': os.environ['PATH'],
'LC_ALL': "C",
}
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, env=env)
for line in p.stdout:
if (b'jump %s' % chain.encode('utf-8')) in line:
return re.sub('.*# ', '', line.decode('utf-8'))
rv = p.wait()
if rv:
raise Fatal('%r returned %d' % (argv, rv))
try:
output = ssubprocess.check_output(argv, env=env)
for line in output.decode('utf-8').split('\n'):
if ('jump %s' % chain) in line:
return re.sub('.*# ', '', line)
except ssubprocess.CalledProcessError as e:
raise Fatal('%r returned %d' % (argv, e.returncode))
_no_ttl_module = False

View File

@ -105,7 +105,7 @@ def _fill_oldctls(prefix):
def _sysctl_set(name, val):
argv = ['sysctl', '-w', '%s=%s' % (name, val)]
debug1('>> %s\n' % ' '.join(argv))
return ssubprocess.call(argv, stdout=open('/dev/null', 'w'))
return ssubprocess.call(argv, stdout=open(os.devnull, 'w'))
_changedctls = []

View File

@ -40,8 +40,12 @@ class Method(BaseMethod):
for _, swidth, sexclude, snet, fport, lport \
in sorted(subnets, key=subnet_weight, reverse=True):
tcp_ports = ('ip', 'protocol', 'tcp')
if fport:
tcp_ports = tcp_ports + ('dport { %d-%d }' % (fport, lport))
if fport and fport != lport:
tcp_ports = \
tcp_ports + \
('tcp', 'dport', '{ %d-%d }' % (fport, lport))
elif fport and fport == lport:
tcp_ports = tcp_ports + ('tcp', 'dport', '%d' % (fport))
if sexclude:
_nft('add rule', chain, *(tcp_ports + (

View File

@ -217,7 +217,7 @@ class FreeBsd(Generic):
b'pass out route-to lo0 %s proto tcp '
b'to %s keep state' % (inet_version, subnet)
if not exclude else
b'pass out quick %s proto tcp to %s' % (inet_version, subnet)
b'pass out %s proto tcp to %s' % (inet_version, subnet)
for exclude, subnet in includes
]
@ -261,7 +261,7 @@ class OpenBsd(Generic):
("proto_variant", c_uint8),
("direction", c_uint8)]
self.pfioc_rule = c_char * 3400
self.pfioc_rule = c_char * 3416
self.pfioc_natlook = pfioc_natlook
super(OpenBsd, self).__init__()
@ -287,7 +287,7 @@ class OpenBsd(Generic):
b'pass out %s proto tcp to %s '
b'route-to lo0 keep state' % (inet_version, subnet)
if not exclude else
b'pass out quick %s proto tcp to %s' % (inet_version, subnet)
b'pass out %s proto tcp to %s' % (inet_version, subnet)
for exclude, subnet in includes
]
@ -452,7 +452,7 @@ class Method(BaseMethod):
# exclusion first; the table will ignore the second, opposite
# definition
for _, swidth, sexclude, snet, fport, lport \
in sorted(subnets, key=subnet_weight, reverse=True):
in sorted(subnets, key=subnet_weight):
includes.append((sexclude, b"%s/%d%s" % (
snet.encode("ASCII"),
swidth,

View File

@ -310,3 +310,11 @@ parser.add_argument(
(internal use only)
"""
)
parser.add_argument(
"--no-sudo-pythonpath",
action="store_false",
dest="sudo_pythonpath",
help="""
do not set PYTHONPATH when invoking sudo
"""
)

View File

@ -279,7 +279,7 @@ class UdpProxy(Handler):
self.mux.send(self.chan, ssnet.CMD_UDP_DATA, hdr + data)
def main(latency_control, auto_hosts, to_nameserver):
def main(latency_control, auto_hosts, to_nameserver, auto_nets):
debug1('Starting server with Python version %s\n'
% platform.python_version())
@ -289,10 +289,6 @@ def main(latency_control, auto_hosts, to_nameserver):
helpers.logprefix = 'server: '
debug1('latency control setting = %r\n' % latency_control)
routes = list(list_routes())
debug1('available routes:\n')
for r in routes:
debug1(' %d/%s/%d\n' % r)
# synchronization header
sys.stdout.write('\0\0SSHUTTLE0001')
@ -304,6 +300,16 @@ def main(latency_control, auto_hosts, to_nameserver):
socket.fromfd(sys.stdout.fileno(),
socket.AF_INET, socket.SOCK_STREAM))
handlers.append(mux)
debug1('auto-nets:' + str(auto_nets) + '\n')
if auto_nets:
routes = list(list_routes())
debug1('available routes:\n')
for r in routes:
debug1(' %d/%s/%d\n' % r)
else:
routes = []
routepkt = ''
for r in routes:
routepkt += '%d,%s,%d\n' % r

View File

@ -116,8 +116,8 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
if python:
pycmd = "'%s' -c '%s'" % (python, pyscript)
else:
pycmd = ("P=python3; $P -V 2>/dev/null || P=python; "
"exec \"$P\" -c %s") % quote(pyscript)
pycmd = ("P=python3; $P -V 2>%s || P=python; "
"exec \"$P\" -c %s") % (os.devnull, quote(pyscript))
pycmd = ("exec /bin/sh -c %s" % quote(pycmd))
argv = (sshl +
portl +

View File

@ -95,6 +95,8 @@ def _try_peername(sock):
_, e = sys.exc_info()[:2]
if e.args[0] not in (errno.ENOTCONN, errno.ENOTSOCK):
raise
except AttributeError:
pass
return 'unknown'

View File

@ -8,12 +8,24 @@ _p = None
def start_syslog():
global _p
_p = ssubprocess.Popen(['logger',
'-p', 'daemon.notice',
'-t', 'sshuttle'], stdin=ssubprocess.PIPE)
with open(os.devnull, 'w') as devnull:
_p = ssubprocess.Popen(
['logger', '-p', 'daemon.notice', '-t', 'sshuttle'],
stdin=ssubprocess.PIPE,
stdout=devnull,
stderr=devnull
)
def close_stdin():
sys.stdin.close()
def stdout_to_syslog():
sys.stdout.flush()
os.dup2(_p.stdin.fileno(), sys.stdout.fileno())
def stderr_to_syslog():
sys.stdout.flush()
sys.stderr.flush()
os.dup2(_p.stdin.fileno(), 2)
os.dup2(_p.stdin.fileno(), sys.stderr.fileno())

View File

@ -205,10 +205,10 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
b'2404:6800:4004:80c::/64 port 8000:9000 -> ::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 quick inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out route-to lo0 inet6 proto tcp to '
b'2404:6800:4004:80c::/64 port 8000:9000 keep state\n'
b'pass out inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out route-to lo0 inet6 proto udp '
b'to <dns_servers> port 53 keep state\n'),
call('-E'),
@ -257,8 +257,8 @@ def test_setup_firewall_darwin(mock_pf_get_dev, mock_ioctl, mock_pfctl):
b'-> 127.0.0.1 port 1025\n'
b'rdr pass on lo0 inet proto udp '
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
b'pass out quick inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out route-to lo0 inet proto tcp to 1.2.3.0/24 keep state\n'
b'pass out inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out route-to lo0 inet proto udp '
b'to <dns_servers> port 53 keep state\n'),
call('-E'),
@ -308,10 +308,10 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
b'2404:6800:4004:80c::/64 port 8000:9000 -> ::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 quick inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out route-to lo0 inet6 proto tcp to '
b'2404:6800:4004:80c::/64 port 8000:9000 keep state\n'
b'pass out inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out route-to lo0 inet6 proto udp '
b'to <dns_servers> port 53 keep state\n'),
call('-e'),
@ -359,8 +359,8 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
b'to 1.2.3.0/24 -> 127.0.0.1 port 1025\n'
b'rdr pass on lo0 inet proto udp '
b'to <dns_servers> port 53 -> 127.0.0.1 port 1027\n'
b'pass out quick inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out route-to lo0 inet proto tcp to 1.2.3.0/24 keep state\n'
b'pass out inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out route-to lo0 inet proto udp '
b'to <dns_servers> port 53 keep state\n'),
call('-e'),
@ -403,8 +403,8 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
None)
assert mock_ioctl.mock_calls == [
call(mock_pf_get_dev(), 0xcd48441a, ANY),
call(mock_pf_get_dev(), 0xcd48441a, ANY),
call(mock_pf_get_dev(), 0xcd58441a, ANY),
call(mock_pf_get_dev(), 0xcd58441a, ANY),
]
assert mock_pfctl.mock_calls == [
call('-s Interfaces -i lo -v'),
@ -416,10 +416,10 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
b'port 8000:9000 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 quick inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out inet6 proto tcp to 2404:6800:4004:80c::/64 '
b'port 8000:9000 route-to lo0 keep state\n'
b'pass out inet6 proto tcp to '
b'2404:6800:4004:80c::101f/128 port 8080:8080\n'
b'pass out inet6 proto udp to '
b'<dns_servers> port 53 route-to lo0 keep state\n'),
call('-e'),
@ -451,8 +451,8 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
False,
None)
assert mock_ioctl.mock_calls == [
call(mock_pf_get_dev(), 0xcd48441a, ANY),
call(mock_pf_get_dev(), 0xcd48441a, ANY),
call(mock_pf_get_dev(), 0xcd58441a, ANY),
call(mock_pf_get_dev(), 0xcd58441a, ANY),
]
assert mock_pfctl.mock_calls == [
call('-s Interfaces -i lo -v'),
@ -464,8 +464,8 @@ def test_setup_firewall_openbsd(mock_pf_get_dev, mock_ioctl, mock_pfctl):
b'127.0.0.1 port 1025\n'
b'pass in on lo0 inet proto udp to '
b'<dns_servers> port 53 rdr-to 127.0.0.1 port 1027\n'
b'pass out quick inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out inet proto tcp to 1.2.3.0/24 route-to lo0 keep state\n'
b'pass out inet proto tcp to 1.2.3.66/32 port 80:80\n'
b'pass out inet proto udp to '
b'<dns_servers> port 53 route-to lo0 keep state\n'),
call('-e'),

View File

@ -7,4 +7,4 @@ else:
collect_ignore = []
if not good_python:
collect_ignore.append("sshuttle/tests/client")
collect_ignore.append("client")