0

I'm trying to set up a lightweight, custom filesync system for myself. I'd like the server to watch for changes to a given folder (with inotify -m), and when it detects any, to propagate them to clients connected to it.

My first thought was for the client computers to initiate an SSH tunnel (with ssh -R 2222:127.0.0.1:22), and then for the server to scp the files back to the clients whenever appropriate. But in order to automate the process, I'd need to set up SSH keys, which means that if the server were compromised without my knowledge, my computer would then be exposed in turn. I understand there are ways to mitigate these risks, like chroot jail or scponly, but it seems a little clumsy to open up a great big hole just to patch it back up 99% of the way.

It has occurred to me that the security issue arises from allowing the server to push to the client, rather than having the client pull from the server. So is there any other program or protocol that I can use to open a tunnel so that the client, hidden behind a dynamic IP and home router, can monitor a given port for a signal from the server without opening it up to manipulation the way an SSH tunnel would?

Ryan Lue
  • 1,076
  • 1
    I have not understand the whole questions regarding dynamic IP problems, etc. But couldn't your server signal by ssh using a non existing user like "mysecretinvaliduser". Then on the client you could watch the logfile for lines like "sshd[xxxx]: Invalid user mysecretinvaliduser from a.b.c.d" to invoke the actual pull action- – rudimeier Nov 13 '16 at 13:25
  • that's a super bright idea. I'll give it a shot! – Ryan Lue Nov 13 '16 at 14:07

1 Answers1

1

To begin with, note that any self made "signaling solution" may have non-obvious race conditions. Watch out that you don't miss a signal while processing the last signal!

One simple idea could be your server would append lines to a local file. So each inotify would cause:

date +"%s" >> /path/to/sync-signals.log

On your clients watch that file via ssh/tail but any pull action is invoked on the client.

ssh server "tail -n1 -f /path/to/sync-signals.log" | while read -r sigdate; do
    pull from server
done

Note this solution should never miss any "signal" but could cause a lot of unneeded "pulls" in case the server appends too many signals within a short time. So either the clients while loop should also compare the last "sigdate" with current date somehow. Or better the server would delay the signal somehow (Only append a line if nothing changed since a few seconds.)

rudimeier
  • 10,315
  • This is a really interesting idea! If I understand correctly, it means keeping a constant open connection to the SSH server. On the one hand, it seems less hacky than @rudimeier's solution – but on the other, it requires a bit more overhead (since I have to maintain a constant open connection to the SSH server, and run a cron job to respawn the daemon whenever that connection dies). Still, a clever use of SSH I had not considered. Thanks! – Ryan Lue Nov 14 '16 at 15:14
  • @RyanLue I've used a constant connection from client to server because your question says that your clients are behind firewall, dynamic IP, etc. – rudimeier Nov 16 '16 at 08:48
  • Oops, didn't realize the comment above was you all along! 2) True, I guess the parameters of the question were unclear. I meant to say that to my knowledge, reverse SSH tunneling allows the server to initiate a connection back to the client without any client-side network configuration, with a dynamic IP or firewall on the client side (is this wrong?), and continues to listen even when the internet connection is disrupted and then restored again – and is there anything that does all of that without giving the server executive control over the client? Your initial comment did the trick.
  • – Ryan Lue Nov 16 '16 at 09:47
  • @RyanLue No, an ssh revers tunnel works only as long the initiating client is still connected. – rudimeier Nov 16 '16 at 10:54
  • Not with the -N flag. – Ryan Lue Nov 17 '16 at 03:35
  • @RyanLue ssh -N only sends the ssh client into the background. It's still running as you see in the process list. – rudimeier Nov 17 '16 at 09:45
  • That's true, but I don't get a broken pipe error (or any other, for that matter) when I disable Wi-Fi, and can still log in server-to-client over the tunnel after re-enabling Wi-Fi, without relaunching the ssh -NR command. I tested it before submitting my last comment, using two separate machines (one to establish the tunnel, the other to SSH into the server and SSH again over the tunnel). Is it different on your machine? fwiw I'm on a Mac, though I can't imagine that makes a difference. – Ryan Lue Nov 17 '16 at 15:52