82 lines
3.7 KiB
Markdown
82 lines
3.7 KiB
Markdown
---
|
|
title: "Replicating Gitea Docker SSH Passthrough on K3s"
|
|
date: "2023-02-12"
|
|
---
|
|
|
|
If you are selfhosting Gitea on a single node Kubernetes cluster and want to enable git through SSH while keeping SSH connection to the cluster, this guide is for you.
|
|
|
|
<!--more-->
|
|
|
|
**Update**
|
|
|
|
As of Gitea Helm Chart v9.0.0, Gitea is not a StatefulSet but a Deployment instead. In order to make this work you have to replace pod pod name `gitea-0` with:
|
|
|
|
{{< highlight bash >}}
|
|
$(kubectl get po -n gitea -l app=gitea -o name --no-headers=true)
|
|
{{< / highlight >}}
|
|
|
|
|
|
Command substitution does not work in `AuthorizedKeysCommand` so I suggest creating a separate script along the lines of `/usr/local/bin/gitea-shell`
|
|
|
|
|
|
## Background
|
|
|
|
I am currently in the process of migrating my selfhosted applications from docker-compose to Kubernetes. One of my most used selfhosted app is Gitea. I use it to host my projects, dotfiles and config files where I don't expect any contributions or I simply want to keep it more private. In my docker-compose setup I used SSH Container Passthrough from [Gitea docs](https://docs.gitea.io/en-us/install-with-docker/#SSH-container-passthrough) but when I moved Gitea to k3s I couldn't find any guides on how to achieve the same thing.
|
|
|
|
I installed Gitea using the official [Helm Chart](https://gitea.com/gitea/helm-chart/). The documentation says this about enabling SSH:
|
|
|
|
> If you're using ingress and want to use SSH, keep in mind, that ingress is not able to forward SSH Ports. You will need a LoadBalancer like metallb and a setting in your SSH service annotations.
|
|
|
|
However using this method will route all incoming SSH connections to the Gitea container, essentialy disabling SSH connection to the host. Therefore we need a way to pass SSH connections to user `git` to our Gite container running on Kubernetes and at the same time allow SSH connections to host for some other user(s)
|
|
|
|
## Kubernetes Setup
|
|
|
|
Create user git on your host and deploy Gitea to Kubernetes (e.g. using Helm). You don't need to expose port 22 using a service.
|
|
|
|
First we are going to create a new login shell for user git. Create file `/usr/local/bin/gitea-shell` with content:
|
|
|
|
{{< highlight bash >}}
|
|
#!/bin/sh
|
|
/usr/local/bin/kubectl exec -i -n gitea gitea-0 -c gitea -- env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" /bin/sh "$@"
|
|
{{< / highlight >}}
|
|
|
|
Your namespace might be different.
|
|
|
|
Then run as root (or sudo):
|
|
|
|
{{< highlight bash >}}
|
|
chmod +x /usr/local/bin/gitea-shell
|
|
usermod -s /usr/local/bin/gitea-shell git
|
|
{{< / highlight >}}
|
|
|
|
Now everytime the user git logs in (i.e. using git via SSH) `/usr/local/bin/gitea-shell` gets executed which means our original SSH command will be executed in the gitea container.
|
|
|
|
Finally we need to make sure that the SSH keys we add through Gitea interface allow us to 'login' as git user.
|
|
|
|
Edit `/etc/SSH/SSHd_config` and add the following:
|
|
|
|
{{< highlight yaml>}}
|
|
Match User git
|
|
AuthorizedKeysCommandUser git
|
|
AuthorizedKeysCommand /usr/local/bin/kubectl exec -i -n gitea gitea-0 -c gitea -- /usr/local/bin/gitea keys -e git -u %u -t %t -k %k
|
|
{{< / highlight >}}
|
|
|
|
If you are using `AllowUsers` directive don't forget to add user git
|
|
|
|
## Testing
|
|
|
|
Open Gitea in web browser and add you SSH key. Then try to SSH into the Gitea container.
|
|
|
|
{{< highlight bash >}}
|
|
ssh git@<your gitea url>
|
|
{{< / highlight >}}
|
|
|
|
You should get a message like this:
|
|
|
|
> PTY allocation request failed on channel 0
|
|
> Hi there, test! You've successfully authenticated with the key named <your ssh key>, but Gitea does not provide shell access.
|
|
> If this is unexpected, please log in with password and setup Gitea under another user.
|
|
> Connection to <your gitea url> closed.
|
|
|
|
Now you can create a repo and you should be able to clone and push via SSH.
|