mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-01-08 06:59:32 +01:00
TProxy support as well as NAT support.
This commit is contained in:
parent
9a7412c08f
commit
f41c6b62e5
11
client.py
11
client.py
@ -12,6 +12,7 @@ def got_signal(signum, frame):
|
||||
|
||||
|
||||
_pidname = None
|
||||
IP_TRANSPARENT = 19
|
||||
def check_daemon(pidfile):
|
||||
global _pidname
|
||||
_pidname = os.path.abspath(pidfile)
|
||||
@ -232,8 +233,11 @@ def onaccept_tcp(listener, method, mux, handlers):
|
||||
return
|
||||
else:
|
||||
raise
|
||||
dstip = original_dst(sock)
|
||||
debug1('Accept: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
|
||||
if method == "tproxy":
|
||||
dstip = sock.getsockname();
|
||||
else:
|
||||
dstip = original_dst(sock)
|
||||
debug1('Accept TCP: %s:%r -> %s:%r.\n' % (srcip[0],srcip[1],
|
||||
dstip[0],dstip[1]))
|
||||
if dstip[1] == listener.getsockname()[1] and islocal(dstip[0], sock.family):
|
||||
debug1("-- ignored: that's my address!\n")
|
||||
@ -466,6 +470,9 @@ def main(listenip_v4,
|
||||
|
||||
fw = FirewallClient(redirectport_v4, subnets_include, subnets_exclude, dnsport_v4, method)
|
||||
|
||||
if fw.method == "tproxy":
|
||||
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
|
||||
|
||||
try:
|
||||
return _main(tcp_listener, fw, ssh_cmd, remotename,
|
||||
python, latency_control, dns_listener,
|
||||
|
63
firewall.py
63
firewall.py
@ -118,6 +118,67 @@ def do_iptables_nat(port, dnsport, family, subnets):
|
||||
'--to-ports', str(dnsport))
|
||||
|
||||
|
||||
def do_iptables_tproxy(port, dnsport, family, subnets):
|
||||
if family not in [socket.AF_INET]:
|
||||
raise Exception('Address family "%s" unsupported by tproxy method'%family_to_string(family))
|
||||
|
||||
table = "mangle"
|
||||
def ipt(*args):
|
||||
return _ipt(family, table, *args)
|
||||
def ipt_ttl(*args):
|
||||
return _ipt_ttl(family, table, *args)
|
||||
|
||||
mark_chain = 'sshuttle-m-%s' % port
|
||||
tproxy_chain = 'sshuttle-t-%s' % port
|
||||
divert_chain = 'sshuttle-d-%s' % port
|
||||
|
||||
# basic cleanup/setup of chains
|
||||
if ipt_chain_exists(family, table, mark_chain):
|
||||
ipt('-D', 'OUTPUT', '-j', mark_chain)
|
||||
ipt('-F', mark_chain)
|
||||
ipt('-X', mark_chain)
|
||||
|
||||
if ipt_chain_exists(family, table, tproxy_chain):
|
||||
ipt('-D', 'PREROUTING', '-j', tproxy_chain)
|
||||
ipt('-F', tproxy_chain)
|
||||
ipt('-X', tproxy_chain)
|
||||
|
||||
if ipt_chain_exists(family, table, divert_chain):
|
||||
ipt('-F', divert_chain)
|
||||
ipt('-X', divert_chain)
|
||||
|
||||
if subnets or dnsport:
|
||||
ipt('-N', mark_chain)
|
||||
ipt('-F', mark_chain)
|
||||
ipt('-N', divert_chain)
|
||||
ipt('-F', divert_chain)
|
||||
ipt('-N', tproxy_chain)
|
||||
ipt('-F', tproxy_chain)
|
||||
ipt('-I', 'OUTPUT', '1', '-j', mark_chain)
|
||||
ipt('-I', 'PREROUTING', '1', '-j', tproxy_chain)
|
||||
ipt('-A', divert_chain, '-j', 'MARK', '--set-mark', '1')
|
||||
ipt('-A', divert_chain, '-j', 'ACCEPT')
|
||||
ipt('-A', tproxy_chain, '-m', 'socket', '-j', divert_chain,
|
||||
'-m', 'tcp', '-p', 'tcp')
|
||||
if subnets:
|
||||
for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[1], reverse=True):
|
||||
if sexclude:
|
||||
ipt('-A', mark_chain, '-j', 'RETURN',
|
||||
'--dest', '%s/%s' % (snet,swidth),
|
||||
'-m', 'tcp', '-p', 'tcp')
|
||||
ipt('-A', tproxy_chain, '-j', 'RETURN',
|
||||
'--dest', '%s/%s' % (snet,swidth),
|
||||
'-m', 'tcp', '-p', 'tcp')
|
||||
else:
|
||||
ipt('-A', mark_chain, '-j', 'MARK', '--set-mark', '1',
|
||||
'--dest', '%s/%s' % (snet,swidth),
|
||||
'-m', 'tcp', '-p', 'tcp')
|
||||
ipt('-A', tproxy_chain, '-j', 'TPROXY', '--tproxy-mark', '0x1/0x1',
|
||||
'--dest', '%s/%s' % (snet,swidth),
|
||||
'-m', 'tcp', '-p', 'tcp',
|
||||
'--on-port', str(port))
|
||||
|
||||
|
||||
def ipfw_rule_exists(n):
|
||||
argv = ['ipfw', 'list']
|
||||
p = ssubprocess.Popen(argv, stdout = ssubprocess.PIPE)
|
||||
@ -408,6 +469,8 @@ def main(port_v4, dnsport_v4, method, syslog):
|
||||
|
||||
if method == "nat":
|
||||
do_it = do_iptables_nat
|
||||
elif method == "tproxy":
|
||||
do_it = do_iptables_tproxy
|
||||
elif method == "ipfw":
|
||||
do_it = do_ipfw
|
||||
else:
|
||||
|
4
main.py
4
main.py
@ -60,7 +60,7 @@ l,listen= transproxy to this ip address and port number [127.0.0.1:0]
|
||||
H,auto-hosts scan for remote hostnames and update local /etc/hosts
|
||||
N,auto-nets automatically determine subnets to route
|
||||
dns capture local DNS requests and forward to the remote DNS server
|
||||
method= auto, nat, or ipfw
|
||||
method= auto, nat, tproxy, or ipfw
|
||||
python= path to python interpreter on the remote server
|
||||
r,remote= ssh hostname (and optional username) of remote sshuttle server
|
||||
x,exclude= exclude this subnet (can be used more than once)
|
||||
@ -120,7 +120,7 @@ try:
|
||||
sh = None
|
||||
if not opt.method:
|
||||
method = "auto"
|
||||
elif opt.method in [ "auto", "nat", "ipfw" ]:
|
||||
elif opt.method in [ "auto", "nat", "tproxy", "ipfw" ]:
|
||||
method = opt.method
|
||||
else:
|
||||
o.fatal("method %s not supported"%opt.method)
|
||||
|
Loading…
Reference in New Issue
Block a user