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

[Question] Encrypted backups without reverse mode possible? #848

Closed
anrxc opened this issue May 21, 2024 · 4 comments
Closed

[Question] Encrypted backups without reverse mode possible? #848

anrxc opened this issue May 21, 2024 · 4 comments

Comments

@anrxc
Copy link

anrxc commented May 21, 2024

Every gocryptfs article about backup purposes is talking about reverse mode, as if there's no other option.

Let's say a user has /home/username.cipherdir/ initialized (with standard options, no deterministic, no AES-SIV) and mounted at /home/username/

Exposing /home/username/ in reverse mode (deterministic, AES-SIV) in /tmp/foobar/ to create backups of your home directory seems like twice the effort.

Would it be possible to rsync copy /home/username.cipherdir/ to your backups server directly, ignoring reverse mode entirely?

If the answer is yes. Would it be possible to rsync copy /home/username.cipherdir/ while it's actively mounted at /home/username/ so you don't have to unmount your $HOME every time a backup needs to run?

P.S. This is how eCryptfs used to work, it allowed taking incremental rsync snapshots of the so called "lower" encrypted directory without special deterministic modes or unmounting your $HOME.

Thank you.

@anrxc
Copy link
Author

anrxc commented May 22, 2024

I performed the following test:

System 1 source:

gocryptfs -init -plaintextnames cipher
gocryptfs -allow_other -exec -rw cipher plain 
cp -arp bunch_of_data/  plain/
rsync -avrog ./cipher/   /mnt/nfs-backup-cluster/home/.gocryptfs/user/cipher/ 

System 2 backups system:

cd /nfs/home/.gocryptfs/user/
mkdir plain
gocryptfs -allow_other -exec -rw cipher plain 

The data was readable.

If this is in any way discouraged :

  1. copying files while mount is active
  2. not using reverse deterministic mode

Please let me know. Thank you.

@rfjakob
Copy link
Owner

rfjakob commented May 28, 2024

Would it be possible to rsync copy /home/username.cipherdir/ to your backups server directly, ignoring reverse mode entirely?

Yes!

If the answer is yes. Would it be possible to rsync copy /home/username.cipherdir/ while it's actively mounted at /home/username/ so you don't have to unmount your $HOME every time a backup needs to run?

Yes!

@rfjakob
Copy link
Owner

rfjakob commented May 28, 2024

Reverse mode is for when the data is not already encrypted on disk.

@rfjakob rfjakob closed this as completed May 28, 2024
@anrxc
Copy link
Author

anrxc commented May 31, 2024

Yes!

Thank you very much.

Adding some extra information for future google searches and people that will lose eCryptfs kernel support in 2025.

eCryptfs used the kernel keyring, ecryptfs-add-passphrase would insert a passphrase into the keyring.

You can potentially use the gocryptfs -extpass feature to continue storing and retrieving your keys from the kernel keyring.

This is a quick proof of concept (Python could handle the passphrase insecurely in memory). But we can't depend on unmaintained ecryptfs-utils packages being available in the future. A safe golang or rust implementation would be nice to have:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# gocryptfs-add-passphrase - add a gocryptfs mount passphrase to the kernel keyring.
#
# Copyright (C) 2024 Adrian C. <anrxc_sysphere_org>

# Licensed under the MIT License:
#   https://opensource.org/license/mit

import sys
import ctypes
import keyutils
from getpass import getpass

# Only pass `bytes` to the keyutils API:
name = b'gocryptfs-home'
#value = b'foobarfoobarfoobarfoobarfoobarfoobar'
value = getpass("Passphrase: ").encode()

ring = keyutils.KEY_SPEC_USER_KEYRING

def zerome(varname):
    strlen = len(varname)
    offset = sys.getsizeof(varname) - strlen - 1
    ctypes.memset(id(varname) + offset, 0, strlen)
    del varname

keyutils.add_key(name, value, ring)
zerome(value)

# Example:
# $ gocryptfs-add-passphrase.py 
#   Passphrase: ************************************
#
# $ keyctl list @u
#   1 key in keyring:
#   462648848: --alswrv  1003  1003 user: gocryptfs-home
#
# $ keyctl search @u user gocryptfs-home
#   462648848
#
# $ keyctl print 462648848
#   foobarfoobarfoobarfoobarfoobarfoobar
#
# $ gocryptfs -extpass "keyctl" -extpass "print 462648848" -exec -rw /home/.gocryptfs/username/ /home/username/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants