Writing

Atom feed icon Software, technology, sysadmin war stories, and more.

Monday, October 21, 2024

Janky remote backups without root on the far end

Sometimes I do dumb things to solve my own problems. This is one of those times. In this case, I wanted something that would give me access to a block device on a physically distant machine for backup purposes. I didn't want to do anything particularly fancy on the distant box, so rootly powers are out of the question. I just need disk space, a bit of bandwidth, and some CPU time every now and then.

Here's how it works. Perhaps you have heard of "nbd" if you're in the Linux world. It lets you load a kernel module on the client machine and then it'll turn a network type connection into a block device. That is in fact right in the name: "nbd" equals "network block device". Nice, right?

I wanted this, but didn't want it making a "bare" connection to the far end. By default, it's just a plain old TCP session to the other side. While you can rig it to use TLS, there are a bunch of problems with this. It means you need to leave a daemon running on the far end, and again, if you aren't root out there, that can be troublesome. It means the distant host ends up stuck with a listening port, and that's not always nice. It also forces you to deal with getting the whole certificate thing hooked up. Hope you're good at wrangling OpenSSL.

This seemed wholly unnecessary to me. I already have ssh access to the machines in question, so that right there will give me a relatively solid transport. I just needed to convince the nbd stuff to use it.

Now, let you stop you right here: if you're saying "SOCKS proxy" and/or "port forwarding", you have missed the part where I'd rather not have a persistent daemon on the far end that's listening on some port, *even if* it's "merely bound to loopback". That's still something running as me that presents an unnecessary orifice to unwelcome visitors. No thank you.

There's another way the nbd client can work: it will totally connect to a stream-style Unix domain socket. As long as whatever is on the other end of that socket speaks the right language, it doesn't matter where it is or what it is. Thus, I needed to make a Unix domain socket reach over the network to the other end of a ssh connection.

Here's what happened: I wrote some grungy plumbing stuff (my specialty) that sets up a Unix domain socket on my local machine. It does it in a directory where only I can access it, and it waits for a connection. Once it gets one, it forks, and the child fires up a ssh to the far end to invoke the nbd server (a trivial userspace thing I can leave in my personal bin directory).

Meanwhile, the parent process of the client sticks around and fires up a pair of threads to do a bucket-brigade thing. It takes any data from the Unix domain socket connection it just received and flings it at the ssh connection. The other one does the reverse.

This keeps going until one of the fds shows up as disconnected, at which point it shuts down everything and exits politely.

The other part of this is a currently a bit of *local* rootly scripting madness which points the NBD client at that socket, then does the crypto gunk to attach it, then fscks it, mounts it, and fires up rsync. Then after it's done, it undoes everything and declares victory.

It's not meant to be fast, and it's definitely not meant to be beautiful, but it does work. My only footprint on the far end is a giant blob of a file that is entirely meaningless to anyone without a suitable key. The data is only ever seen in a usable form here on the client machine which already has access to the original data by definition. I didn't have to install anything special on the far end, I don't have to run any daemons, and I didn't need root out there.

It's the type of thing that you can stand up and just let it run every now and then, kind of like Time Machine on a Mac. You hope you never need to use it, but it's there if you really get stuck somehow.

So, yeah, when my part of CA "falls into the ocean", I will bob up to the surface, swim to shore, and then walk to where my offsites are and restore from backups. You know, that whole thing.

Just basic sysadmin stuff. Nothing fancy.