rfjakob / gocryptfs

Encrypted overlay filesystem written in Go
https://nuetzlich.net/gocryptfs/
MIT License
3.57k stars 253 forks source link

Add needed changes to use gocryptfs with singularity #590

Closed jmfernandez closed 3 years ago

jmfernandez commented 3 years ago

Singularity is a daemon-less container platform very popular in HPC environments. One of its many features is mounting FUSE filesystems before switching from host to container context, assuring these user space mounts are only visible inside the container (see https://sylabs.io/guides/3.7/user-guide/bind_paths_and_mounts.html#fuse-mounts).

Currently, gocryptfs is not compatible with singularity due two different reasons I'm going to explain in next scenario. Imagine next command line:

singularity run --fusemount "host:gocryptfs --params crypted_in_host uncrypted_in_container" docker://ubuntu

What singularity does under the hood is building a command line similar to this:

gocryptfs --params crypted_in_host /dev/fd/number -f

in order to fire the fuse mount command in foreground, and use as mountpoint the filehandler of the mountpoint directory within the container. This last feature is only supported by a subset of FUSE filesystems, like sshfs or cvmfs, which are usually linked against libfuse3.

Could you consider in your roadmap the support of these features, please?

rfjakob commented 3 years ago

Interesting, yes, I think this can be added.

What error do you get at the moment?

jmfernandez commented 3 years ago

Interesting, yes, I think this can be added.

What error do you get at the moment?

Well, the first complaint I'm getting from gocryptfs is that it does not understand the -f parameter and it is at the end (where it is unexpected):

singularity exec --fusemount "host:/home/jmfernandez/projects/WfExS-backend/.pyWEenv/bin/gocryptfs --passfile /tmp/passfile /home/jmfernandez/projects/WfExS-backend/wfexs-backend-test_WorkDir/91c1b346-4058-472f-a56a-aee73ea99418/.crypt /home/jmfernandez/projects/WfExS-backend/wfexs-backend-test_WorkDir/91c1b346-4058-472f-a56a-aee73ea99418/work/" docker://alpine:3.9 ls
Wrong number of arguments (have 3, want 2). You passed: /home/jmfernandez/projects/WfExS-backend/.pyWEenv/bin/gocryptfs /home/jmfernandez/projects/WfExS-backend/wfexs-backend-test_WorkDir/91c1b346-4058-472f-a56a-aee73ea99418/.crypt /dev/fd/3 -f
Usage: gocryptfs [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]
# And the result from ls is here

In order to circumvent this issue and try advancing, I created a bash wrapper which gets rid of -f, substituting it with -fg at the beginning of the command line.

#!/bin/bash

set -e

PROGDIR="$(dirname "$0")"
case "$PROGDIR" in
        /*)
                true
                ;;
        .)
                PROGDIR="$PWD"
                ;;
        *)
                PROGDIR="${PWD}/${PROGDIR}"
                ;;
esac

declare -a arr=( "$@" )
unset "arr[${#arr[@]}-1]"

exec "${PROGDIR}"/gocryptfs -fg "${arr[@]}"

Using the wrapper, the error message from gocryptfs is different:

singularity exec --fusemount "host:/home/jmfernandez/projects/WfExS-backend/.pyWEenv/bin/gocryptfs.bash --passfile /tmp/passfile /home/jmfernandez/projects/WfExS-backend/wfexs-backend-test_WorkDir/91c1b346-4058-472f-a56a-aee73ea99418/.crypt /home/jmfernandez/projects/WfExS-backend/wfexs-backend-test_WorkDir/91c1b346-4058-472f-a56a-aee73ea99418/work/" docker://alpine:3.9 ls
Invalid mountpoint: /dev/fd/3 is not a directory
# And the result from ls is here

Hope this helps!

rfjakob commented 3 years ago

References:

rfjakob commented 3 years ago

The problem with -f at the end should be fixed now via https://github.com/rfjakob/gocryptfs/commit/f53f52b0464f747a370618bcdf152fad585f1eb5 . This removes the need for the bash wrapper.

rfjakob commented 3 years ago

Want to give

gocryptfs.gz (gocryptfs v2.0.1-52-g9a8dfd9-dirty without_openssl; go-fuse v2.1.1-0.20210802120645-15a8bb029a4e => ../../hanwen/go-fuse; 2021-08-12 go1.16.5 linux/amd64)

a try?

Looks pretty good here:

$ singularity run --fusemount "host:gocryptfs --extpass echo --extpass test /tmp/a /mnt" docker://ubuntu
INFO:    Using cached SIF image
Reading password from extpass program "echo", arguments: ["test"]
Decrypting master key
bash: /home/jakob/.cargo/env: No such file or directory
bash: /home/jakob/.cargo/env: No such file or directory
bash: /home/jakob/.cargo/env: No such file or directory
Singularity> Filesystem mounted and ready.
Singularity> 
jmfernandez commented 3 years ago

Yes, you got it! It is working!!! 👏👏👏👏👏👏👏👏👏👏👏👏

rfjakob commented 3 years ago

Merged to master now.