Gitea SSL con Apache come proxy inverso

Per utilizzare il registro dei contenitori in k8s è necessario utilizzarlo su SSL

Indice

Vogliamo ospitare un registro dei contenitori sicuro e gradevole – per spingere le immagini docker lì e il nostro cluster kubernetes le tirerà da questo registro. Così è venuta l’idea di utilizzare Gitea su SSL.

  1. Gitea ha già un registro dei contenitori
  2. Apache come proxy terminatore TLS aggiungerà HTTPS al nostro Gitea.
  3. Ecco come è iniziato… CA rotta, certificati autofirmati…

Ogni registro ha i propri segreti

Quando abbiamo bisogno del registro in k8s

Purtroppo il registro nel cluster kubernetes creato da kubespray non funziona per me.

  • per spingere dentro di esso dobbiamo creare un tunnel temporaneo tramite kube-proxy
  • dopo aver spinto dentro di esso la mia versione attuale del nuovo cluster non riesce a tirare immagini da questo registro interno

Dopo aver trascorso alcune fantastiche serate cercando di risolverlo, ho deciso di utilizzare il registro dei contenitori interno a Gitea, basta configurare l’accesso HTTPS a esso.

Lo renderò pubblico comunque, così docker e k8s non devono fare alcun login docker. Forse. Vedremo come andrà.

Testando se funziona

Per testare se il registro dei contenitori si adatta a noi vogliamo poter

  • spingere un’immagine lì e
  • creare un deployment in k8s da quell’immagine
sudo docker pull alpine:3.12.0
sudo docker images
sudo docker tag a24bb4013296 localhost:5000/rg/alpine:version.3.12.0
sudo docker push localhost:5000/rg/alpine:version.3.12.0

Ora xed alp1.yaml o nano alp1.yaml a seconda del tuo umore e

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alp-registry-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alp-registry-test
  template:
    metadata:
      labels:
        app: alp-registry-test
    spec:
      containers:
        - name: alpine-test
          image: localhost:5000/rg/lpine:version.3.12.0
      imagePullSecrets:
      - name: registry-secret

Ecco questo file disponibile per il download Poi creando questo deployment

kubectl create -f alp1.yaml
kubectl get pods

kubectl describe po alp-registry-test-5f5cb94b97-njsp2
# o qualunque pod sia stato creato o non creato

Sì, so di questo frammento

      imagePullSecrets:
      - name: registry-secret 

registry-secret è il nome del segreto creato da kubespray.

Pulizia

kubectl delete -f alp1.yaml

Come

Una serie di documentazione è disponibile sul sito Gitea: https-setup

E su questa pagina: https://docs.gitea.com/administration/reverse-proxies

Passo 1 - Installare Apache e creare un semplice sito di test

Installare Apache

sudo apt install apache2

Controllare cosa abbiamo nel firewall

sudo ufw status

Se il firewall è attivo pensare a quale porta si vuole esporre tramite https e permetterla. Le configurazioni standard di apache sono

sudo ufw app list

Potremmo vedere qualcosa come

Applicazioni disponibili:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

e per abilitare solo la porta 443 eseguiamo

sudo ufw allow 'Apache Secure'

ok. ora controllare lo stato del servizio

sudo systemctl status apache2

Successivamente - creare un semplice server virtuale per testare Apache

sudo mkdir /var/www/reg.homelab
sudo chown -R $USER:$USER /var/www/reg.homelab
sudo chmod -R 755 /var/www/reg.homelab
sudo nano /var/www/reg.homelab/index.html

Inserire lì

<html>
    <head>
        <title>Benvenuti in reg.homelab!</title>
    </head>
    <body>
        <h1>Successo! Il virtual host reg.homelab funziona!</h1>
    </body>
</html>

poi

sudo nano /etc/apache2/sites-available/reg.homelab.conf

e mettere lì

<VirtualHost *:3080>
    ServerAdmin webmaster@localhost
    ServerName reg.homelab
    ServerAlias www.reg.homelab
    DocumentRoot /var/www/reg.homelab
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

poi disabilitare il sito predefinito, abilitare questo e controllare come stiamo andando

sudo a2ensite reg.homelab.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest

vedere qualcosa come questo?

AH00558: apache2: Non è stato possibile determinare con certezza il nome completo del server, utilizzando 127.0.1.1. Impostare la direttiva 'ServerName' globalmente per eliminare questo messaggio

poi

sudo nano /etc/apache2/apache2.conf

aggiungere alla fine:

ServerName reg.homelab

E questo non è ancora la fine! Ora dobbiamo rimuovere l’attempto di binding sulla porta 80

sudo nano /etc/apache2/ports.conf

mettere lì

Listen 3030
...
Listen 443

E ora

sudo systemctl restart apache2
sudo systemctl status apache2
journalctl -xeu apache2.service
curl localhost:3080

OK! Ora navigare a :3080

Passo 2 - Convertire questo sito in un reverse proxy non sicuro :) verso Gitea

sudo nano /etc/apache2/sites-available/reg.homelab.conf

mettendo lì

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName reg.homelab
    ServerAlias www.reg.homelab
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ProxyPreserveHost On
    ProxyRequests off
    AllowEncodedSlashes NoDecode
    ProxyPass / http://localhost:3000/ nocanon
</VirtualHost>

Fare alcuni test di configurazione

sudo apache2ctl configtest

Aggiungere alcuni moduli apache e riavviare Apache

sudo a2enmod proxy proxy_http ssl
sudo systemctl restart apache2
sudo systemctl status apache2

OK, ora navigare a o curl

# Sì, è ancora http, ma sulla porta 443
curl http://localhost:443
http://<Server_IP_Address>:443/

Passo 3 - CA radice autofirmata e certificato del sito

SweetHome-RootCA.

CANAME=MostImportant-RootCA

# opzionale, creare una directory
mkdir $CANAME
cd $CANAME

# generare una chiave privata crittografata con aes
openssl genrsa -aes256 -out $CANAME.key 4096

# creare certificato, 1826 giorni = 5 anni
openssl req -x509 -new -nodes -key $CANAME.key -sha256 -days 1826 -out $CANAME.crt -subj '/CN=My Root CA/C=AT/ST=Vienna/L=Vienna/O=MyOrganisation'

# creare certificato per il servizio
MYCERT=reg.homelab
openssl req -new -nodes -out $MYCERT.csr -newkey rsa:4096 -keyout $MYCERT.key -subj '/CN=My Firewall/C=AT/ST=Vienna/L=Vienna/O=MyOrganisation'

# creare un file v3 ext per le proprietà SAN
cat > $MYCERT.v3.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = reg.homelablab
DNS.2 = gitea.homelablab
IP.1 = 192.168.0.10
IP.2 = 192.168.0.11
EOF

openssl x509 -req -in $MYCERT.csr -CA $CANAME.crt -CAkey $CANAME.key -CAcreateserial -out $MYCERT.crt -days 730 -sha256 -extfile $MYCERT.v3.ext
Su macchine che si connettono a gitea / registro

Registrare il certificato radice su linux:

sudo cp MostImportant-RootCA.crt /usr/local/share/ca-certificates
sudo update-ca-certificates

Registrare il certificato radice su windows:

  • Doppio clic sul file MostImportant-RootCA.crt
  • Importare per l’utente locale
  • Selezionare Truster Root CA.
  • Quando richiesto riguardo all’importazione di un certificato non attendibile - cliccare sì

Quando git pull su windows dice

Impossibile risolvere "unable to get local issuer certificate...

si può dire a git di utilizzare il layer di rete windows con

git config --global http.sslbackend schannel

Passo 4 - Sicurezza del proxy con certificato autofirmato

https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html

Creare un certificato autofirmato SE non lo hai creato nel passo 3

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -subj "/CN=reg.homelab" \
  -addext "subjectAltName = DNS:reg.homelab" \
  -keyout /etc/ssl/private/apache-selfsigned-reg.homelab.key \
  -out /etc/ssl/certs/apache-selfsigned-reg.homelab.crt

O semplicemente prenderlo dal passo precedente

sudo cp reg.homelab.crt /etc/ssl/certs/apache-selfsigned-reg.homelab.crt
sudo cp reg.homelab.key /etc/ssl/private/apache-selfsigned-reg.homelab.key

Ancora una volta, aprire la configurazione del virtual host

sudo nano /etc/apache2/sites-available/reg.homelab.conf

Aggiungere in fondo la sezione SSL con i certificati

<VirtualHost *:443>
   ServerAdmin webmaster@localhost
   ServerName reg.homelab
   ServerAlias www.reg.homelab
   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined
   ProxyPreserveHost On
   ProxyRequests off
   AllowEncodedSlashes NoDecode
   ProxyPass / http://localhost:3000/ nocanon
    
   SSLEngine on
   SSLCertificateFile /etc/ssl/certs/apache-selfsigned-reg.homelab.crt
   SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned-reg.homelab.key
</VirtualHost>

Controllare la configurazione, riavviare il server, controllare lo stato e navigare verso il nostro Gitea su SSL

sudo apache2ctl configtest
sudo systemctl restart apache2
sudo systemctl status apache2

# andare a: http://<Server_IP_Address>:443/
# o
curl -k -v https://localhost

il browser avviserà riguardo al certificato autofirmato

La tua connessione non è privata
Gli attaccanti potrebbero cercare di rubare le tue informazioni da reg.homelab (ad esempio, password, messaggi o carte di credito). Scopri di più
NET::ERR_CERT_AUTHORITY_INVALID

Ma lo ignoreremo, per ora, finché non utilizziamo Let’s Encrypt.

Ora il test su k8s

Fare alcuni DNS…

Su ogni nodo k8s:

sudo nano /etc/hosts

e aggiungere lì

192.168.18.200 gitea.homelab
192.168.18.200 reg.homelab

CA radice

Su ogni nodo k8s:

sudo cp SweetHome-RootCA.crt /usr/local/share/ca-certificates
sudo update-ca-certificates

E riavviare ora

Creare il segreto con le credenziali del registro

https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

sudo docker login reg.homelab
kubectl create secret generic regcred --from-file=.dockerconfigjson=/home/rg/.docker/config.json --type=kubernetes.io/dockerconfigjson

o

kubectl create secret docker-registry regcred --docker-server=your-registry-server --docker-username=your-name --docker-password=your-pword --docker-email=your-email

Nuova immagine docker e deployment k8s

sudo docker pull alpine:3.12.0
sudo docker images
sudo docker tag a24bb4013296 reg.homelab/rg/alpine:version.3.12.0
sudo docker push reg.homelab/rg/alpine:version.3.12.0

Ora nano alp2.yaml, il file è [disponibile]disponibile

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alp-registry-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alp-registry-test
  template:
    metadata:
      labels:
        app: alp-registry-test
    spec:
      containers:
        - name: alpine-test
          image: reg.homelab/rg/alpine:version.3.12.0
      imagePullSecrets:
      - name: regcred

Ecco questo file disponibile per il download: Poi creando questo deployment

kubectl create -f alp2.yaml
kubectl get pods
kubectl describe po alp...

Pulizia

kubectl delete -f alp2.yaml