2021-10-03

Personal File Hosting Service with SFTP on OpenBSD

openbsd   index

I’ve used Nextcloud for file hosting, calendar and contacts services, since its very first release. However, I recently had to downgrade my large servers, and found myself lacking resources for running a hungry service like that.

Goal

To have an “offsite” backup of my documents, and to be able to view them on a phone. The documents are read-only on the server, and the synchronization is one way, local to server.

Create a dedicated user for file hosting

Since sftp implies ssh access, we need to restrict things as much as possible.

Thankfully, OpenSSH has an easy way of achieving this, by forcing an sftp only mode on a user, and confining it to a directory.

Which means we need a dedicated user on the server for the file store.

useradd -m syncuser

Restrict SFTP

Create a new root directory:

mkdir /chroot

Add to /etc/sshd_config the following:

Match User syncuser
    ForceCommand internal-sftp
    ChrootDirectory /chroot

This will disable ssh login for syncuser, and restrict sftp to the directory /chroot.

Mount file storage directory

We can keep our files directly under /chroot, however it’s likely we don’t have that much space in the root partition, especially if we followed the standard OpenBSD installation.

To solve this, we can create a sync directory under our user’s home, and mount it to /chroot with nfs. As an extra, mounting it with -ro will make the share, and thus our sftp server, read-only.

mkdir /home/syncuser/sync
mkdir /chroot/sync

rcctl enable portmap nfsd mountd
echo "/home/syncuser/sync -network=127.0.0.1 -mask=255.255.255.255 -ro" \
    > /etc/exports
rcctl start portmap nfsd mountd

mount localhost:/home/syncuser/sync/ /chroot/sync

Sync files

Synchronization of our files from the local to the server can be done with rsync. However, since we don’t have regular ssh to syncuser, we need a workaround.

The solution is to send the files using another user (for example privuser) with regular ssh access, while running rsync on the server as syncuser through rsync-path:

rsync --rsync-path 'doas -u syncuser /usr/local/bin/rsync' \
      -ar --delete \
      /home/localuser/sync/ \
      <privuser>@<server>:/home/syncuser/sync/

The above requires a rule in doas:

permit nopass privuser as syncuser cmd /usr/local/bin/rsync

As mentioned before, this is just a one-way sync. For two-way sync, the tool unison may do the job.

View on phone

To view and open the files on a smartphone, we need an application that can access sftp. The Android file manager that I use, “Material Files”, already has this capability.

Conclusion

The gain from all this, is that we can now access the sftp server through the restricted syncuser, without needing access to privuser on the phone.

Sources