Sans Big Tech Part 5: File server in the personal cloud

In Part 1 of this series, I explained why I have embarked on a long journey towards digital independence from Big Tech and Big Risk. Part 2 documented the first step of that journey – building a personal cloud, Part 3 discussed the security issues, and Part 4 described setting up an encrypted calendar in the personal cloud. This post is about a file server in the personal cloud as a partial replacement of Dropbox and Google Drive. It currently covers only the use of these services to sync between my own devices; I could extend it to include a couple of family members or close collaborators but not to a wider circle. This limited replacement is valuable because the privacy needs are greatest for material that I share only with the half a dozen devices (desktop, laptop, tablet, phone) that I use on a regular basis.

SFTP Server

The simplest solution to a file server is of course an FTP server, but for security reasons, several tweaks are necessary:

  • First, to minimize the threat surface, I want to run everything over the SSH port, and so I use an SFTP server instead of a plain FTP server.
  • Second, the file server will be accessed using unattended scripts and so the SSH key for this will have to be cached in the SSH-Agent or in a key ring. Therefore, the SFTP server will be accessed as a different highly restricted user that is allowed to run SFTP and nothing else. This is easily accomplished by creating a new group sftponly for this user and then adding the following lines to the end of /etc/ssh/sshd_config:
        Match Group sftponly
            ChrootDirectory %h
            ForceCommand internal-sftp
            AllowTcpForwarding no
            X11Forwarding no
            PasswordAuthentication no
  • Third, I want the SFTP server to host only encrypted files. So all uploads and downloads are done using scripts that encrypt and decrypt the files using a locally cached symmetric password. I currently use 7-Zip to archive, compress and encrypt the files using AES-256.

Encrypted Git Repo

SFTP servers are not suitable for frequently modified files that need to be under version control. For this I use git-remote-gcrypt. which is a git remote helper to push and pull from repositories encrypted with GnuPG, using a custom format. I basically followed Caloan’s simple instructions on how to set this up.

What is interesting about this setup is that git is not running on the server at all. The server runs rsync so that only the changed chunks are uploaded and downloaded. Only the clients run git, and when stuff has to be pushed to or pulled from the remote, git-remote-gcrypt steps in to handle this operation. Chunks are encrypted before uploading and decrypted after downloading using a key. The server does not even have the public key.

A known issue with git-remote-gcrypt is that every git push to the server effectively has --force. We must therefore pull before pushing. The relevant part of my shell script is shown below:

    git fetch $SERVER
    local=$(git rev-parse HEAD)  # hash of local head
    remote=$(git rev-parse $SERVER/master)  # hash of remote head
    base=$(git merge-base HEAD $SERVER/master)   # hash of common ancestor
    if [ $local == $remote ]; then
        action=none # local and remote are identical
    elif [ $local == $base ]; then
        action=pull  # remote is one or more commits ahead of local
    elif [ $remote == $base ]; then
        action=push  # local is one or more commits ahead of remote
        action=merge # local and remote have diverged from common ancestor

Once again, I want this user to run in a chroot jail. There are many good introductions on how to do this: for example, John Otieno. There are only two commands needed inside the jail: sh and rsync. We add a section in /etc/ssh/sshd_config to match this user and send it to the jail. It is also convenient to modify AuthorizedKeysFile directive in /etc/ssh/sshd_config to something like:

   AuthorizedKeysFile      /etc/ssh/authorized_keys/%u     .ssh/authorized_keys

and create authorized_keys in the new location.

Termux in Android Devices

The above setup is designed for easy access from laptops running Linux, but the greatest need for syncing content is to and from phones and tablets. Thankfully, termux solved this problem for me by allowing me to run a Linux-like environment on my phone. I have termux running in the background all the time, and from any Android App, I can share a file to termux. I have setup ~/bin/termux-file-editor to point to a script that uploads the file to the SFTP server.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s