Gitea SSL с Apache в качестве обратного прокси

Для использования репозитория контейнеров в k8s необходимо использовать его через SSL

Содержимое страницы

Мы хотим разместить удобный и безопасный контейнерный реестр, чтобы туда отправлять образы Docker, а наш кластер Kubernetes мог их извлекать из этого реестра.
Идея использовать Gitea поверх SSL возникла именно из-за этого.

  1. Gitea уже имеет контейнерный реестр
  2. Apache в роли прокси-сервера с терминированием TLS добавит HTTPS к нашему Gitea.
  3. Так всё и началось… Создание корневого CA, самоподписанные сертификаты…

Каждый реестр имеет свои секреты

Когда нам нужен реестр в k8s

К сожалению, реестр, созданный в кластере Kubernetes с помощью kubespray, не работает для меня.

  • чтобы отправить образ туда, нужно создать временный туннель через kube-proxy
  • после отправки образа в него моя текущая версия нового кластера не может извлекать образы из этого внутреннего реестра

После того, как я потратил несколько потрясающих двух вечеров на попытки это исправить, я решил просто использовать внутренний контейнерный реестр Gitea, нужно только настроить HTTPS-доступ к нему.

Сделаю его публичным, так что Docker и Kubernetes не будут выполнять никаких логинов в Docker. Возможно. Посмотрим, как всё пойдёт.

Проверка работоспособности

Чтобы проверить, подходит ли контейнерный реестр, нам нужно уметь:

  • отправлять образ туда и
  • создавать развертывание в k8s из этого образа
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

Теперь xed alp1.yaml или nano alp1.yaml в зависимости от вашего настроения и

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

Этот файл доступен для скачивания
Затем создание этого развертывания

kubectl create -f alp1.yaml
kubectl get pods

kubectl describe po alp-registry-test-5f5cb94b97-njsp2
# или любой другой созданный или не созданный pod

Да, я знаю об этом фрагменте

      imagePullSecrets:
      - name: registry-secret 

registry-secret — это имя секрета, созданного kubespray.

Очистка

kubectl delete -f alp1.yaml

Как

Пакет документации доступен на сайте Gitea: https-setup

И на этой странице: https://docs.gitea.com/administration/reverse-proxies

Шаг 1 — установка Apache и создание простого тестового сайта

Установите Apache

sudo apt install apache2

Проверьте, что у вас есть в брандмауэре

sudo ufw status

Если брандмауэр активен, подумайте, какой порт вы хотите открыть через HTTPS и разрешите его. Стандартные настройки Apache:

sudo ufw app list

Мы можем увидеть что-то вроде

Доступные приложения:
  Apache
  Apache Full
  Apache Secure
  OpenSSH

и чтобы включить только порт 443, мы выполняем

sudo ufw allow 'Apache Secure'

Хорошо. Теперь проверьте статус службы

sudo systemctl status apache2

Далее — создайте простой виртуальный сервер для тестирования 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

Поместите туда

<html>
    <head>
        <title>Welcome to reg.homelab!</title>
    </head>
    <body>
        <h1>Успех! Виртуальный хост reg.homelab работает!</h1>
    </body>
</html>

затем

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

и поместите туда

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

затем отключите стандартный сайт, включите этот и проверьте, как мы себя чувствуем

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

увидите что-то вроде этого?

AH00558: apache2: Не удалось надежно определить полное доменное имя сервера, используется 127.0.1.1. Установите директиву 'ServerName' глобально, чтобы подавить это сообщение

затем

sudo nano /etc/apache2/apache2.conf

добавьте в конец:

ServerName reg.homelab

И это ещё не конец! Теперь нужно убрать попытку привязки порта 80

sudo nano /etc/apache2/ports.conf

поместите туда

Listen 3030
...
Listen 443

Теперь

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

Хорошо! Теперь перейдите по адресу :3080

Шаг 2 — преобразование этого сайта в небезопасный обратный прокси к Gitea

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

поместите туда

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

Проверьте конфигурацию

sudo apache2ctl configtest

Добавьте некоторые модули Apache и перезапустите Apache

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

Хорошо, теперь перейдите по адресу или выполните curl

# Да, это всё ещё http, но на порту 443
curl http://localhost:443
http://<Server_IP_Address>:443/

Шаг 3 — самоподписанный корневой CA и сертификат сайта

SweetHome-RootCA.

CANAME=MostImportant-RootCA

# необязательно, создайте директорию
mkdir $CANAME
cd $CANAME

# сгенерируйте AES-зашифрованный приватный ключ
openssl genrsa -aes256 -out $CANAME.key 4096

# создайте сертификат, 1826 дней = 5 лет
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'

# создайте сертификат для сервиса
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'

# создайте файл v3 ext для свойств 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
На машинах, подключающихся к gitea / реестру

Зарегистрируйте корневой сертификат на Linux:

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

Зарегистрируйте корневой сертификат на Windows:

  • Дважды щелкните файл MostImportant-RootCA.crt
  • Импортируйте в локального пользователя
  • Выберите Доверенный корневой CA.
  • При запросе о вводе непроверенного сертификата — нажмите да

Когда git pull на Windows говорит о

Не удается разрешить "unable to get local issuer certificate...

вы можете сообщить git, чтобы он использовал слой сетевого уровня Windows, выполнив

git config --global http.sslbackend schannel

Шаг 4 — защита прокси-сервера с помощью самоподписанного сертификата

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

Создайте самоподписанный сертификат, если вы этого ещё не сделали в шаге 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

Или просто возьмите его из предыдущего шага

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

Снова откройте конфигурацию виртуального хоста

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

Добавьте внизу раздел с SSL и сертификатами

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

Проверьте конфигурацию, перезапустите сервер, проверьте статус и перейдите к нашему Gitea через SSL

sudo apache2ctl configtest
sudo systemctl restart apache2
sudo systemctl status apache2

# перейдите: http://<Server_IP_Address>:443/
# или
curl -k -v https://localhost

браузер предупредит о самоподписанном сертификате

Ваше соединение не является приватным
Взломщики могут пытаться украсть ваши данные с reg.homelab (например, пароли, сообщения или кредитные карты). Узнайте больше
NET::ERR_CERT_AUTHORITY_INVALID

Но мы сейчас проигнорируем это, пока не используем Let’s Encrypt.

Теперь тестирование k8s

Выполним некоторые DNS-записи…

На каждом узле k8s:

sudo nano /etc/hosts

и добавьте туда

192.168.18.200 gitea.homelab
192.168.18.200 reg.homelab

Корневой CA

На каждом узле k8s:

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

И перезапустите сейчас

Создание секрета с учетными данными реестра

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

или

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

Новый образ Docker и развертывание 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

Теперь nano alp2.yaml, файл доступен для скачивания

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

Здесь этот файл доступен для скачивания: Затем создание этого развертывания

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

Очистка

kubectl delete -f alp2.yaml

Полезные ссылки