Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add needed changes to use gocryptfs with singularity #590

Closed
jmfernandez opened this issue Aug 3, 2021 · 7 comments
Closed

Add needed changes to use gocryptfs with singularity #590

jmfernandez opened this issue Aug 3, 2021 · 7 comments

Comments

@jmfernandez
Copy link

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
Copy link
Owner

rfjakob commented Aug 4, 2021

Interesting, yes, I think this can be added.

What error do you get at the moment?

@jmfernandez
Copy link
Author

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
Copy link
Owner

rfjakob commented Aug 4, 2021

References:

rfjakob added a commit that referenced this issue Aug 10, 2021
Need support for flags at any position for
#590
@rfjakob
Copy link
Owner

rfjakob commented Aug 10, 2021

The problem with -f at the end should be fixed now via f53f52b . This removes the need for the bash wrapper.

rfjakob added a commit that referenced this issue Aug 12, 2021
@rfjakob
Copy link
Owner

rfjakob commented Aug 12, 2021

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> 

rfjakob added a commit to rfjakob/go-fuse that referenced this issue Aug 13, 2021
libfuse introduced [1] a special `/dev/fd/N` syntax for the mountpoint:
It means that a privileged parent process:

 * Opened /dev/fuse
 * Called mount() on a real mountpoint directory
 * Inherited the fd to /dev/fuse to us
 * Informs us about the fd number via /dev/fd/N

This functionality is used to allow FUSE mounts inside containers
that have neither root permissions nor suid binaries [2], and
for the --drop_privileges flag of mount.fuse3 [4]

Tested with singularity and gocryptfs and actually works [3].

Now with doc comment for NewServer.

[1] libfuse/libfuse@64e1107
[2] rfjakob/gocryptfs#590
[3]:
 $ 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.
[4] man mount.fuse3

Change-Id: Ibcc2464b0ef1e3d236207981b487fd9a7d94c910
@jmfernandez
Copy link
Author

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

hanwen pushed a commit to hanwen/go-fuse that referenced this issue Aug 25, 2021
libfuse introduced [1] a special `/dev/fd/N` syntax for the mountpoint:
It means that a privileged parent process:

 * Opened /dev/fuse
 * Called mount() on a real mountpoint directory
 * Inherited the fd to /dev/fuse to us
 * Informs us about the fd number via /dev/fd/N

This functionality is used to allow FUSE mounts inside containers
that have neither root permissions nor suid binaries [2], and
for the --drop_privileges flag of mount.fuse3 [4]

Tested with singularity and gocryptfs and actually works [3].

v2: Added doccomment for NewServer.
v3: Added specific error message on Server.Unmount().
v4: Moved mount details to package comment

[1] libfuse/libfuse@64e1107
[2] rfjakob/gocryptfs#590
[3] $ 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.
[4] man mount.fuse3

Change-Id: Ibcc2464b0ef1e3d236207981b487fd9a7d94c910
@rfjakob
Copy link
Owner

rfjakob commented Aug 25, 2021

Merged to master now.

jiefenghuang pushed a commit to juicedata/go-fuse that referenced this issue Aug 6, 2024
libfuse introduced [1] a special `/dev/fd/N` syntax for the mountpoint:
It means that a privileged parent process:

 * Opened /dev/fuse
 * Called mount() on a real mountpoint directory
 * Inherited the fd to /dev/fuse to us
 * Informs us about the fd number via /dev/fd/N

This functionality is used to allow FUSE mounts inside containers
that have neither root permissions nor suid binaries [2], and
for the --drop_privileges flag of mount.fuse3 [4]

Tested with singularity and gocryptfs and actually works [3].

v2: Added doccomment for NewServer.
v3: Added specific error message on Server.Unmount().
v4: Moved mount details to package comment

[1] libfuse/libfuse@64e1107
[2] rfjakob/gocryptfs#590
[3] $ 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.
[4] man mount.fuse3

Change-Id: Ibcc2464b0ef1e3d236207981b487fd9a7d94c910
jiefenghuang pushed a commit to juicedata/go-fuse that referenced this issue Aug 6, 2024
libfuse introduced [1] a special `/dev/fd/N` syntax for the mountpoint:
It means that a privileged parent process:

 * Opened /dev/fuse
 * Called mount() on a real mountpoint directory
 * Inherited the fd to /dev/fuse to us
 * Informs us about the fd number via /dev/fd/N

This functionality is used to allow FUSE mounts inside containers
that have neither root permissions nor suid binaries [2], and
for the --drop_privileges flag of mount.fuse3 [4]

Tested with singularity and gocryptfs and actually works [3].

v2: Added doccomment for NewServer.
v3: Added specific error message on Server.Unmount().
v4: Moved mount details to package comment

[1] libfuse/libfuse@64e1107
[2] rfjakob/gocryptfs#590
[3] $ 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.
[4] man mount.fuse3

Change-Id: Ibcc2464b0ef1e3d236207981b487fd9a7d94c910
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants