Running a git-annex forge on a Synology NAS
I recently purchased a Synology DS1522+ for my house and have been transitioning my data to it. A significant amount of my data is in git-annex repositories that are managed with gitolite on my server.
I used Deploying and managing Forgejo-aneksajo with podman and systemd from the DataLad blog to guide my efforts, and this post is intended mainly as notes where I had to find alternate methods.
Docker
Synology ships a custom Linux distribution that does not come with a full-fledged package manager. It does, on the other hand, have a Container Manager, which is a Docker interface. So the first adaptation is to use Docker instead of podman, which means managing permissions.
The docker group
Synology has a web UI for creating groups, but you can use the command line:
sudo synogroup --add docker
sudo chown :docker /var/run/docker.sock
The git user
I would like to use the convention of git@<host>:<org>/<repo>
that is typical of git servers, but the Synology web UI does not permit you to create a git
user. It does not restrict its CLI, however:
sudo synouser --add git none "git user" 0 noreply@nodomain none
sudo passwd -ld git
Now, in order to run the SSH passthrough, the git user needs the docker group to be its primary group, not just a member. There is no equivalent to usermod
available, even after installing busybox, so this needs to be edited manually.
git:x:1000:65536:git user:/var/services/homes/git:/bin/sh
The docker GID assigned was 65536, so that was set there. Also, Synology starts UIDs at 1024, but the container we’ll use uses 1000. For simplicity, I changed the UID here.
The docker image
For a first pass, I’m using the image published by Michael Hanke:
Very little configuration is needed, but it looks like this:
SSH Passthrough
Note above that we do not change the shell, which is a departure from the DataLad instructions. Synology appears to have custom PAM modules that prevent the use of arbitrary programs as shells, as opposed to the more standard pam_shells (8).
Therefore we need to use AuthorizedKeysCommand
in sshd_config (5) to do all of the work for us.
/usr/local/bin/forgejo-keys
#!/bin/sh
PROXY=/usr/local/bin/docker
CONTAINER=forgejo
KEYS_COMMAND="/usr/local/bin/gitea keys -c /etc/gitea/app.ini"
$PROXY exec $CONTAINER $KEYS_COMMAND $@ \
| sed -e 's@/@'"${PROXY} exec -i -e SSH_ORIGINAL_COMMAND $CONTAINER /@"
This script passes arguments to gitea keys
inside the container, which returns a command that can be run inside the container, for example:
command="/usr/local/bin/gitea --config=/etc/gitea/app.ini serv key-1",<ssh-options> ssh-ed25519 <pubkey>
The sed
script finds the first /
and inserts a docker exec
prefix, for example:
command="/usr/local/bin/docker exec -i -e SSH_ORGINAL_COMMAND forgejo /usr/local/bin/gitea --config=/etc/gitea/app.ini serv key-1",<ssh-options> ssh-ed25519 <pubkey>
To ensure that this is usable by sshd
, set the permissions correctly:
sudo chown root:root /usr/local/bin/forgejo-keys
sudo chmod 755 /usr/local/bin/forgejo-keys
Finally, update sshd_config
:
/etc/ssh/sshd_config
...
Match User git
AuthorizedKeysCommandUser git AuthorizedKeysCommand /usr/local/bin/forgejo-keys -e git -u %u -t %t -k %k
Reverse proxy
The only remaining thing is to set up Synology’s reverse proxy through their Control Panel:
A little bit more configuration is needed to get a LetsEncrypt certificate working. If I flesh out this post into a full how-to, I will include that as well.