Securing access to a REST server by using a reverse tunnel

Interesting! Thanks for the tipp. I wasn’t aware of that. As far as I can tell the commands do not end up in a shell history though - at least not on my systems. That would indeed be counter productive :sweat_smile:

One alternative is storing the password in a file on the host-to-be-backed-up. That also works but there’s always some form of attack surface. Are there other methods that would work?

The main features of this approach to me are that the backup server is not exposed nor even “mentioned” on the backupee and in the case of multiple machines to be backed up, the backup server can work through them one by one centrally managed with a script.

You could pass the environment variable directly with ssh, though this requires configuring both the server (AcceptEnv) and the client (SendEnv).

I agree, there are definitely benefits to this approach. It’s worth noting that the backup server is still somewhat exposed, but only the REST server and only when a backup is actually running.

I wonder if Restic can connect to the REST server over a Unix domain socket rather than TCP? If so, you could have the reverse tunnel bound to a Unix domain socket such that only the user actually running the backup can even connect to the REST server at all.

This I have never heard of but will research. Thanks for the tipp!

Yes of course. But taking that lane is arguably complicated and probably reserved for the likes of APTs. Nothing I can do against that anyway.

I’m afraid I don’t understand. @kburchfiel if you don’t mind our hijacking your thread I’d like to ask @cdhowie for some more details? I guess we’re heading towards times where we can’t really afford to take security lightly.

I split this to a new topic to address your topic hijacking concerns. :slightly_smiling_face:

It looks like using a Unix domain socket is supported!

1 Like

Nice, thanks!

So now we can forward the local socket like so:

ssh -R /tmp/remote_socket:/tmp/local_socket user@remote_host

But how do I configure rest-server to use a socket? And, more importantly: what do we gain by using the forwarded socket?

Based on the Github issue, the syntax would be something like -r rest:unix://tmp/remote_socket.

What you gain is the ability to control permissions on the socket so that e.g. only root (or whichever user runs the backup) can access it. Compare this to TCP ports, where any process on the system could connect to it. This lowers your attack surface by not letting your application services connect to the REST server at all.

To control access to the socket, the simplest approach would probably be creating a directory that only the backup user has access to. For example, if running backups as root, you could do something like this on the machine that will take the backup:

# mkdir /var/restic-backup-server
# chmod 700 /var/restic-backup-server

Then use ssh -R /var/restic-backup-server/socket:.... Because the directory containing it can only be traversed by root, the socket inside can only be accessed by root, too!

Note that you can forward a remote socket to a local TCP endpoint as well, so you could do ssh -R /var/restic-backup-server/socket:127.0.0.1:3000 for example, if you are running the REST server locally on port 3000. (But you could also potentially use a Unix socket on the local side as well; I forget if the REST server lets you bind to one.)

1 Like

Thank you very much for your detailed answer! I will indeed try this out!

1 Like