* daemon:
daemonization: make sure the firewall subproc sends to syslog too.
Rearrange daemonization/syslog stuff and make it more resilient.
run in background (daemon) and option
Rename --background to -D/--daemon, to match other programs (like smbd).
You can now have --syslog even without --daemon.
Avoid using atexit(); try/finally is better.
Don't just close stderr; we'll end up eating error output from ssh!
Instead, redirect stderr to a 'logger' subprocess that will send to syslog.
Delay redirecting stderr until after we know we're daemonizing, so handy
error messages can go to stderr instead of syslog.
Make pidfile stuff more resilient: support already-existing files, files
with strict permissions, outdated files containing an already-dead pid. Add
a --pidfile option to let you specify the pidfile path.
chdir("/") while daemonizing, so that the filesystem containing $PWD can
later be unmounted without killing the daemon.
fw.done() can't wait on the firewall subprocess on exit when daemonized; we
no longer are the parent of that process.
This avoids any possible problem caused by other people on your network
using you as a proxy. If you want to allow this, you can force it back to
the old way using the --listen option.
Thanks to 'tass' on github for reporting portscans that revealed this
potential security problem.
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.
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.
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.
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.
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.
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.