mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-11-22 07:53:43 +01:00
dns: add support for MacOS (but it doesn't work...)
...because stupid MacOS ipfw 'fwd' rules don't work quite right with udp. It can intercept packets bound for remote hosts, but it doesn't correctly rewrite the port number from its original to the new socket, so it gets dropped by the local kernel anyway. That is, a packet to 1.2.3.4:53 should be redirected to, say, 127.0.0.1:9999, the local DNS listener socket. But instead, it gets sent to 127.0.0.1:53, which nobody is listening on, so it gets eaten. Sigh.
This commit is contained in:
parent
760740e9aa
commit
ebfc3703ec
18
firewall.py
18
firewall.py
@ -59,12 +59,13 @@ def do_iptables(port, dnsport, subnets):
|
||||
ipt('-F', chain)
|
||||
ipt('-X', chain)
|
||||
|
||||
if subnets:
|
||||
if subnets or dnsport:
|
||||
ipt('-N', chain)
|
||||
ipt('-F', chain)
|
||||
ipt('-I', 'OUTPUT', '1', '-j', chain)
|
||||
ipt('-I', 'PREROUTING', '1', '-j', chain)
|
||||
|
||||
if subnets:
|
||||
# create new subnet entries. Note that we're sorting in a very
|
||||
# particular order: we need to go from most-specific (largest swidth)
|
||||
# to least-specific, and at any given level of specificity, we want
|
||||
@ -98,6 +99,7 @@ def ipfw_rule_exists(n):
|
||||
for line in p.stdout:
|
||||
if line.startswith('%05d ' % n):
|
||||
if not ('ipttl 42 setup keep-state' in line
|
||||
or 'ipttl 42 keep-state' in line
|
||||
or ('skipto %d' % (n+1)) in line
|
||||
or 'check-state' in line):
|
||||
log('non-sshuttle ipfw rule: %r\n' % line.strip())
|
||||
@ -167,13 +169,14 @@ def do_ipfw(port, dnsport, subnets):
|
||||
oldval = _oldctls[name]
|
||||
_sysctl_set(name, oldval)
|
||||
|
||||
if subnets:
|
||||
if subnets or dnsport:
|
||||
sysctl_set('net.inet.ip.fw.enable', 1)
|
||||
sysctl_set('net.inet.ip.scopedroute', 0)
|
||||
|
||||
ipfw('add', sport, 'check-state', 'ip',
|
||||
'from', 'any', 'to', 'any')
|
||||
|
||||
|
||||
if subnets:
|
||||
# create new subnet entries
|
||||
for swidth,sexclude,snet in sorted(subnets, reverse=True):
|
||||
if sexclude:
|
||||
@ -186,6 +189,14 @@ def do_ipfw(port, dnsport, subnets):
|
||||
'from', 'any', 'to', '%s/%s' % (snet,swidth),
|
||||
'not', 'ipttl', '42', 'keep-state', 'setup')
|
||||
|
||||
if dnsport:
|
||||
nslist = resolvconf_nameservers()
|
||||
for ip in nslist:
|
||||
ipfw('add', sport, 'fwd', '127.0.0.1,%d' % dnsport,
|
||||
'log', 'udp',
|
||||
'from', 'any', 'to', '%s/32' % ip, '53',
|
||||
'not', 'ipttl', '42', 'keep-state')
|
||||
|
||||
|
||||
def program_exists(name):
|
||||
paths = (os.getenv('PATH') or os.defpath).split(os.pathsep)
|
||||
@ -194,6 +205,7 @@ def program_exists(name):
|
||||
if os.path.exists(fn):
|
||||
return not os.path.isdir(fn) and os.access(fn, os.X_OK)
|
||||
|
||||
|
||||
hostmap = {}
|
||||
def rewrite_etc_hosts(port):
|
||||
HOSTSFILE='/etc/hosts'
|
||||
|
Loading…
Reference in New Issue
Block a user