Server-side authentication for qube-sync

I’ve got a folder on qube-sync which I’d like to make available to any other qube for mounting (in read only mode). I can follow the usual method to mount the drive using sshfs, which binds to socat on localhost on one end, and triggers an RPC service on qube-sync on the other end, which completes the tunnel by binding to sshd.

However, this method is inconvenient, because authentication must happen on the client qube, in the sshfs command. If it relies on a private ssh key, this key must either be copied to each new client qube, or retrieved for each use via ssh-split. If instead I simplify this by using password authentication with an empty password, I still need to add at least the username to the sshfs command. Either way, this is a security issue, because I would have to create a policy that allows all qubes to invoke the RPC call on qube-sync and access the sshd service running there.

I’d like instead to use a dedicated RPC service on qubes-sync that is associated only with the username which has access to that particular folder. The RPC script would consist of something like:
socat STDIO EXEC:"ssh -N usernam@localhost"

The -N flag tells ssh to not issue any command (such as invoking a shell); this is necessary if we want to use the connection only for sftp (the protocol used by sshfs).

On the client qubes, I would have a background socat instance like this:
socat TCP-LISTEN:840 EXEC:"qrexec-client-vm qube-sync user.rpc-call"

So now we have a tunnel from the client qube on port 840, to qube-sync, where there’s a ssh connection authenticated with the relevant user for the folder we want to mount. But now how can I get sshfs to use this? I’ve tried:

sshfs -p 840 localhost:/ ~/mount

And it seems to be starting up fine, however it hangs before connecting fully. Specifically, sshfs hangs at this:
debug1: Local version string SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u6

It doesn’t fail or crash, but this is an incomplete connection. If I try to run ls ~/mount, it just hangs.

Any suggestions?

Yes… maybe not very helpful… but a thorough read of the sshfs man page may be required! (the old RTFM acronym).

In particular, look for the option “-o directport=PORT” and/or “-o slave”.
This is because you establish the SSH tunnel/connection outside of sshfs, so sshfs should not try to start its own instance of ssh.

-o slave isn’t a flag on my sshfs command. The closest one seems to be -o passive, but I’m not sure if it’s relevant in this scenario.

Regarding -o directport, as I understand it bypasses ssh altogether and expects to find an sftp server on the other end. I wasn’t sure if ForceCommand internal-sftp in /etc/ssh/sshd_config would already address this, so I adjusted user.rpc-call to just run sftp:
socat STDIO EXEC:"sftp username@localhost"

But I’m getting a similar behavior as before. sshfs hangs and ls ~/mount hangs too.

However, at this point I’m no longer sure why it’s not working, because I’m also getting the same broken behavior even when testing it inside the same domain, i.e:
socat TCP-LISTEN:841,fork EXEC:"sftp user@localhost"
sshfs -o directport=841 localhost: ~/mount

I think that was supposed to be working, but it doesn’t.

It’s possibly related to the fact that I have the ForceCommand internal-sftp instruction in /etc/ssh/sshd_config and/or the fact that the login shell of user is /usr/sbin/nologin. These settings are leftovers from the original qube-sync configuration and they might be interfering.

I’m a bit tired of troubleshooting this, so I’m taking a break. Also, I guess this is now more of a Linux question, not a Qubes question.

1 Like