Add .gitignore .vscode/ path. Resolve the issue #374 adding tproxy mark option to allow different network mapping.

Signed-off-by: Samuel Bernardo <samuel@lip.pt>
This commit is contained in:
Samuel Bernardo 2020-12-06 17:23:15 +00:00 committed by Brian May
parent a5214e0fd7
commit 76b8b83e22
7 changed files with 37 additions and 15 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@
/.redo /.redo
/.pytest_cache/ /.pytest_cache/
/.python-version /.python-version
.vscode/

View File

@ -274,6 +274,10 @@ Options
Set the file name for the sudoers.d file to be added. Default is Set the file name for the sudoers.d file to be added. Default is
"sshuttle_auto". Only works with --sudoers. "sshuttle_auto". Only works with --sudoers.
.. option:: -t, --tmark
Transproxy optional traffic mark with provided MARK value.
.. option:: --version .. option:: --version
Print program version. Print program version.

View File

@ -8,9 +8,11 @@ There are some things you need to consider for TPROXY to work:
done once after booting up:: done once after booting up::
ip route add local default dev lo table 100 ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100 ip rule add fwmark {TMARK} lookup 100
ip -6 route add local default dev lo table 100 ip -6 route add local default dev lo table 100
ip -6 rule add fwmark 1 lookup 100 ip -6 rule add fwmark {TMARK} lookup 100
where {TMARK} is the identifier mark passed with -t or --tmark flag (default value is 1).
- The ``--auto-nets`` feature does not detect IPv6 routes automatically. Add IPv6 - The ``--auto-nets`` feature does not detect IPv6 routes automatically. Add IPv6
routes manually. e.g. by adding ``'::/0'`` to the end of the command line. routes manually. e.g. by adding ``'::/0'`` to the end of the command line.

View File

@ -248,7 +248,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): 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
@ -258,6 +258,7 @@ class FirewallClient:
self.dnsport_v4 = dnsport_v4 self.dnsport_v4 = dnsport_v4
self.udp = udp self.udp = udp
self.user = user self.user = user
self.tmark = tmark
def check(self): def check(self):
rv = self.p.poll() rv = self.p.poll()
@ -576,7 +577,7 @@ def main(listenip_v6, listenip_v4,
ssh_cmd, remotename, python, latency_control, dns, nslist, ssh_cmd, remotename, python, latency_control, 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): user, sudo_pythonpath, tmark):
if not remotename: if not remotename:
print("WARNING: You must specify -r/--remote to securely route " print("WARNING: You must specify -r/--remote to securely route "
@ -902,7 +903,7 @@ 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) required.udp, user, tmark)
# start the client process # start the client process
try: try:

View File

@ -107,7 +107,8 @@ def main():
opt.to_ns, opt.to_ns,
opt.pidfile, opt.pidfile,
opt.user, opt.user,
opt.sudo_pythonpath) opt.sudo_pythonpath,
opt.tmark)
if return_code == 0: if return_code == 0:
log('Normal exit code, exiting...') log('Normal exit code, exiting...')

View File

@ -152,6 +152,11 @@ class Method(BaseMethod):
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp, def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
user): user):
self.setup_firewall_tproxy(port, dnsport, nslist, family, subnets, udp,
user, self.firewall.tmark)
def setup_firewall_tproxy(self, port, dnsport, nslist, family, subnets, udp,
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'
@ -182,9 +187,9 @@ class Method(BaseMethod):
_ipt('-F', divert_chain) _ipt('-F', divert_chain)
_ipt('-N', tproxy_chain) _ipt('-N', tproxy_chain)
_ipt('-F', tproxy_chain) _ipt('-F', tproxy_chain)
_ipt('-I', 'OUTPUT', '1', '-j', mark_chain) _ipt('-I', 'OUTPUT', tmark, '-j', mark_chain)
_ipt('-I', 'PREROUTING', '1', '-j', tproxy_chain) _ipt('-I', 'PREROUTING', tmark, '-j', tproxy_chain)
_ipt('-A', divert_chain, '-j', 'MARK', '--set-mark', '1') _ipt('-A', divert_chain, '-j', 'MARK', '--set-mark', tmark)
_ipt('-A', divert_chain, '-j', 'ACCEPT') _ipt('-A', divert_chain, '-j', 'ACCEPT')
_ipt('-A', tproxy_chain, '-m', 'socket', '-j', divert_chain, _ipt('-A', tproxy_chain, '-m', 'socket', '-j', divert_chain,
'-m', 'tcp', '-p', 'tcp') '-m', 'tcp', '-p', 'tcp')
@ -194,11 +199,11 @@ class Method(BaseMethod):
'-m', 'udp', '-p', 'udp') '-m', 'udp', '-p', 'udp')
for _, ip in [i for i in nslist if i[0] == family]: for _, ip in [i for i in nslist if i[0] == family]:
_ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1', _ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', tmark,
'--dest', '%s/32' % ip, '--dest', '%s/32' % ip,
'-m', 'udp', '-p', 'udp', '--dport', '53') '-m', 'udp', '-p', 'udp', '--dport', '53')
_ipt('-A', tproxy_chain, '-j', 'TPROXY', _ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1', '--tproxy-mark', '0x'+tmark+'/0x'+tmark,
'--dest', '%s/32' % ip, '--dest', '%s/32' % ip,
'-m', 'udp', '-p', 'udp', '--dport', '53', '-m', 'udp', '-p', 'udp', '--dport', '53',
'--on-port', str(dnsport)) '--on-port', str(dnsport))
@ -218,12 +223,12 @@ class Method(BaseMethod):
'-m', 'tcp', '-m', 'tcp',
*tcp_ports) *tcp_ports)
else: else:
_ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1', _ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', tmark,
'--dest', '%s/%s' % (snet, swidth), '--dest', '%s/%s' % (snet, swidth),
'-m', 'tcp', '-m', 'tcp',
*tcp_ports) *tcp_ports)
_ipt('-A', tproxy_chain, '-j', 'TPROXY', _ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1', '--tproxy-mark', '0x'+tmark+'/0x'+tmark,
'--dest', '%s/%s' % (snet, swidth), '--dest', '%s/%s' % (snet, swidth),
'-m', 'tcp', '-m', 'tcp',
*(tcp_ports + ('--on-port', str(port)))) *(tcp_ports + ('--on-port', str(port))))
@ -242,12 +247,12 @@ class Method(BaseMethod):
'-m', 'udp', '-m', 'udp',
*udp_ports) *udp_ports)
else: else:
_ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1', _ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', tmark,
'--dest', '%s/%s' % (snet, swidth), '--dest', '%s/%s' % (snet, swidth),
'-m', 'udp', '-m', 'udp',
*udp_ports) *udp_ports)
_ipt('-A', tproxy_chain, '-j', 'TPROXY', _ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1', '--tproxy-mark', '0x'+tmark+'/0x'+tmark,
'--dest', '%s/%s' % (snet, swidth), '--dest', '%s/%s' % (snet, swidth),
'-m', 'udp', '-m', 'udp',
*(udp_ports + ('--on-port', str(port)))) *(udp_ports + ('--on-port', str(port))))

View File

@ -409,3 +409,11 @@ parser.add_argument(
do not set PYTHONPATH when invoking sudo do not set PYTHONPATH when invoking sudo
""" """
) )
parser.add_argument(
"-t", "--tmark",
metavar="[MARK]",
deafult="1",
help="""
transproxy optional traffic mark with provided MARK value
"""
)