Commit Graph

972 Commits

Author SHA1 Message Date
Avery Pennarun
b0f061e204 Implement our own left-shift operator to shut up python 2.3 warnings.
Apparently left-shift in python 2.3 just *always* prints a warning, even if
we weren't doing anything wrong.  Or maybe it only prints the warning
sometimes.  Anyway, let's just multiply by 2**x instead of using <<x, since
we're not performance-sensitive anyway.
2010-10-01 14:46:34 -07:00
Avery Pennarun
c403a83ab8 Don't use set() since it's not in python 2.3.
Just use a plain list instead.  Technically probably slightly worse
asymptotic behaviour, but it's not like we'll have a million sockets anyway.
2010-10-01 14:38:08 -07:00
Avery Pennarun
da774f3f46 import and use subprocess.py from python 2.6.
This should hopefully let us run even on python 2.3 on really old servers.
2010-10-01 12:11:48 -07:00
Avery Pennarun
7d3028dee2 Remove list comprehensions for python 2.3 compatibility. 2010-10-01 11:55:45 -07:00
Avery Pennarun
518df41049 ssh.py: don't os.setsid().
This prevents ssh from asking for a password successfully.  Error reported
by Chetan Kunte.
2010-10-01 11:35:13 -07:00
Avery Pennarun
76bbbfd67b Catch the exception thrown when ssh can't connect.
Easiest test: give it an invalid hostname.

Reported by Chetan Kunte.
2010-10-01 10:34:20 -07:00
Avery Pennarun
6e336c09bf README: remove the note about MacOS not working. It works now! 2010-10-01 00:43:01 -07:00
Avery Pennarun
f950a3800b BSD: sysctl net.inet.ip.forwarding=1 is not necessary.
If your machine is a firewall/router, it affects whether people behind the
router can use your sshuttle connection - in the same way that it affects
whether they can route *anything* through you.  And thus, it should be set
by the admin, not by sshuttle.

sshuttle works fine for the local user either way.

(This also affects MacOS since it's a BSD variant.)
2010-10-01 00:39:30 -07:00
Avery Pennarun
8b4466b802 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!
2010-10-01 00:36:46 -07:00
Avery Pennarun
4bf4f70c67 ssnet: recover slightly more gracefully from an infinite forwarding loop.
If you 'telnet localhost 12300' weird things happen; someday we should
probably auto-detect and avoid that altogether.  But meanwhile, catch EPIPE
if it happens (it's irrelevant) and don't barf with a %d data type for a
value that can apparently sometimes be None.
2010-10-01 00:05:49 -07:00
Avery Pennarun
410b9d4229 Magic incantation to mostly fix MacOS 10.6.
It comes down to this:
   sysctl_set('net.inet.ip.scopedroute', 0)

I say "mostly" because actually it doesn't fix it; sshuttle doesn't know
what to do with the received connection, so there must be a minor bug
remaining somewhere.  I'll fix that next.

Thanks to dkf <dfortunato@gmail.com> on the sshuttle mailing list for
suggesting the magic fix.  He points at this post in particular:
  http://discussions.apple.com/thread.jspa?messageID=11558355&#11558355
that gave him the necessary clue.
2010-10-01 00:05:48 -07:00
Avery Pennarun
2ef1c6a4c4 latest options.py from bup, now with tty-width guessing.
as of bup commit bup-0.19-2-gce2ace5.
2010-09-21 18:03:17 -07:00
Frederik Deweerdt
b35cfbd022 hostwatch: add missing errno import
If the ~/.sshuttle.hosts file does not exist, it triggers the following
error:

       Traceback (most recent call last):
         File "./sshuttle", line 80, in <module>
           sys.exit(hostwatch.hw_main(extra))
         File "/home/def/p/sshuttle/hostwatch.py", line 246, in hw_main
           read_host_cache()
         File "/home/def/p/sshuttle/hostwatch.py", line 41, in read_host_cache
           if e.errno == errno.ENOENT:
       NameError: global name 'errno' is not defined

(This only happened if you run 'sshuttle --hostwatch' from the command line
directly, without passing it through assembler.py.)
2010-09-21 17:15:46 -07:00
Avery Pennarun
dcba684766 If netstat -rn returns an error, make that non-fatal.
That only really stops --auto-nets from working; it's mostly harmless
otherwise.  And apparently some locked-down shared hosts don't let you get
the list of routes.
2010-09-04 11:29:11 -07:00
chocolateboy
ee74110cff add option to allow the remote python binary's name/path to be specified 2010-09-03 23:00:26 -07:00
Avery Pennarun
5bf8687ce3 Import latest options.py from bup-0.17.
This has new support for default values in square brackets, so let's use
that.
2010-09-03 23:00:26 -07:00
Avery Pennarun
6bdb9517fd README: fix some out-of-date system requirements stuff.
Reported by Jason Axelson.
2010-07-25 00:16:09 -04:00
Avery Pennarun
f1b33dab29 Add a --exclude option for excluding subnets from routing.
Also, add 127.0.0.0/8 to the default list of excludes.  If you want to route
0/0, you almost certainly *don't* want to route localhost to the remote ssh
server's localhost!

Thanks to Edward for the suggestion.
2010-07-15 14:13:33 -04:00
Avery Pennarun
3a25f709e5 log(): don't abort if we fail to write to stderr.
Failing to write to the log sucks, but not as much as failing to clean up
just because stderr disappeared.  So let's catch any IOError exception from
log() and just ignore it.

This should fix a problem reported by Camille Moncelier, which is that
sshuttle firewall entries stick around if your tty dies strangely (eg. your
X server aborts for some reason).
2010-05-16 17:57:18 -04:00
Avery Pennarun
a8b3d69856 ssh.py: try harder to find required *.py files.
Search the entire python sys.path, not just the directory that argv[0] is
in.  That way if you symlink the sshuttle binary into (for example) ~/bin,
it'll be able to work correctly.
2010-05-12 13:53:14 -04:00
Avery Pennarun
2d4f6a4308 client: add a debug1() message for connecting/connected.
If the server is going to delay us, we'd at least like to know that.
2010-05-11 19:04:44 -04:00
Avery Pennarun
d435ed837d Created a googlegroups.com mailing list for sshuttle. 2010-05-11 15:30:53 -04:00
Avery Pennarun
2d77403a0b Don't use try/except/finally so that python 2.4 works.
Use try/(try/except)/finally instead.  There was only once case of this.

Thanks to Wayne Scott and nisc for pointing this out.
2010-05-10 13:58:52 -04:00
Avery Pennarun
77cf37e0fa firewall: preserve permissions on /etc/hosts
Pointed out by nisc on github.  If people use an unusual umask or have funny
permissions on /etc/hosts, sshuttle would screw it up.

We also use hardlinks to atomically backup the original /etc/hosts to
/etc/hosts.sbak the first time, rather than manually copying it.  Not sure
why I didn't think of that before.
2010-05-09 11:22:05 -04:00
Avery Pennarun
384d0e7c1d hostwatch: watch "netstat -n" for IP addresses.
The list of active sessions might tell us about some hostnames on the local
networks, which we can then add to our subnet list.
2010-05-08 16:14:36 -04:00
Avery Pennarun
5a4a2ab7f9 Oops, previous change to ipfw settings prevented cleanup from working. 2010-05-08 16:14:36 -04:00
Avery Pennarun
33efa5ac62 Added new --auto-hosts and --seed-hosts options to the client.
Now if you use --auto-hosts (-H), the client will ask the server to spawn a
hostwatcher to add names.  That, in turn, will send names back to the
server, which sends them back to the client, which sends them to the
firewall subprocess, which will write them to /etc/hosts.  Whew!

Only the firewall process can write to /etc/hosts, of course, because only
he's running as root.

Since the name discovery process is kind of slow, we cache the names in
~/.sshuttle.hosts on the remote server.

Right now, most of the names are discovered using nmblookup and smbclient,
as well as by reading the existing entries in /etc/hosts.  What would really
be nice would be to query active directory or mdns somehow... but I don't
really know how those work, so this is what you get for now :)  It's pretty
neat, at least.
2010-05-08 03:32:30 -04:00
Avery Pennarun
a2ea5ab455 Add 'sshuttle --hostwatch' subcommand.
This tries to discover local hostnames and prints them to stdout.  Will be
used by the server for auto-hostname tracking.
2010-05-08 03:00:05 -04:00
Avery Pennarun
680941cb0c BSD: "ipfw add %d accept ip from any to any established"
With this rule, we don't interfere with already-established (or incoming)
connections to routes that we're about to take over.  This is what
happens by default in Linux/iptables.
2010-05-07 20:07:41 -04:00
Avery Pennarun
7043195043 Add -N (--auto-nets) option for auto-discovering subnets.
Now if you do

	./sshuttle -Nr username@myservername

It'll automatically route the "local" subnets (ie., stuff in the routing
table) from myservername.  This is (hopefully a reasonable default setting
for most people.
2010-05-07 20:02:04 -04:00
Avery Pennarun
77935bd110 ssnet: EHOSTUNREACH and ENETUNREACH are non-fatal errors.
Reported by Wayne Scott.
2010-05-07 12:30:03 -04:00
Avery Pennarun
8fe3592be3 Don't require the remote server to have sshuttle installed.
Instead, grab our source code, send it over the link, and have python eval
it and then start the server.py main() function.

Strangely, there's now *less* horrible stuff in ssh.py, because we no longer
have to munge around with the PATH environment variable.  And this
significantly reduces the setup required to get sshuttle going.

Based on a suggestion from Wayne Scott.
2010-05-04 23:42:36 -04:00
Avery Pennarun
ba19d9c72d Rename iptables->firewall.
Since we "almost" support ipfw on MacOS (which I guess might mean FreeBSD
too), the name should be a bit more generic.
2010-05-04 22:06:27 -04:00
Avery Pennarun
096bbcc576 Client "almost" works on MacOS and maybe FreeBSD.
Basic forwarding now works on MacOS, assuming you set up ipfw correctly
(ha ha).  I wasted a few hours today trying to figure this out, and I'm *so
very close*, but unfortunately it just didn't work.  Think you can figure it
out?

Related changes:
- don't die if iptables is unavailable
- BSD uses getsockname() instead of SO_ORIGINAL_DST
- non-blocking connect() returns EISCONN once it's connected
- you can't setsockopt IP_TTL more than once
2010-05-04 22:06:22 -04:00
Avery Pennarun
7bd0efd57b Oops, broke --noserver mode at some point. 2010-05-04 18:40:21 -04:00
Avery Pennarun
8173925bcd ssh.py: allow hostnames of the form hostname:port
Feature requested by Wayne Scott and Ed Maste.
2010-05-04 13:08:38 -04:00
Avery Pennarun
0cdd72c830 README: clarify that the server doesn't need Linux or iptables. 2010-05-03 16:35:35 -04:00
Avery Pennarun
403a088e07 README: add information about which iptables modules are needed.
As requested by a user.
2010-05-03 13:08:26 -04:00
Avery Pennarun
4a93d3362d README: fix some formatting for easier text-mode readability.
It looked okay in markdown, but some of the text lines were a bit too long.
2010-05-03 13:07:30 -04:00
Avery Pennarun
33a73056ee README: update to use real markdown-style headings.
Oops, got those mixed up with some random other markup format.
2010-05-02 21:46:51 -04:00
Avery Pennarun
4a462258f5 ssh.py: support finding sshuttle in "$HOME/.../sshuttle"
If you ran sshuttle from /home/apenwarr/sshuttle/sshuttle, we would
automatically add /home/apenwarr/sshuttle to the PATH before trying to
execute sshuttle on the remote machine.  That way, if you install it in the
same place on two computers, the client would still be able to start the
server.

Someone reported, though, that if they installed the client in
/home/apenwarr/sshuttle/shuttle, and the server in /root/sshuttle/sshuttle,
then used "-r root@servername", it wasn't able to find the program.

Similar problems would happen if you're apenwarr at home and averyp at work.

So what we now do is add *two* directories to the PATH:
/home/apenwarr/sshuttle and $HOME/sshuttle, where $HOME is the value of
$HOME on the *server*, not the client.  So it'll find it in either place.
2010-05-02 21:24:31 -04:00
Avery Pennarun
a5fc93c841 iptables: if client dies before sending GO, just quit.
If the server was having trouble starting, we would print a lot of
unnecessary stuff from iptables.  We shouldn't even have bothered *starting*
iptables if the server was dead anyway.
2010-05-02 21:06:31 -04:00
Avery Pennarun
ea6bb5c255 iptables: die quietly if parent process dies.
If we can't communicate with the parent process, he's probably died
unexpectedly; just shut down and don't bother people about it.
2010-05-02 21:02:09 -04:00
Avery Pennarun
2c2bea80bc iptables: try launching with sudo, then su, then directly.
Previous versions depended on having 'sudo' in your PATH.  Now that we can
feel safe that --iptables will clean up properly when you exit, and it
doesn't need to authenticate twice, the advantages of sudo aren't strictly
needed.  Good old 'su' is a reasonable fallback - and everybody has it,
which is nice.

Unfortunately su doesn't let you redirect stdin, so I had to play a stupid
fd trick to make it work.
2010-05-02 20:54:10 -04:00
Avery Pennarun
7d674e9e37 ssnet: throw a nicer-looking Fatal when the mux connection dies.
When it happens, it's probably because the client died and the server hasn't
noticed yet.
2010-05-02 20:53:29 -04:00
Avery Pennarun
a21e8c7a3c iptables: more resilient startup/cleanup.
Now the sudo iptables subprocess persists for the entire life of sshuttle.
The benefits of this are:

- no need to authenticate again at shutdown (failure of which could cause us
  to not clean up iptables)

- if the main process dies unexpectedly, iptables still gets cleaned up

- the password prompt can happen *before* starting the ssh/server process,
  which means it'll stand out and the password prompt won't be overwritten.
2010-05-02 19:29:03 -04:00
Avery Pennarun
ca14231aae Whoops, we were spinning in the server when the mux outbuf was full.
Once again, the buffering gets mixed up with the selecting.  Seems to be the
story of my life.
2010-05-02 06:17:43 -04:00
Avery Pennarun
6c2dc54b9e More latency fixes: use a PING/PONG pair to limit queue length.
It seems ssh is kind of stupid and uses a really big SO_SNDBUF (hundreds of
kbytes).  Thus, we can't depend on the socket's output buffer to limit our
latency down to something reasonable.  Instead, limit the amount of data we
can send in a single round trip.
2010-05-02 05:39:17 -04:00
Avery Pennarun
5d1390927d Don't overfill the mux's output buffer.
Otherwise a single busy stream can ruin it for everybody.
2010-05-02 05:06:51 -04:00
Avery Pennarun
da06286427 ssnet: when a connection error occurs, stop trying to connect. 2010-05-02 03:52:46 -04:00