summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvery Pennarun <apenwarr@gmail.com>2010-10-01 00:00:45 -0700
committerAvery Pennarun <apenwarr@gmail.com>2010-10-01 00:36:46 -0700
commit8b4466b802ff3fb19b80f5d594a188c4638b32d6 (patch)
tree31570e41839516e1e70816231c9329c455db5d8a
parent4bf4f70c670b929f5018091bb5ef2e5fbcf71ff3 (diff)
BSD ipfw: switch from 'established' to 'keep-state/check-state'.
It turns out 'established' doesn't work the way I expected it to from iptables; it's not stateful. It just checks the TCP flags to see if the connection *thinks* it's already established, and follows the rule if so. That caused the first packet of each new connection to set sent to our transproxy, but not the subsequent ones, so weird stuff happened. With this change, any (matching) connection created *after* starting sshuttle will get forwarded, but pre-existing ones - most importantly, sshuttle's own ssh connection - will not. And with this (plus the previous commit), sshuttle works on MacOS, including 10.6!
-rw-r--r--firewall.py15
1 files changed, 10 insertions, 5 deletions
diff --git a/firewall.py b/firewall.py
index b7110e0..8f57504 100644
--- a/firewall.py
+++ b/firewall.py
@@ -65,14 +65,19 @@ def do_iptables(port, subnets):
def ipfw_rule_exists(n):
argv = ['ipfw', 'list']
p = subprocess.Popen(argv, stdout = subprocess.PIPE)
+ found = False
for line in p.stdout:
if line.startswith('%05d ' % n):
- if line.find('ipttl 42') < 0 and line.find('established') < 0:
+ if not ('ipttl 42 setup 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())
raise Fatal('non-sshuttle ipfw rule #%d already exists!' % n)
- return True
+ found = True
rv = p.wait()
if rv:
raise Fatal('%r returned %d' % (argv, rv))
+ return found
def sysctl_get(name):
@@ -127,8 +132,8 @@ def do_ipfw(port, subnets):
sysctl_set('net.inet.ip.forwarding', 1)
sysctl_set('net.inet.ip.scopedroute', 0)
- ipfw('add', sport, 'accept', 'ip',
- 'from', 'any', 'to', 'any', 'established')
+ ipfw('add', sport, 'check-state', 'ip',
+ 'from', 'any', 'to', 'any')
# create new subnet entries
for swidth,sexclude,snet in sorted(subnets, reverse=True):
@@ -140,7 +145,7 @@ def do_ipfw(port, subnets):
ipfw('add', sport, 'fwd', '127.0.0.1,%d' % port,
'log', 'tcp',
'from', 'any', 'to', '%s/%s' % (snet,swidth),
- 'not', 'ipttl', '42')
+ 'not', 'ipttl', '42', 'keep-state', 'setup')
def program_exists(name):