1SSHUTTLE(1)                        sshuttle                        SSHUTTLE(1)
2
3
4

NAME

6       sshuttle - sshuttle documentation
7

SYNOPSIS

9       sshuttle [options] -r [username@]sshserver[:port] <subnets ...>
10

DESCRIPTION

12       sshuttle allows you to create a VPN connection from your machine to any
13       remote server that you can connect to via ssh, as long as  that  server
14       has a sufficiently new Python installation.
15
16       To  work,  you  must have root access on the local machine, but you can
17       have a normal account on the server.
18
19       It's valid to run sshuttle more than once simultaneously  on  a  single
20       client machine, connecting to a different server every time, so you can
21       be on more than one VPN at once.
22
23       If run on a router, sshuttle can forward traffic for your entire subnet
24       to the VPN.
25

OPTIONS

27       <subnets>
28              A   list  of  subnets  to  route  over  the  VPN,  in  the  form
29              a.b.c.d[/width][port[-port]]. Valid examples are 1.2.3.4 (a sin‐
30              gle   IP   address)  and  1.2.3.4/32  (equivalent  to  1.2.3.4),
31              1.2.3.0/24 (a 24-bit subnet, ie. with a 255.255.255.0  netmask).
32              Specify  subnets  0/0  to  match  all IPv4 addresses and ::/0 to
33              match all IPv6 addresses. Any of the previous examples are  also
34              valid if you append a port or a port range, so 1.2.3.4:8000 will
35              only tunnel traffic that has as the  destination  port  8000  of
36              1.2.3.4  and  1.2.3.0/24:8000-9000  will tunnel traffic going to
37              any port between 8000 and 9000 (inclusive) for all  IPs  in  the
38              1.2.3.0/24  subnet.  A hostname can be provided instead of an IP
39              address. If the hostname resolves to multiple IPs,  all  of  the
40              IPs  are  included.  If a width is provided with a hostname, the
41              width is applied to all of the hostnames IPs (if  they  are  all
42              either  IPv4  or  IPv6).  Widths cannot be supplied to hostnames
43              that resolve to both IPv4 and IPv6.  Valid  examples  are  exam‐
44              ple.com,  example.com:8000,  example.com/24, example.com/24:8000
45              and example.com:8000-9000.
46
47       --method <auto|nat|nft|tproxy|pf|ipfw>
48              Which firewall method should sshuttle use?  For  auto,  sshuttle
49              attempts  to  guess  the appropriate method depending on what it
50              can find in PATH. The default value is auto.
51
52       -l <[ip:]port>, --listen=<[ip:]port>
53              Use this ip address and port number  as  the  transparent  proxy
54              port.  By default sshuttle finds an available port automatically
55              and listens on IP 127.0.0.1 (localhost), so you  don't  need  to
56              override it, and connections are only proxied from the local ma‐
57              chine, not from outside machines.  If you want to accept connec‐
58              tions  from  other machines on your network (ie. to run sshuttle
59              on a router) try enabling IP Forwarding in your kernel, then us‐
60              ing --listen 0.0.0.0:0.  You can use any name resolving to an IP
61              address of the machine running sshuttle,  e.g.  --listen  local‐
62              host.
63
64              For  the nft, tproxy and pf methods this can be an IPv6 address.
65              Use this option with comma separated values if required, to pro‐
66              vide    both    IPv4   and   IPv6   addresses,   e.g.   --listen
67              127.0.0.1:0,[::1]:0.
68
69       -H, --auto-hosts
70              Scan for remote hostnames and update the local  /etc/hosts  file
71              with  matching  entries for as long as the VPN is open.  This is
72              nicer than changing your system's  DNS  (/etc/resolv.conf)  set‐
73              tings,  for several reasons.  First, hostnames are added without
74              domain names attached, so you can ssh thatserver without  worry‐
75              ing if your local domain matches the remote one.  Second, if you
76              sshuttle into more than one VPN at a time,  it's  impossible  to
77              use  more  than one DNS server at once anyway, but sshuttle cor‐
78              rectly merges /etc/hosts entries  between  all  running  copies.
79              Third,  if  you're  only routing a few subnets over the VPN, you
80              probably would prefer to keep using your local  DNS  server  for
81              everything else.
82
83              sshuttle  tries  to  store a cache of the hostnames in ~/.sshut‐
84              tle.hosts on the remote host. Similarly, it tries  to  read  the
85              file  when you later reconnect to the host with --auto-hosts en‐
86              abled to quickly populate the host  list.  When  troubleshooting
87              this  feature,  try  removing  this file on the remote host when
88              sshuttle is not running.
89
90       -N, --auto-nets
91              In addition to the subnets provided on the command line, ask the
92              server  which subnets it thinks we should route, and route those
93              automatically.  The suggestions are taken automatically from the
94              server's routing table.
95
96              This  feature  does not detect IPv6 routes. Specify IPv6 subnets
97              manually. For example, specify the ::/0 subnet  on  the  command
98              line to route all IPv6 traffic.
99
100       --dns  Capture local DNS requests and forward to the remote DNS server.
101              All queries to any of the local system's DNS  servers  (/etc/re‐
102              solv.conf  and,  if it exists, /run/systemd/resolve/resolv.conf)
103              will be intercepted and resolved on the remote side of the  tun‐
104              nel  instead,  there using the DNS specified via the --to-ns op‐
105              tion, if specified. Only plain DNS traffic sent to these servers
106              on port 53 are captured.
107
108       --ns-hosts=<server1[,server2[,server3[...]]]>
109              Capture  local  DNS requests to the specified server(s) and for‐
110              ward to the remote DNS server. Contrary  to  the  --dns  option,
111              this  flag  allows  to  specify the DNS server(s) the queries to
112              which to intercept, instead of intercepting all DNS  traffic  on
113              the  local machine. This can be useful when only certain DNS re‐
114              quests should be resolved on the remote side of the tunnel, e.g.
115              in combination with dnsmasq.
116
117       --to-ns=<server>
118              The DNS to forward requests to when remote DNS resolution is en‐
119              abled. If not given, sshuttle will simply resolve using the sys‐
120              tem configured resolver on the remote side (via /etc/resolv.conf
121              on the remote side).
122
123       --python
124              Specify the name/path of the remote python interpreter. The  de‐
125              fault is to use python3 (or python, if python3 fails) in the re‐
126              mote system's PATH.
127
128       -r       <[username@]sshserver[:port]>,       --remote=<[username@]ssh‐
129       server[:port]>
130              The remote hostname and optional username and ssh port number to
131              use for connecting to the remote  server.   For  example,  exam‐
132              ple.com, testuser@example.com, testuser@example.com:2222, or ex‐
133              ample.com:2244. This hostname is passed to ssh, so it will  rec‐
134              ognize  any  aliases  and  settings  you  may have configured in
135              ~/.ssh/config.
136
137       -x <subnet>, --exclude=<subnet>
138              Explicitly exclude this subnet from forwarding.  The  format  of
139              this  option  is  the  same as the <subnets> option.  To exclude
140              more than one subnet, specify the -x option more than once.  You
141              can  say  something like 0/0 -x 1.2.3.0/24 to forward everything
142              except the local subnet over the VPN, for example.
143
144       -X <file>, --exclude-from=<file>
145              Exclude the subnets specified in a file, one  subnet  per  line.
146              Useful when you have lots of subnets to exclude.
147
148       -v, --verbose
149              Print  more  information  about the session.  This option can be
150              used more than once for increased verbosity.  By default, sshut‐
151              tle prints only error messages.
152
153       -e, --ssh-cmd
154              The  command to use to connect to the remote server. The default
155              is just ssh.  Use this if your ssh client is in  a  non-standard
156              location  or  you  want to provide extra options to the ssh com‐
157              mand, for example, -e 'ssh -v'.
158
159       --seed-hosts
160              A comma-separated list of hostnames to  use  to  initialize  the
161              --auto-hosts scan algorithm.  --auto-hosts does things like poll
162              netstat output for lists  of  local  hostnames,  but  can  speed
163              things up if you use this option to give it a few names to start
164              from.
165
166              If this option is used without  --auto-hosts,  then  the  listed
167              hostnames  will  be  scanned and added, but no further hostnames
168              will be added.
169
170       --no-latency-control
171              Sacrifice latency to improve bandwidth benchmarks. ssh uses  re‐
172              ally  big  socket  buffers, which can overload the connection if
173              you start doing large file transfers, thus making all your other
174              sessions  inside  the  same tunnel go slowly. Normally, sshuttle
175              tries to avoid this problem using a "fullness check" that allows
176              only  a  certain  amount of outstanding data to be buffered at a
177              time.  But on high-bandwidth links, this can leave a lot of your
178              bandwidth  underutilized.   It  also makes sshuttle seem slow in
179              bandwidth benchmarks (benchmarks rarely test ping latency, which
180              is  what  sshuttle  is trying to control).  This option disables
181              the latency control feature, maximizing bandwidth usage.  Use at
182              your own risk.
183
184       --latency-buffer-size
185              Set  the size of the buffer used in latency control. The default
186              is 32768. Changing this option allows a compromise  to  be  made
187              between  latency  and bandwidth without completely disabling la‐
188              tency control (with --no-latency-control).
189
190       -D, --daemon
191              Automatically fork into the background after connecting  to  the
192              remote server.  Implies --syslog.
193
194       -s <file>, --subnets=<file>
195              Include  the  subnets specified in a file instead of on the com‐
196              mand line. One subnet per line.
197
198       --syslog
199              after connecting, send all log messages to the syslog(3) service
200              instead of stderr.  This is implicit if you use --daemon.
201
202       --pidfile=<pidfilename>
203              when  using  --daemon,  save sshuttle's pid to pidfilename.  The
204              default is sshuttle.pid in the current directory.
205
206       --disable-ipv6
207              Disable IPv6 support for methods  that  support  it  (nat,  nft,
208              tproxy, and pf).
209
210       --firewall
211              (internal  use only) run the firewall manager.  This is the only
212              part of sshuttle that must run as root.  If you  start  sshuttle
213              as  a  non-root  user,  it  will automatically run sudo or su to
214              start the firewall manager, but the core of sshuttle still  runs
215              as a normal user.
216
217       --hostwatch
218              (internal use only) run the hostwatch daemon.  This process runs
219              on the server side and collects hostnames for  the  --auto-hosts
220              option.   Using  this  option by itself makes it a lot easier to
221              debug and test the --auto-hosts feature.
222
223       --sudoers-no-modify
224              sshuttle prints a configuration to stdout which allows a user to
225              run  sshuttle  without  a  password. This option is INSECURE be‐
226              cause, with some cleverness, it also allows the user to run  any
227              command  as  root without a password. The output also includes a
228              suggested method for you to install the configuration.
229
230              Use --sudoers-user to modify the user that it applies to.
231
232       --sudoers-user
233              Set the user name or group with %group_name for passwordless op‐
234              eration.  Default  is the current user. Set to ALL for all users
235              (NOT RECOMMENDED: See note about security in --sudoers-no-modify
236              documentation  above).  Only  works with the --sudoers-no-modify
237              option.
238
239       -t <mark>, --tmark=<mark>
240              An option used by the tproxy method: Use the  specified  traffic
241              mark. The mark must be a hexadecimal value. Defaults to 0x01.
242
243       --version
244              Print program version.
245

CONFIGURATION FILE

247       All  the  options described above can optionally be specified in a con‐
248       figuration file.
249
250       To run sshuttle with options defined in, e.g., /etc/sshuttle.conf  just
251       pass   the  path  to  the  file  preceded  by  the  @  character,  e.g.
252       @/etc/sshuttle.conf.
253
254       When running sshuttle with options defined in a configuration file, op‐
255       tions  can  still be passed via the command line in addition to what is
256       defined in the file. If a given option is defined both in the file  and
257       in  the  command  line,  the value in the command line will take prece‐
258       dence.
259
260       Arguments read from a file must be one per line, as shown below:
261
262          value
263          --option1
264          value1
265          --option2
266          value2
267
268       The configuration file supports  comments  for  human-readable  annota‐
269       tions. For example:
270
271          # company-internal API
272          8.8.8.8/32
273          # home IoT
274          192.168.63.0/24
275

EXAMPLES

277       Use  the following command to route all IPv4 TCP traffic through remote
278       (-r) host example.com (and possibly other traffic too, depending on the
279       selected  --method).  The  0/0 subnet, short for 0.0.0.0/0, matches all
280       IPv4 addresses. The ::/0 subnet, matching all IPv6 addresses  could  be
281       added  to  the  example. We also exclude (-x) example.com:22 so that we
282       can establish ssh connections from our local machine to the remote host
283       without  them  being routed through sshuttle. Excluding the remote host
284       may be necessary on some machines for sshuttle to work properly.  Press
285       Ctrl+C  to exit. To also route DNS queries through sshuttle, try adding
286       --dns. Add or remove -v options to see more or less information:
287
288          $ sshuttle -r example.com -x example.com:22 0/0
289
290          Starting sshuttle proxy (version ...).
291          [local sudo] Password:
292          fw: Starting firewall with Python version 3.9.5
293          fw: ready method name nat.
294          c : IPv6 disabled since it isn't supported by method nat.
295          c : Method: nat
296          c : IPv4: on
297          c : IPv6: off (not available with nat method)
298          c : UDP : off (not available with nat method)
299          c : DNS : off (available)
300          c : User: off (available)
301          c : Subnets to forward through remote host (type, IP, cidr mask width, startPort, endPort):
302          c :   (<AddressFamily.AF_INET: 2>, '0.0.0.0', 0, 0, 0)
303          c : Subnets to exclude from forwarding:
304          c :   (<AddressFamily.AF_INET: 2>, '...', 32, 22, 22)
305          c :   (<AddressFamily.AF_INET: 2>, '127.0.0.1', 32, 0, 0)
306          c : TCP redirector listening on ('127.0.0.1', 12299).
307          c : Starting client with Python version 3.9.5
308          c : Connecting to server...
309          user@example.com's password:
310           s: Starting server with Python version 3.6.8
311           s: latency control setting = True
312           s: auto-nets:False
313          c : Connected to server.
314          fw: setting up.
315          fw: iptables -w -t nat -N sshuttle-12299
316          fw: iptables -w -t nat -F sshuttle-12299
317          ...
318          Accept: 192.168.42.121:60554 -> 77.141.99.22:22.
319          ^C
320          c : Keyboard interrupt: exiting.
321          c : SW'unknown':Mux#1: deleting (1 remain)
322          c : SW#7:192.168.42.121:60554: deleting (0 remain)
323
324       Connect to a remote server, with automatic hostname and  subnet  guess‐
325       ing:
326
327          $ sshuttle -vNHr example.com -x example.com:22
328          Starting sshuttle proxy (version ...).
329          [local sudo] Password:
330          fw: Starting firewall with Python version 3.9.5
331          fw: ready method name nat.
332          c : IPv6 disabled since it isn't supported by method nat.
333          c : Method: nat
334          c : IPv4: on
335          c : IPv6: off (not available with nat method)
336          c : UDP : off (not available with nat method)
337          c : DNS : off (available)
338          c : User: off (available)
339          c : Subnets to forward through remote host (type, IP, cidr mask width, startPort, endPort):
340          c : NOTE: Additional subnets to forward may be added below by --auto-nets.
341          c : Subnets to exclude from forwarding:
342          c :   (<AddressFamily.AF_INET: 2>, '...', 32, 22, 22)
343          c :   (<AddressFamily.AF_INET: 2>, '127.0.0.1', 32, 0, 0)
344          c : TCP redirector listening on ('127.0.0.1', 12300).
345          c : Starting client with Python version 3.9.5
346          c : Connecting to server...
347          user@example.com's password:
348           s: Starting server with Python version 3.6.8
349           s: latency control setting = True
350           s: auto-nets:True
351          c : Connected to server.
352          c : seed_hosts: []
353           s: available routes:
354           s:   77.141.99.0/24
355          fw: setting up.
356          fw: iptables -w -t nat -N sshuttle-12300
357          fw: iptables -w -t nat -F sshuttle-12300
358          ...
359          c : Accept: 192.168.42.121:60554 -> 77.141.99.22:22.
360          ^C
361          c : Keyboard interrupt: exiting.
362          c : SW'unknown':Mux#1: deleting (1 remain)
363          c : SW#7:192.168.42.121:60554: deleting (0 remain)
364
365       Run sshuttle with a /etc/sshuttle.conf configuration file:
366
367          $ sshuttle @/etc/sshuttle.conf
368
369       Use the options defined in /etc/sshuttle.conf but be more verbose:
370
371          $ sshuttle @/etc/sshuttle.conf -vvv
372
373       Override the remote server defined in /etc/sshuttle.conf:
374
375          $ sshuttle @/etc/sshuttle.conf -r otheruser@test.example.com
376
377       Example configuration file:
378
379          192.168.0.0/16
380          --remote
381          user@example.com
382

DISCUSSION

384       When it starts, sshuttle creates an ssh session to the server specified
385       by the -r option.
386
387       After connecting to the remote server, sshuttle  uploads  its  (python)
388       source  code  to the remote end and executes it there.  Thus, you don't
389       need to install sshuttle on the remote  server,  and  there  are  never
390       sshuttle version conflicts between client and server.
391
392       Unlike most VPNs, sshuttle forwards sessions, not packets.  That is, it
393       uses kernel transparent proxying (iptables REDIRECT rules on Linux)  to
394       capture  outgoing TCP sessions, then creates entirely separate TCP ses‐
395       sions out to the original destination at the other end of the tunnel.
396
397       Packet-level forwarding (eg. using the tun/tap devices on Linux)  seems
398       elegant  at first, but it results in several problems, notably the 'tcp
399       over tcp' problem.  The tcp protocol depends fundamentally  on  packets
400       being  dropped  in order to implement its congestion control algorithm;
401       if you pass tcp packets through a tcp-based tunnel (such as  ssh),  the
402       inner  tcp packets will never be dropped, and so the inner tcp stream's
403       congestion control will be completely broken, and performance  will  be
404       terrible.   Thus,  packet-based VPNs (such as IPsec and openvpn) cannot
405       use tcp-based encrypted streams like ssh or ssl, and have to  implement
406       their  own  encryption  from  scratch,  which is very complex and error
407       prone.
408
409       sshuttle's simplicity comes from the fact that it can  safely  use  the
410       existing  ssh encrypted tunnel without incurring a performance penalty.
411       It does this by letting the client-side kernel manage the incoming  tcp
412       stream,  and  the  server-side  kernel  manage the outgoing tcp stream;
413       there is no need for congestion control to be shared  between  the  two
414       separate streams, so a tcp-based tunnel is fine.
415
416       SEE ALSO:
417          ssh(1), python(1)
418

AUTHOR

420       Brian May
421
423       2023, Brian May
424
425
426
427
4281.1                              Jan 21, 2023                      SSHUTTLE(1)
Impressum