Konfiguracja SSL w Gitea z użyciem Apache jako odwrotnego proxy'ego

Aby użyć rejestru kontenerów w k8s, potrzebujemy go z wykorzystaniem SSL.

Page content

Chcemy uruchomić przyjazny i bezpieczny rejestru kontenerów – aby przesyłać obrazy docker do niego, a nasz kubernetes cluster pobierał je z tego rejestru. Wtedy przyszła idea użycia gitea z ssl.

  1. Gitea już ma rejestru kontenerów
  2. Apache jako proxy kończący TLS dodaj HTTPS do naszego Gitea.
  3. I tak się zaczęło… Rot CA, certyfikaty samozsygnowane…

Każdy rejestru ma swoje sekrety

Kiedy potrzebujemy rejestru w k8s

Niestety rejestru w klastrze kubernetes utworzonego przez kubespray nie działa dla mnie.

  • aby przesłać do niego musimy utworzyć tymczasowy tunel przez kube-proxy
  • po przesłaniu do niego moja aktualna wersja nowego klastra nie mogła pobrać obrazów z tego wewnętrznego rejestru

Po spędzić kilka wspaniałych dwóch wieczorów próbując naprawić to, zdecydowałem się po prostu użyć wewnętrznego rejestru kontenerów Gitea, wystarczy skonfigurować HTTPS do niego.

Zrobię to publicznym, więc docker i k8s nie muszą wykonywać żadnych logowań do docker. Może. Zobaczymy jak to pójdzie.

Testowanie czy działa

Aby przetestować czy rejestru kontenerów odpowiada nam chcemy móc

  • przesłać obraz tam i
  • utworzyć wdrożenie w k8s z tego obrazu
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

Teraz xed alp1.yaml lub nano alp1.yaml w zależności od tego w jakim nastroju jesteś i

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

Oto ten plik dostępny do pobrania Następnie tworzenie tego wdrożenia

kubectl create -f alp1.yaml
kubectl get pods

kubectl describe po alp-registry-test-5f5cb94b97-njsp2
# albo co pod został utworzony albo nie

Tak, wiem o tym fragmencie

      imagePullSecrets:
      - name: registry-secret 

registry-secret to nazwa sekretu utworzonego przez kubespray.

Czyszczenie

kubectl delete -f alp1.yaml

Jak

Duża ilość dokumentacji dostępna jest na stronie Gitea: https-setup

I na tej stronie: https://docs.gitea.com/administration/reverse-proxies

Krok 1 - Instalacja Apache i utworzenie prostego testowego serwera

Instalacja Apache

sudo apt install apache2

Sprawdzenie co mamy w firewall

sudo ufw status

Jeśli firewall jest aktywny, pomyśl, który port chcesz uwidocznić przez https i zezwól na niego. Standardowe konfiguracje apache to

sudo ufw app list

Możemy zobaczyć coś takiego jak

Dostępne aplikacje:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

i aby włączyć tylko port 443 wykonujemy

sudo ufw allow 'Apache Secure'

OK. teraz sprawdź status serwisu

sudo systemctl status apache2

Następnie - utwórz prosty serwer wirtualny, aby przetestować 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

Wstaw tam

<html>
    <head>
        <title>Witaj w reg.homelab!</title>
    </head>
    <body>
        <h1>Sukces! Wirtualny host reg.homelab działa!</h1>
    </body>
</html>

następnie

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

i wstaw tam

<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>

następnie wyłącz domyślny serwer, włącz ten i sprawdź jak się mamy

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

widzisz coś takiego?

AH00558: apache2: Nie można niezawodnie określić pełnej nazwy domeny serwera, używając 127.0.1.1. Ustaw dyrektywę 'ServerName' globalnie, aby zignorować to wiadomość

następnie

sudo nano /etc/apache2/apache2.conf

dodaj na końcu:

ServerName reg.homelab

I to wciąż nie koniec! teraz trzeba usunąć próbę wiązania portu 80

sudo nano /etc/apache2/ports.conf

wstaw tam

Listen 3030
...
Listen 443

I teraz

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

OK! Teraz przejdź do :3080

Krok 2 - Konwertowanie tego serwera na niebezpieczny proxy odwrotny :) do Gitea

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

wstaw tam

<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>

Zrób test konfiguracji

sudo apache2ctl configtest

Dodaj niektóre moduły apache i restartuj Apache

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

OK, teraz przejdź do lub curl

# Tak, nadal to jest http, ale na porcie 443
curl http://localhost:443
http://<Server_IP_Address>:443/

Krok 3 Samozsygnowany root CA i certyfikat serwisu

SweetHome-RootCA.

CANAME=MostImportant-RootCA

# opcjonalnie, utwórz katalog
mkdir $CANAME
cd $CANAME

# wygeneruj prywatny klucz zaszyfrowany aes
openssl genrsa -aes256 -out $CANAME.key 4096

# utwórz certyfikat, 1826 dni = 5 lat
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'

# utwórz certyfikat dla usługi
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'

# utwórz plik v3 ext dla właściwości 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
Na maszynach łączących się z gitea / rejestru

Zarejestruj certyfikat root na linux:

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

Zarejestruj certyfikat root na windows:

  • Podwójnie kliknij plik MostImportant-RootCA.crt
  • Zaimportuj do użytkownika lokalnego
  • Wybierz Truster Root CA.
  • Kiedy zostaniesz poproszony o zaimportowanie niezaufanego certyfikatu - kliknij tak

Kiedy git pull na windows mówi o

Nie można rozwiązać "unable to get local issuer certificate...

możesz powiedzieć git, aby używał warstwy sieciowej windows przez

git config --global http.sslbackend schannel

Krok 4 - Zabezpieczenie proxy za pomocą certyfikatu samozsygnowanego

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

Utwórz samozsygnowany certyfikat, jeśli nie zrobiłeś tego w kroku 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

Lub po prostu wziąć go z poprzedniego kroku

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

Znowu otwórz konfigurację wirtualnego hosta

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

Dodaj na dół sekcję SSL z certyfikatami

<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>

Sprawdź konfigurację, restartuj serwer, sprawdź status i przejdź do naszego Gitea przez SSL

sudo apache2ctl configtest
sudo systemctl restart apache2
sudo systemctl status apache2

# przejdź do: http://<Server_IP_Address>:443/
# albo
curl -k -v https://localhost

przeglądarka będzie ostrzegać o samozsygnowanym certyfikacie

Twoja połączenie nie jest prywatne
Atakujący mogą próbować ukraść Twoje informacje z reg.homelab (np. hasła, wiadomości lub karty kredytowe). Dowiedz się więcej
NET::ERR_CERT_AUTHORITY_INVALID

Ale zignorujemy to, na razie, aż użyjemy Let’s Encrypt.

Teraz test k8s

Zrób trochę DNSowania…

Na każdym węźle k8s:

sudo nano /etc/hosts

i dodaj tam

192.168.18.200 gitea.homelab
192.168.18.200 reg.homelab

Root CA

Na każdym węźle k8s:

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

I restartuj teraz

Utwórz sekret z poświadczeniami rejestru

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

lub

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

Nowy obraz docker i wdrożenie 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

Teraz nano alp2.yaml, plik jest [dostępny]dostępny

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

Oto ten plik dostępny do pobrania: Tworzenie tego wdrożenia

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

Czyszczenie

kubectl delete -f alp2.yaml

Przydatne linki