Securing Gitea with HTTPS
I’ve got Gitea installed on my cluster, but it’s currently accessed via HTTP (i.e. no TLS; it’s not secure).
Ordinarily, I’d secure it by replacing the LoadBalancer service with an Ingress object. However: Gitea allows git access over HTTPS and SSH protocols. If we use a standard Ingress object, we’ll only be able to use HTTPS. That complicates things.
Separate DNS entries
While researching this problem, I found “Deploying Fully Functional Gitea on Google Kubernetes Engine
(GKE)”, which punts the problem: it runs HTTPS through an Ingress on one name (
gitea.example.com), and SSH
through a LoadBalancer on another name (
In theory, however, Traefik IngressRoute objects support multiple protocols. My concern there, though, is how that’s
going to work with DNS. I’ve got a LoadBalancer (on
192.168.28.10) pointing at Traefik, which then uses the various
Ingress and IngressRoute objects to route the traffic appropriately.
I’d need to add port 22 (ssh) to that LoadBalancer and then somehow persuade Traefik to route all SSH traffic to
Gitea. It would need to route all traffic, because SSH doesn’t provide the equivalent of HTTP’s
Host header or TLS
Server Name Indication (SNI).
I guess I could route the SSH traffic to a Bastion server (a “bounce box”), though… (strokes chin).
Multiple Traefik Instances
One other option that occurs is to add another Traefik instance, with its own LoadBalancer (hence its own IP address and DNS entry). That would be responsible for Gitea and nothing else. It could route SSH traffic as normal, and could do the TLS termination for Gitea.
Gitea does TLS termination
The least-bad option, as far as I can tell at this point, is to have Gitea do its own TLS termination. That’s documented here; all we need to do is figure out how to provide the TLS certificates in an idiomatic Kubernetes way.
Gitea HTTPS setup
To tell Gitea about the TLS certificates, we need to edit the
values.yaml file. As far as I can tell, that means uninstalling the Helm chart and then reinstalling it with the changes.
helm --namespace gitea uninstall gitea
Create a TLS secret
./certs create-cert \ --issuer-cert k3s-ca.crt --issuer-key k3s-ca.key \ --out-cert gitea.crt --out-key gitea.key \ --template server \ --subject '/CN=git.k3s.differentpla.net'
Note that the
CN= needs to match the server name in DNS. For Gitea, I used
git.k3s..., rather than
echo "tls.crt: $(base64 -w0 < gitea.crt)" echo "tls.key: $(base64 -w0 < gitea.key)"
apiVersion: v1 kind: Secret type: kubernetes.io/tls metadata: name: gitea-tls namespace: gitea data: tls.crt: LS0tLS1... tls.key: LS0tLS1...
values.yaml so that it looks like this:
... gitea: config: server: DOMAIN: git.k3s.differentpla.net PROTOCOL: https CERT_FILE: /certs/tls.crt KEY_FILE: /certs/tls.key ... extraVolumes: - name: gitea-tls secret: secretName: gitea-tls extraVolumeMounts: - name: gitea-tls readOnly: true mountPath: /certs
gitea.config values will be written to
extraVolumeMounts entries are for the
helm install gitea gitea-charts/gitea --namespace gitea --create-namespace --values values.yaml
apiVersion: v1 kind: Service metadata: labels: app: gitea name: gitea namespace: gitea spec: type: LoadBalancer ports: - name: gitea-https # <-- port: 443 # <-- protocol: TCP targetPort: 3000 - name: gitea-ssh port: 22 protocol: TCP targetPort: 22 selector: app: gitea