Use qubes-sync with multiple clients and one server

Original forum link
https://forum.qubes-os.org/t/19780
Original poster
Marisoc
Editors
Marisoc
Created at
2023-07-11 14:47:29
Last wiki edit
2023-07-13 04:41:10
Revisions
3 revisions
Posts count
2
Likes count
3

This guide uses unman's qubes-sync to sync directories from multiple qubes to a single qube while using chroots to prevent client qubes from accessing other qubes' files.

The goal of this is to allow for easier backup from a single qube, or to use software like syncthing to keep multiple devices in sync without requiring network access in client qubes.

Qube creation

Create an appvm to be the server qube. In the instructions replace $SERVERNAME with the name of this qube.

Create an appvm to be the client qube. In the instructions replace $CLIENTNAME with the name of this qube.

Template setup

These instructions should be done in the template qube (i.e. debian-11).

Install dependencies:

sudo apt install openssh-server sshfs

Create /lib/systemd/system/qubes-ssh-forwarder.socket (note that ConditionPathExists is in unman's source, but is removed here):

[Unit]
Description=Forward connection to ssh over Qubes RPC

[Socket]
ListenStream=127.0.0.1:840
BindToDevice=lo
Accept=true

[Install]
WantedBy=multi-user.target

Create /lib/systemd/system/qubes-ssh-forwarder@.service:

[Unit]
Description=Forward connection to ssh over Qubes RPC

[Service]
ExecStart=/usr/bin/qrexec-client-vm '' qubes.ssh
StandardInput=socket
StandardOutput=inherit

Create /etc/qubes-rpc/qubes.ssh:

#!/bin/sh
exec socat STDIO TCP:localhost:22

Then mark it as executable:

sudo chmod +x /etc/qubes-rpc/qubes.ssh

Shut down the template and (re)start the server and client qubes.

Set up directories

Run this on $SERVERNAME:

sudo mkdir -p /rw/syncdir/authorized_keys

To make sure that client qubes aren't able to access files outside of their directories, it's important to configure chroot:

Create a new file /rw/syncdir/sshd_config-addition on $SERVERNAME:

AuthorizedKeysFile /rw/syncdir/authorized_keys/%u

Match Group sftponly
    ChrootDirectory %h
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    PasswordAuthentication no

Append this to /rw/config/rc.local on $SERVERNAME:

groupadd sftponly
cat /rw/syncdir/sshd_config-addition | sudo tee -a /etc/ssh/sshd_config

Restart $SERVERNAME

Add clients

Run this in $CLIENTNAME

# Run this command, accept defaults for no password
ssh-keygen
# Copy the generated key to the server qube
qvm-copy /home/user/.ssh/id_rsa.pub

Run this in $SERVERNAME:

# Create user for qube
sudo useradd -g sftponly -s /usr/sbin/nologin -d /rw/syncdir/$CLIENTNAME sync-$CLIENTNAME
# Set up directory for user to chroot to
sudo mkdir /rw/syncdir/$CLIENTNAME
# Set up writable directory for user
sudo mkdir /rw/syncdir/$CLIENTNAME/writable
sudo chown sync-$CLIENTNAME /rw/syncdir/$CLIENTNAME/writable
# Set up ssh keys for user
sudo mv /home/user/QubesIncoming/$CLIENTNAME/id_rsa.pub /rw/syncdir/authorized_keys/sync-$CLIENTNAME
sudo chown root:root /rw/syncdir/authorized_keys/sync-$CLIENTNAME
sudo chmod 644 /rw/syncdir/authorized_keys/sync-$CLIENTNAME
systemctl restart sshd

Append this to /rw/config/rc.local in $SERVERNAME:

useradd -g sftponly -s /usr/sbin/nologin -d /rw/syncdir/$CLIENTNAME sync-$CLIENTNAME

Append this to /etc/qubes/policy.d/30-user.policy in dom0:

qubes.ssh    *    $CLIENTNAME    @default    allow    target=$SERVERNAME

Run this in $CLIENTNAME

mkdir /home/user/sync

Connect client to server

Run in $SERVERNAME:

systemctl start sshd

Run in $CLIENTNAME

systemctl start qubes-ssh-forwarder.socket
sshfs -p 840 sync-$CLIENTNAME@localhost:/writable /home/user/sync

Start qubes-sync automatically

Append this to /rw/config/rc.local on $SERVERNAME. This must come after all useradd commands:

bash -c "sleep 10 && systemctl restart sshd"

Append this to /rw/config/rc.local on $CLIENTNAME:

systemctl start qubes-ssh-forwarder.socket
sudo -H -u user -i sshfs -p 840 sync-$CLIENTNAME@localhost:/writable /home/user/sync

Notes

Sources: - https://github.com/unman/qubes-sync - https://wiki.archlinux.org/title/SFTP_chroot


Is there anything that's unclear or should be changed? Feedback is welcome!