Skip to content

Commit a7df12c

Browse files
committed
Fix --tmark option
Even when --tmark was used, the iptables code always used '1' for the mark. This patch corrects the problem. Previously, it wasn't clear if the tmark should be supplied in hexadecimal or as an integer. This makes it use hexadecimal, checks that the input is hexadecimal, and updates the associated documentation. This patch also makes --ttl information get passed to the firewall in a way that matches how other information gets passed. The ttl and tmark information are passed next to each other in many places and this patch also makes the order consistent.
1 parent bc54ffe commit a7df12c

File tree

16 files changed

+71
-66
lines changed

16 files changed

+71
-66
lines changed

docs/manpage.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,10 @@ Options
274274
Set the file name for the sudoers.d file to be added. Default is
275275
"sshuttle_auto". Only works with --sudoers.
276276

277-
.. option:: -t, --tmark
277+
.. option:: -t <mark>, --tmark=<mark>
278278

279-
Transproxy optional traffic mark with provided MARK value.
279+
An option used by the tproxy method: Use the specified traffic
280+
mark. The mark must be a hexadecimal value. Defaults to 0x01.
280281

281282
.. option:: --version
282283

docs/tproxy.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ There are some things you need to consider for TPROXY to work:
1212
ip -6 route add local default dev lo table 100
1313
ip -6 rule add fwmark {TMARK} lookup 100
1414
15-
where {TMARK} is the identifier mark passed with -t or --tmark flag (default value is 1).
15+
where {TMARK} is the identifier mark passed with -t or --tmark flag
16+
as a hexadecimal string (default value is '0x01').
1617

1718
- The ``--auto-nets`` feature does not detect IPv6 routes automatically. Add IPv6
1819
routes manually. e.g. by adding ``'::/0'`` to the end of the command line.

sshuttle/client.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,7 @@ def __init__(self, method_name, sudo_pythonpath, ttl):
205205
argvbase = ([sys.executable, sys.argv[0]] +
206206
['-v'] * (helpers.verbose or 0) +
207207
['--method', method_name] +
208-
['--firewall'] +
209-
['--ttl', str(ttl)])
208+
['--firewall'])
210209
if ssyslog._p:
211210
argvbase += ['--syslog']
212211

@@ -261,7 +260,7 @@ def setup():
261260

262261
def setup(self, subnets_include, subnets_exclude, nslist,
263262
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4, udp,
264-
user, tmark, ttl):
263+
user, ttl, tmark):
265264
self.subnets_include = subnets_include
266265
self.subnets_exclude = subnets_exclude
267266
self.nslist = nslist
@@ -311,7 +310,9 @@ def start(self):
311310
else:
312311
user = b'%d' % self.user
313312

314-
self.pfile.write(b'GO %d %s\n' % (udp, user))
313+
self.pfile.write(b'GO %d %s %d %s\n' %
314+
(udp, user, self.ttl,
315+
bytes(self.tmark, 'ascii')))
315316
self.pfile.flush()
316317

317318
line = self.pfile.readline()
@@ -1003,7 +1004,7 @@ def feature_status(label, enabled, available):
10031004
# start the firewall
10041005
fw.setup(subnets_include, subnets_exclude, nslist,
10051006
redirectport_v6, redirectport_v4, dnsport_v6, dnsport_v4,
1006-
required.udp, user, tmark, ttl)
1007+
required.udp, user, ttl, tmark)
10071008

10081009
# start the client process
10091010
try:

sshuttle/cmdline.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ def main():
8585
ipport_v4 = "auto"
8686
# parse_ipport6('[::1]:0')
8787
ipport_v6 = "auto" if not opt.disable_ipv6 else None
88+
try:
89+
int(opt.tmark, 16)
90+
except ValueError:
91+
parser.error("--tmark must be a hexadecimal value")
92+
opt.tmark = opt.tmark.lower() # make 'x' in 0x lowercase
93+
if not opt.tmark.startswith("0x"): # accept without 0x prefix
94+
opt.tmark = "0x%s" % opt.tmark
8895
if opt.syslog:
8996
ssyslog.start_syslog()
9097
ssyslog.close_stdin()

sshuttle/firewall.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,13 @@ def main(method_name, syslog, ttl):
223223
raise Fatal('expected GO but got %r' % line)
224224

225225
_, _, args = line.partition(" ")
226-
udp, user = args.strip().split(" ", 1)
226+
udp, user, ttl, tmark = args.strip().split(" ", 3)
227227
udp = bool(int(udp))
228228
if user == '-':
229229
user = None
230-
debug2('Got udp: %r, user: %r' % (udp, user))
230+
ttl = int(ttl)
231+
debug2('Got udp: %r, user: %r, ttl: %s, tmark: %s' %
232+
(udp, user, ttl, tmark))
231233

232234
subnets_v6 = [i for i in subnets if i[0] == socket.AF_INET6]
233235
nslist_v6 = [i for i in nslist if i[0] == socket.AF_INET6]
@@ -242,14 +244,14 @@ def main(method_name, syslog, ttl):
242244
method.setup_firewall(
243245
port_v6, dnsport_v6, nslist_v6,
244246
socket.AF_INET6, subnets_v6, udp,
245-
user, ttl)
247+
user, ttl, tmark)
246248

247249
if subnets_v4 or nslist_v4:
248250
debug2('setting up IPv4.')
249251
method.setup_firewall(
250252
port_v4, dnsport_v4, nslist_v4,
251253
socket.AF_INET, subnets_v4, udp,
252-
user, ttl)
254+
user, ttl, tmark)
253255

254256
flush_systemd_dns_cache()
255257
stdout.write('STARTED\n')

sshuttle/methods/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def assert_features(self, features):
9191
(key, self.name))
9292

9393
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
94-
user):
94+
user, ttl, tmark):
9595
raise NotImplementedError()
9696

9797
def restore_firewall(self, port, family, udp, user):

sshuttle/methods/ipfw.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def setup_udp_listener(self, udp_listener):
189189
# udp_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVDSTADDR, 1)
190190

191191
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
192-
user, ttl):
192+
user, ttl, tmark):
193193
# IPv6 not supported
194194
if family not in [socket.AF_INET]:
195195
raise Exception(

sshuttle/methods/nat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Method(BaseMethod):
1313
# recently-started one will win (because we use "-I OUTPUT 1" instead of
1414
# "-A OUTPUT").
1515
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
16-
user, ttl):
16+
user, ttl, tmark):
1717
# only ipv4 supported with NAT
1818
if family != socket.AF_INET:
1919
raise Exception(

sshuttle/methods/nft.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Method(BaseMethod):
1313
# recently-started one will win (because we use "-I OUTPUT 1" instead of
1414
# "-A OUTPUT").
1515
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
16-
user, ttl):
16+
user, ttl, tmark):
1717
if udp:
1818
raise Exception("UDP not supported by nft")
1919

sshuttle/methods/pf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def get_tcp_dstip(self, sock):
444444
return sock.getsockname()
445445

446446
def setup_firewall(self, port, dnsport, nslist, family, subnets, udp,
447-
user, ttl):
447+
user, ttl, tmark):
448448
if family not in [socket.AF_INET, socket.AF_INET6]:
449449
raise Exception(
450450
'Address family "%s" unsupported by pf method_name'

0 commit comments

Comments
 (0)