L O A D I N G
View on GitHub

gocryptfs-standalone

Synchronizes a gocryptfs (plaintext names) encrypted directory with a decrypted copy without needing FUSE or admin rights.

Project Status

npmnpm downloads

buildbuild push package

check typeslinttestgocryptfs compatibilitystandalone executables

code coverage

deploy web documentationweb documentation

Use case

Work with a gocryptfs encrypted directory (for example synchronized via a cloud service like Google Drive) on machines where gocryptfs or a FUSE backend can not be installed (no admin rights). The tool runs as a standalone executable on Linux, macOS and Windows.

Only vaults created with gocryptfs -init -plaintextnames are supported (feature flags HKDF GCMIV128 PlaintextNames). Every other vault is refused so it never gets damaged.

Installation

Download the executable of your platform from the releases (linux, macos or windows, each for x64 and arm64), unpack it and run it, no installation or admin rights needed. SHA256SUMS lists the checksums of all archives.

The executables are not signed by a registered developer, so:

  • macOS blocks downloaded ones at first: remove the quarantine flag with xattr -d com.apple.quarantine gocryptfs-standalone-macos-* (or allow it under "System Settings → Privacy & Security").
  • Windows SmartScreen may warn on first start ("More info → Run anyway").
  • Linux executables need a glibc based distribution (not Alpine/musl).

With node (26 or newer) the package can be used directly as well: npx gocryptfs-standalone ….

To build the executable of the current platform yourself: yarn build:standalone (and yarn test:standalone to check it end to end).

Usage

gocryptfs-standalone init <vault> [--scryptn 16]
gocryptfs-standalone info <vault>
gocryptfs-standalone cat <vault> <path> > file
gocryptfs-standalone decrypt <vault> <target>
gocryptfs-standalone encrypt <source> <vault>
gocryptfs-standalone sync <plaintext> <vault> [--dry-run] [--trash-days 30]

decrypt, encrypt and sync accept --exclude <pattern> (repeatable).

The vault's configuration file is looked up as gocryptfs.conf and then as .gocryptfs.conf in the vault directory (init creates gocryptfs.conf). Every command accepts --config <path> to use a configuration file located elsewhere, like gocryptfs' -config option (for example to keep it out of the cloud). Both names are reserved in the vault root and never synchronized.

decrypt and encrypt work one way: existing files on the target side get overwritten, nothing gets deleted. Modification times, permissions and symbolic links are carried over. Vaults created with init can be mounted with gocryptfs (-init -plaintextnames compatible).

Synchronization

sync keeps a plaintext directory and a vault in sync in both directions. After each run the state of both sides is remembered (a json file in the user's configuration directory: %APPDATA%\gocryptfs-standalone on Windows, $XDG_CONFIG_HOME/gocryptfs-standalone or ~/.config/gocryptfs-standalone elsewhere). Compared to that state:

Plaintext directoryVaultResult
changed / newunchanged / missingencrypted into the vault
unchanged / missingchanged / newdecrypted into the plaintext directory
deletedunchangedvault version moved into the trash
unchangeddeletedplaintext version moved into the trash
changeddeletedencrypted again (a change beats a deletion)
changedchangednewer version wins, the older one is kept as name (conflict <host> <date>).ext on both sides

Without a state (first run) both sides get merged, files existing on both sides are compared by content, and nothing gets deleted. The trash lives next to the state (pairs/<id>/trash, vault files stay encrypted there) and gets purged after 30 days (--trash-days). Entries changing while being synchronized are skipped and retried next time, a lock prevents parallel runs of the same pair. --dry-run only shows what would happen.

Excludes

Excluded entries are left alone on both sides, as if they did not exist. Excluding something already synchronized never deletes it. Patterns follow gitignore conventions:

PatternMatches
.DS_Store, *.tmp, ~$*names at any depth
docs/*.pdf, docs/**/*.pdfpaths relative to the root
/buildonly in the root
cache/, node_modules/only directories (with all their content)

Supported globs: *, **, ?, [...] and {a,b}. Matching is case insensitive on macOS and Windows.

Configured pairs and background synchronization

Pairs of a plaintext directory and a vault can be configured once and then be synchronized by name, all at once or periodically in the background:

# Asks for the password, verifies it and stores it in the keychain.
gocryptfs-standalone pair add documents ~/Documents/private ~/GoogleDrive/vault --interval 10m
gocryptfs-standalone pair list
gocryptfs-standalone sync documents        # one pair
gocryptfs-standalone sync                  # all pairs
gocryptfs-standalone daemon                # all pairs on changes and in their intervals until stopped
gocryptfs-standalone service install       # start "daemon" after each log in
gocryptfs-standalone service status
gocryptfs-standalone service uninstall
gocryptfs-standalone pair remove documents

Everything lives in configuration.json inside the configuration directory and can be edited by hand as well:

{
    "defaults": {
        "excludes": [".DS_Store", "._*", ".~lock.*#", "Thumbs.db", "desktop.ini", "~$*"],
        "interval": "10m",
        "trashDays": 30,
        "watch": true
    },
    "pairs": {
        "documents": {
            "plaintext": "/home/me/Documents/private",
            "vault": "/home/me/GoogleDrive/vault",
            "interval": "5m",
            "excludes": ["*.tmp", "build/"],
            "trashDays": 7,
            "watch": false,
            "password": "keychain",
            "config": "/home/me/vault.conf"
        }
    }
}

A pair's excludes are added to the default ones. config is optional and only needed for a configuration file outside of the vault (pair add --config). Intervals take seconds, minutes or hours (30s, 10m, 2h, at least 10 seconds). Password sources:

SourceMeaning
"keychain" (default of pair add)operating system's credential store, see below
"prompt"asked interactively (once when the daemon starts)
"environment"environment variable GOCRYPTFS_PASSWORD
{"file": "<path>"}first line of the file (pair add --passfile)
{"command": "<command line>"}first line of the output (pair add --extpass)

Credential stores used without any native module or admin rights:

  • macOS: login keychain via security
  • Linux: Secret Service (GNOME Keyring, KWallet, …) via secret-tool (package libsecret-tools or similar)
  • Windows: DPAPI via PowerShell, the encrypted password is stored in credentials/<pair>.dpapi inside the configuration directory and can only be decrypted by the same user on the same machine

The daemon unlocks all vaults on start (so wrong passwords fail early), synchronizes every pair right away and afterwards in its interval. Runs never overlap and failures get retried in the next interval, a run blocked by a parallel sync of the same pair after 10 seconds. Only one daemon watches a pair at a time, another one stops right away (exit code 4). Pairs must not overlap: pair add, sync and daemon refuse configurations where a directory of one pair (plaintext or vault) is located inside one of another pair.

With "watch": true (default) the daemon additionally listens to file system events of both sides (FSEvents on macOS, inotify on Linux, change notifications on Windows) and synchronizes a pair 2 seconds after the last change, at the latest 30 seconds after the first one while changes keep coming. Changed entries still looking like after the last synchronization (e.g. written by it) do not trigger a run. Events only trigger a regular synchronization, so the interval stays as fallback for changes no event reports: cloud clients (e.g. files arriving in a Google Drive folder) and network or FUSE mounts often do not report everything. If watching fails (e.g. Linux' limit of inotify watches, fs.inotify.max_user_watches, is reached) the pair is synchronized in its interval only and watching is retried every 5 minutes. --no-watch disables watching for pair add or a single daemon run. service install registers it per user:

  • macOS: launchd agent ~/Library/LaunchAgents/com.tsickert.gocryptfs-standalone.plist, logging to daemon.log in the configuration directory
  • Linux: systemd user unit ~/.config/systemd/user/gocryptfs-standalone.service (log: journalctl --user -u gocryptfs-standalone, keep it running while logged out with loginctl enable-linger)
  • Windows: command file in the user's startup folder, starting the daemon minimized and logging to daemon.log in the configuration directory

Password of single commands

The password is taken from the first available source:

  1. --passfile <path> (first line of the file)
  2. --extpass <command> (first line of the command's output)
  3. Environment variable GOCRYPTFS_PASSWORD
  4. Interactive prompt

Alternatively --masterkey <hex> unlocks the vault with its master key. A given master key is checked against existing vault content before anything gets encrypted with it.

About this website

Provider ofhttps://tsickert.com/gocryptfs-standalone:
Torben Sickert
Waldstraße 29
791194 Gundelfingen i.Br.
Phone: +49 (0) 176 / 10 248 185
Email:
[email protected]
Website: https://tsickert.com
homedeDE: StartseitefrFR: Maison

Disclaimer

Liability for content

The content of our pages has been prepared with the utmost care. However, we cannot guarantee the accuracy, completeness or timeliness of the content. As a service provider, we are responsible for our own content on these pages under general law. However, we are not obliged to monitor transmitted or stored third-party information or investigate circumstances that indicate illegal activity. Obligations to remove or block the use of information under general law remain unaffected. Liability in this respect is only possible from the time we become aware of a specific infringement. Upon becoming aware of any such legal violations, we will remove this content immediately.

Liability for links

Our website contains links to external third-party websites whose content is beyond our control. We therefore cannot accept any responsibility for such third-party content. The respective provider or operator of each linked site is always responsible for its content. The linked sites were checked for possible legal violations when the links were created. No illegal content was apparent at that time. However, continuous monitoring of linked sites is not reasonable without specific evidence of a legal violation. If we become aware of any legal violations, we will remove the relevant links immediately.

Copyright

Content and works on these pages created by the site operators are subject to German copyright law. Reproduction, adaptation, distribution and any use beyond the scope of copyright law require the written consent of the respective author or creator. Downloads and copies of this site are permitted for private, non-commercial use only. Where content on this site was not created by the operator, third-party copyrights are respected. In particular, third-party content is identified as such. If you become aware of a copyright infringement, please notify us. Upon becoming aware of any legal violations, we will remove the relevant content immediately.

Privacy Policy

You can generally use our website without providing personal data. Where personal data (such as names, addresses or email addresses) is collected on our pages, this is, wherever possible, always done on a voluntary basis. This data will not be passed on to third parties without your express consent. Please note that data transmission over the internet (for example, when communicating by email) may have security vulnerabilities. It is not possible to completely protect data against access by third parties. We expressly object to the use by third parties of contact details published to meet legal notice requirements for sending unsolicited advertising or information. The site operators expressly reserve the right to take legal action if unsolicited advertising, such as spam emails, is sent.

Content Delivery Network (Cloudflare)

We use Cloudflare (Cloudflare, Inc., 101 Townsend St., San Francisco, CA 94107, USA) to protect and speed up our website. This constitutes a legitimate interest within the meaning of Art. 6(1)(f) GDPR. Cloudflare processes log data (including IP addresses) and sets technically necessary cookies to defend against malicious bot traffic. We have concluded a Data Processing Addendum (DPA) with Cloudflare based on the EU Standard Contractual Clauses. Cloudflare is certified under the EU-U.S. Data Privacy Framework.

Privacy Statement for using Google Analytics

This website uses Google Analytics 4, a web analytics service provided by Google Ireland Limited ("Google", Gordon House, Barrow Street, Dublin 4, Ireland). Data is processed solely on the basis of your express consent (Art. 6(1)(a) GDPR). Google Analytics uses cookies that enable analysis of how you use the website. Information generated by these cookies about your use of this website is transmitted to and stored on a Google server; transfer of data to third countries (such as the United States) cannot be ruled out. IP anonymization is enabled by default on this website, so Google truncates your IP address within a member state of the European Union or another state party to the Agreement on the European Economic Area before transmission. You may withdraw your consent at any time with effect for the future through the cookie settings (our consent tool), or prevent data collection by using the official Google browser add-on .

Copyright Statement

Unless noted otherwise, all artwork on this website is protected property of the website author. Any use for commercial purpose, reproduction and publication requires the author's written permission. Commercial work created in cooperation or bound by contract with third parties are specifically marked. Respective copyrights apply.

top