How to encrypt remote repo, with gcrypt or other?

1.7k Views Asked by At

The goal is to store my code encrypted on a BitBucket remote repo. Something should deal with encrypting and decrypting so I landed on gcrypt or in full, git-remote-gcrypt.

I have a Bitbucket account with SSH keys configured.
This is what I've tried.

rsync

I copied these commands from the manual.

git remote remove cryptremote
git remote add cryptremote gcrypt::rsync://[email protected]/user/cryptremote.git
git config remote.cryptremote.gcrypt-participants "user"
git push cryptremote master

console:

gcrypt: Repository not found: rsync://[email protected]/user/cryptremote.git
gcrypt: Setting up new repository
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(600) [sender=v3.2.3]
error: failed to push some refs to 'gcrypt::rsync://[email protected]/user/cryptremote.git'

3

There are 3 best solutions below

3
VonC On BEST ANSWER

[email protected]: I confirm this would never work, as an SSH URL to a Git remote repository hosting service would always use the 'git' user (and rely on the SSH key to authenticate and identify the actual user account).

spwhitton/git-remote-gcrypt commit 6233fde does mention:

Remove deprecated gcrypt::ssh:// (use rsync instead)

So a rsync URI seems more supported, as in commit 3b69f81

In your case:

 gcrypt::rsync://[email protected]/user/cryptremote.git
                ^^^^^            ^^^

For any "protocol version mismatch -- is your shell clean?" error message, try and put in your .bashrc:

# for non-interactive sessions stop execution here -- https://serverfault.com/a/805532/67528
[[ $- != *i* ]] && return

But check also a possible rsync version mismatch (for instance, using a Bitbucket pipeline just to display rsync version).

As illustrated here, if SSH is not working, a gcrypt::https://[email protected]/user/test.git HTTPS URL might work better.

0
progonkpa On

Thanks to the comments, I got it to work over HTTPS.

I wrote a small tutorial for myself and for you.


Encrypt remote Git repo with git-remote-gcrypt

General Workflow

  • generate GPG private and public key (GnuPG Linux)
  • create a remote repo
  • init a local repo
  • configure remote and gcrypt (commands below)
  • clone or push

gcrypt example with rsync didn't work with Bitbucket

git remote add cryptremote gcrypt::rsync://[email protected]/USER/cryptremote.git
# gcrypt docs use :user but git usually uses /user format
# git remote add cryptremote gcrypt::rsync://[email protected]:USER/cryptremote.git
git config remote.cryptremote.gcrypt-participants "GPG_KEY_ID_OR_KEY_NAME"
git config remote.cryptremote.gcrypt-signingkey "GPG_KEY_ID_OR_KEY_NAME"
git push cryptremote master

gcrypt: Repository not found: rsync://[email protected]/user/cryptremote.git gcrypt: Setting up new repository protocol version mismatch -- is your shell clean? (see the rsync man page for an explanation) rsync error: protocol incompatibility (code 2) at compat.c(600) [sender=v3.2.3] error: failed to push some refs to 'gcrypt::rsync://[email protected]/user/cryptremote.git'

gcrypt over HTTPS

Template from man page, modified to HTTPS, example repo name 'cryptremote':

git init
git remote add origin gcrypt::https://USER:[email protected]/USER/cryptremote.git
git config remote.origin.gcrypt-participants "GPG_KEY_ID_OR_KEY_NAME"
git config remote.origin.gcrypt-signingkey "GPG_KEY_ID_OR_KEY_NAME"
# removes GPG password prompts but makes the name of the key owner public
git config remote.origin.gcrypt-publish-participants true
# in case of an existing encrypted repo
git clone gcrypt::https://USER:[email protected]/USER/cryptremote.git
# in case of starting a new encrypted remote repo
git push --set-upstream origin master

Fix GPG password prompts during gcrypt push and pull

man git-remote-gcrypt

gcrypt.publish-participants

By default, the gpg key ids of the participants are obscured by encrypting using gpg -R. Setting this option to true disables that security measure.


Gratitude for something that works.

However, I don't like that I had to use HTTPS and an app password as Bitbucket now forces its users to use those for HTTPS.

Though I'm not sure why rsync isn't working, it seems the issue lies at Bitbucket as I use rsync flawlessly between my computer and my Android.

3
gsal On

So, it seems the instructions vary and some indications do not even work; I started to try the various combinations of " : " vs " / " and "https" vs. "rsync" vs "git"....and finally found a combination that seems to work:

git remote add origin gcrypt::git@<URL>:<group>/test.git

git config remote.origin.gcrypt-participants "<my-key-id>"
git config remote.origin.gcrypt-signingkey "<my-key-id>"

git push -u origin alpha
gcrypt: Repository not found: git@<URL>:<group>/test.git
gcrypt: Setting up new repository
gcrypt: Remote ID is :id:<some hash>
gcrypt: Due to a longstanding bug, this push implicitly has --force.
gcrypt: Consider explicitly passing --force, and setting
gcrypt: gcrypt's require-explicit-force-push git config key.
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Compressing objects: 100% (2/2), done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
gcrypt: Encrypting to:  -r <my-key-id>
gcrypt: Requesting manifest signature
remote: 
remote: To create a merge request for master, visit:
remote:   http://<URL>/<group>/test/-/merge_requests/new?merge_request%5Bsource_branch%5D=master
remote: 
To <URL>:<group>/test.git
 * [new branch]      alpha -> alpha
Branch 'alpha' set up to track remote branch 'alpha' from 'origin'.

When I go to the gitlab repo, I can see two new files with hex names.

But then, I try to clone the repo back and get the following error:

cd somewhere-else
git clone gcrypt::git@<URL>:<group>/test.git
Cloning into 'test'...
gpg: error reading key: No public key

What's the problem? It was I who encrypted this a moment ago and now I cannot clone.

Any pointers?