Commit Graph

950 Commits

Author SHA1 Message Date
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
Avery Pennarun
616d0680d1 Add a README file based on my blog entry. 2010-05-02 03:42:59 -04:00
Avery Pennarun
9b23fd2c01 Do non-blocking connect().
This way we don't freeze the entire proxy when someone tries to connect to a
nonexistent IP address (oops).
2010-05-02 02:43:10 -04:00
Avery Pennarun
81c89ce9be Don't bother with a backtrace when we produce certain fatal errors.
We'll introduce a new "Fatal" exception for this purpose, and throw it when
we just want to print a user message and abort immediately.
2010-05-02 02:29:23 -04:00
Avery Pennarun
2dd328ada4 Add a -v (and -vv) flag and decrease default message verbosity. 2010-05-02 02:14:20 -04:00
Avery Pennarun
a244b325cb iptables: add a PREROUTING rule so we can proxy for other machines too.
If you run sshuttle on a router, it can handle vpn'ing for all the boxes on
your network.
2010-05-02 02:00:58 -04:00
Avery Pennarun
10069f99e2 Clean up SockWrapper.peername stuff.
Some fds don't have peernames, and sometimes the peername isn't very
helpful, so let's fill it in by hand when appropriate.
2010-05-02 01:52:05 -04:00
Avery Pennarun
ea12048418 ssh.py: use 'exec sshuttle' to get rid of the extra sh process. 2010-05-02 01:30:40 -04:00
Avery Pennarun
bfd506dcdc Improve some debugging information to find the weird data problem.
Turns out list.pop() removes the *last* item, not the first one.  Oops.  It
all works great for queues of only one item... :)
2010-05-02 01:25:09 -04:00
Avery Pennarun
915a96b0ec We now have a server that works... some of the time.
There still seem to be some weird timing and/or closing-related bugs, since
I can't load the eqldata project correctly unless I use --noserver.
2010-05-02 00:52:06 -04:00
Avery Pennarun
d435c41bdb stdin and stdout have different fds, so make SockWrapper take *two* socks.
We'll need this when we have a SockWrapper pointing at a Mux on a subprocess
pipe.
2010-05-01 23:32:30 -04:00
Avery Pennarun
5f0bfb5d9e Basic implementation of a multiplex protocol - client side only.
Currently the 'server' is just a pipe to run 'hd' (hexdump) for looking at
the client-side results.  Lame, but true.
2010-05-01 23:14:42 -04:00
Avery Pennarun
9f514d7a15 Smarter listenport selection.
Now if we aren't given an explicit port, we always initiate the port search
at 12300 and count upward looking for an available port.

Normally the kernel will assign us a random port, but that's not ideal
in our case because we'd like to use the same port numbers whenever
possible; that avoids piling up crap inside iptables in the (hopefully
unlikely) event that we die without cleaning up correctly.
2010-05-01 21:50:43 -04:00
Avery Pennarun
ad459e2918 iptables.py: completely replace ipt script.
Doing it in python instead of shell makes the code a bit less error prone.
Plus we can parse the iptables output and avoid triggering iptables errors.
2010-05-01 21:34:05 -04:00
Avery Pennarun
8278dcfb5d Parse options correctly; call ./ipt automatically. 2010-05-01 21:14:19 -04:00
Avery Pennarun
550048370e Move some code that'll be useful for the server into ssnet.py. 2010-05-01 20:48:11 -04:00
Avery Pennarun
3766d4d506 Don't "import * from socket". 2010-05-01 20:26:16 -04:00
Avery Pennarun
651b945299 Prevent loopbacks caused by telnetting to the transproxy port directly. 2010-05-01 20:20:54 -04:00
Avery Pennarun
dc643ccdc4 Clean up log messages slightly. 2010-05-01 20:14:17 -04:00
Avery Pennarun
72ed385b7f Really basic transproxying on localhost.
When regenerating outgoing connections, we set TTL=42 to prevent re-proxying
of requests.  That's a little hacky, but at least it avoids infinite loops.
2010-05-01 20:03:50 -04:00
Avery Pennarun
a818105dfe client now listens on a socket and gets SO_ORIGINAL_DST correctly. 2010-05-01 18:03:45 -04:00
Avery Pennarun
f84b87d7eb ipt: example script for how to set up an iptables transproxy. 2010-05-01 17:15:18 -04:00
Avery Pennarun
2f3c86e962 Initial commit.
Importing options.py, ssh.py, and LICENSE from the bup project.
2010-05-01 16:15:37 -04:00