Skip to content

Instantly share code, notes, and snippets.

@bcduggan
Last active February 15, 2025 03:33
Show Gist options
  • Select an option

  • Save bcduggan/ecd01b9451fb39ec821d2a3bd3d3c94d to your computer and use it in GitHub Desktop.

Select an option

Save bcduggan/ecd01b9451fb39ec821d2a3bd3d3c94d to your computer and use it in GitHub Desktop.
Qubes RPC service for git remotes

Qubes RPC for git remotes over qrexec

This gist describes a set of configurations to implement a new set of Qubes RPCs, qubes.GitUploadPack and qubes.GitReceivePack. These RPCs allow a client qube to clone, fetch, push, etc from local repositories to repositories on service qubes over qrexec. Qubes policy can control ro (clone, fetch, etc) and rw (push, etc) access per-repository.

The RPCs only allow access to git repositories on the service qube filesystem. They do not connect the client qube to internet git servers or forges.

However, the service qube can mount directories of git repositories to its filesystem from any remote storage service.

Purpose

There are nicer ways to implement these RPCs. But the files in this gist are, hopefully, close to the minimal delta from a base system to implement them. They are suited for manual entry to bootstrap a new Qubes system.

Target

Debian qubes. YMMV.

Usage

Client qube

git clone --config protocol.ext.allow=user "ext::git qubes-remote-%s remote-qube /repos/project"

Policy

These RPCs require an argument to connect to the git repository. The argument must be a systemd-escaped path to a git repository on the git remote service qube.

For example, a git remote service qube has a git repository at /repos/project. The systemd-escaped version of this path is repos-project. A policy that allows client-qube to clone /repos/project on remote-qube would be

qubes.GitUploadPack +repos-project client-qube remote-qube allow

NB: Use systemd-escape --path

Without the --path flag, systemd-escape will escape the entire path, producing -repos-project, which programs interpret as an option. Always uses the --path flag with systemd-escape on paths for both escaping and unescaping.

# On dom0:
# /etc/qubes/policy.d/10-git-remote.policy
#
# service_name argument source_qube target_qube action [parameter=value]
qubes.GitUploadPack +repos-project client-qube remote-qube allow
qubes.GitReceivePack +repos-project client-qube remote-qube allow
#!/usr/bin/sh
# On the git remote service qube:
# /etc/qubes-rpc/qubes.GitUploadPack
exec git-upload-pack "$(systemd-escape --path --unescape $QREXEC_SERVICE_ARGUMENT)"
#!/usr/bin/sh
# On the git remote service qube:
# /etc/qubes-rpc/qubes.GitReceivePack
exec git-receive-pack "$(systemd-escape --path --unescape $QREXEC_SERVICE_ARGUMENT)"
# On the git client qube:
# /home/user/.gitconfig
# Where `remote-qube` is the name of the Qube that hosts remote git repositories:
[alias]
qubes-remote-upload-pack = !sh -c 'qrexec-client-vm $0 qubes.GitUploadPack+$(systemd-escape --path $1)'
qubes-remote-receive-pack = !sh -c 'qrexec-client-vm $0 qubes.GitReceivePack+$(systemd-escape --path $1)'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment