mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-11-22 07:53:43 +01:00
Simplify nftables based method
This commit is contained in:
parent
6e9c58b4b4
commit
3edeb726b8
@ -44,7 +44,7 @@ Options
|
|||||||
to during startup will be routed over the VPN. Valid examples are
|
to during startup will be routed over the VPN. Valid examples are
|
||||||
example.com, example.com:8000 and example.com:8000-9000.
|
example.com, example.com:8000 and example.com:8000-9000.
|
||||||
|
|
||||||
.. option:: --method [auto|nat|tproxy|pf]
|
.. option:: --method [auto|nat|nft|tproxy|pf]
|
||||||
|
|
||||||
Which firewall method should sshuttle use? For auto, sshuttle attempts to
|
Which firewall method should sshuttle use? For auto, sshuttle attempts to
|
||||||
guess the appropriate method depending on what it can find in PATH. The
|
guess the appropriate method depending on what it can find in PATH. The
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import subprocess as ssubprocess
|
import subprocess as ssubprocess
|
||||||
|
|
||||||
from sshuttle.helpers import log, debug1, Fatal, family_to_string
|
from sshuttle.helpers import log, debug1, Fatal, family_to_string
|
||||||
|
|
||||||
|
|
||||||
@ -52,10 +50,8 @@ def ipt(family, table, *args):
|
|||||||
|
|
||||||
|
|
||||||
def nft(family, table, action, *args):
|
def nft(family, table, action, *args):
|
||||||
if family == socket.AF_INET:
|
if family in (socket.AF_INET, socket.AF_INET6):
|
||||||
argv = ['nft', action, 'ip', table] + list(args)
|
argv = ['nft', action, 'inet', table] + list(args)
|
||||||
elif family == socket.AF_INET6:
|
|
||||||
argv = ['nft', action, 'ip6', table] + list(args)
|
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported family "%s"' % family_to_string(family))
|
raise Exception('Unsupported family "%s"' % family_to_string(family))
|
||||||
debug1('>> %s\n' % ' '.join(argv))
|
debug1('>> %s\n' % ' '.join(argv))
|
||||||
@ -68,48 +64,6 @@ def nft(family, table, action, *args):
|
|||||||
raise Fatal('%r returned %d' % (argv, rv))
|
raise Fatal('%r returned %d' % (argv, rv))
|
||||||
|
|
||||||
|
|
||||||
def nft_chain_exists(family, table, name):
|
|
||||||
if family == socket.AF_INET:
|
|
||||||
fam = 'ip'
|
|
||||||
elif family == socket.AF_INET6:
|
|
||||||
fam = 'ip6'
|
|
||||||
else:
|
|
||||||
raise Exception('Unsupported family "%s"' % family_to_string(family))
|
|
||||||
argv = ['nft', 'list', 'chain', fam, table, name]
|
|
||||||
debug1('>> %s\n' % ' '.join(argv))
|
|
||||||
env = {
|
|
||||||
'PATH': os.environ['PATH'],
|
|
||||||
'LC_ALL': "C",
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
table_exists = False
|
|
||||||
output = ssubprocess.check_output(argv, env=env,
|
|
||||||
stderr=ssubprocess.STDOUT)
|
|
||||||
for line in output.decode('ASCII').split('\n'):
|
|
||||||
if line.startswith('table %s %s ' % (fam, table)):
|
|
||||||
table_exists = True
|
|
||||||
if table_exists and ('chain %s {' % name) in line:
|
|
||||||
return True
|
|
||||||
except ssubprocess.CalledProcessError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def nft_get_handle(expression, chain):
|
|
||||||
cmd = 'nft'
|
|
||||||
argv = [cmd, 'list', expression, '-a']
|
|
||||||
env = {
|
|
||||||
'PATH': os.environ['PATH'],
|
|
||||||
'LC_ALL': "C",
|
|
||||||
}
|
|
||||||
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
|
_no_ttl_module = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import socket
|
import socket
|
||||||
from sshuttle.firewall import subnet_weight
|
from sshuttle.firewall import subnet_weight
|
||||||
from sshuttle.linux import nft, nft_get_handle, nft_chain_exists, nonfatal
|
from sshuttle.linux import nft, nonfatal
|
||||||
from sshuttle.methods import BaseMethod
|
from sshuttle.methods import BaseMethod
|
||||||
|
|
||||||
|
|
||||||
@ -16,22 +16,19 @@ class Method(BaseMethod):
|
|||||||
if udp:
|
if udp:
|
||||||
raise Exception("UDP not supported by nft")
|
raise Exception("UDP not supported by nft")
|
||||||
|
|
||||||
table = "nat"
|
table = 'sshuttle-%s' % port
|
||||||
|
|
||||||
def _nft(action, *args):
|
def _nft(action, *args):
|
||||||
return nft(family, table, action, *args)
|
return nft(family, table, action, *args)
|
||||||
|
|
||||||
|
chain = table
|
||||||
|
|
||||||
# basic cleanup/setup of chains
|
# basic cleanup/setup of chains
|
||||||
_nft('add table', '')
|
_nft('add table', '')
|
||||||
# prerouting, postrouting, and output chains may already exist
|
_nft('add chain', 'prerouting',
|
||||||
for chain in ['prerouting', 'postrouting', 'output']:
|
'{ type nat hook prerouting priority -100; policy accept; }')
|
||||||
rules = '{{ type nat hook {} priority -100; policy accept; }}' \
|
_nft('add chain', 'output',
|
||||||
.format(chain)
|
'{ type nat hook output priority -100; policy accept; }')
|
||||||
if not nft_chain_exists(family, table, chain):
|
|
||||||
_nft('add chain', chain, rules)
|
|
||||||
|
|
||||||
chain = 'sshuttle-%s' % port
|
|
||||||
|
|
||||||
_nft('add chain', chain)
|
_nft('add chain', chain)
|
||||||
_nft('flush chain', chain)
|
_nft('flush chain', chain)
|
||||||
_nft('add rule', 'output jump %s' % chain)
|
_nft('add rule', 'output jump %s' % chain)
|
||||||
@ -70,16 +67,10 @@ class Method(BaseMethod):
|
|||||||
if udp:
|
if udp:
|
||||||
raise Exception("UDP not supported by nft method_name")
|
raise Exception("UDP not supported by nft method_name")
|
||||||
|
|
||||||
table = "nat"
|
table = 'sshuttle-%s' % port
|
||||||
|
|
||||||
def _nft(action, *args):
|
def _nft(action, *args):
|
||||||
return nft(family, table, action, *args)
|
return nft(family, table, action, *args)
|
||||||
|
|
||||||
chain = 'sshuttle-%s' % port
|
|
||||||
|
|
||||||
# basic cleanup/setup of chains
|
# basic cleanup/setup of chains
|
||||||
handle = nft_get_handle('chain ip nat output', chain)
|
nonfatal(_nft, 'delete table', '')
|
||||||
nonfatal(_nft, 'delete rule', 'output', handle)
|
|
||||||
handle = nft_get_handle('chain ip nat prerouting', chain)
|
|
||||||
nonfatal(_nft, 'delete rule', 'prerouting', handle)
|
|
||||||
nonfatal(_nft, 'delete chain', chain)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user