Поделиться через


Фронтенд MTLS с Шлюзом приложений для контейнеров – API Шлюза

Этот документ помогает настроить пример приложения, использующего следующие ресурсы из API шлюза. Предоставлены следующие шаги:

Общие сведения

Взаимная безопасность уровня транспорта (MTLS) — это процесс, основанный на сертификатах для шифрования связи и идентификации клиентов в службе. Это позволяет Шлюзу приложений для контейнеров повысить уровень безопасности, только доверяя подключениям от устройств, прошедших проверку подлинности.

См. следующий рисунок:

Схема, демонстрирующая процесс MTLS на интерфейсе Шлюза приложений для контейнеров.

В потоке допустимых сертификатов клиента отображается клиент, который представляет сертификат в интерфейсе Шлюз приложений для контейнеров. Шлюз приложений для контейнеров определяет, что сертификат действителен, и перенаправляет запрос на целевой сервер. Ответ в конечном итоге возвращается клиенту.

В процессе отзыва клиентских сертификатов показан клиент, который представляет отозванный сертификат на фронтенд Шлюза приложений для контейнеров. Шлюз приложений для контейнеров определяет, что сертификат недействителен, и предотвращает проксирование запроса к клиенту. Клиент получит недопустимый запрос HTTP 400 и соответствующую причину.

Предварительные условия

  1. Если вы используете стратегию развертывания BYO, убедитесь, что вы настроили Шлюз приложений для ресурсов контейнеров и контроллера балансировки нагрузки.

  2. Если вы используете стратегию управляемого развертывания ALB, подготовьте контроллер ALB и подготовите Шлюз приложений для ресурсов контейнеров с помощью настраиваемого ресурса ApplicationLoadBalancer.

  3. Развертывание примера HTTP-приложения:

    Примените следующий файл deployment.yaml на свой кластер, чтобы создать пример веб-приложения и развернуть тестовые секреты для демонстрации взаимной аутентификации (mTLS).

    kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/https-scenario/ssl-termination/deployment.yaml
    

    Эта команда создает следующее в кластере:

    • Пространство имен с именем test-infra
    • Одна служба, вызываемая echotest-infra в пространстве имен
    • Одно развертывание, названное echo в пространстве имен test-infra
    • Один секрет, называемый listener-tls-secret, в пространстве имен test-infra

Создание сертификатов

В этом примере мы создадим корневой сертификат и выпустим сертификат клиента из корневого сертификата. Если у вас уже есть корневой сертификат и сертификат клиента, можно пропустить эти действия.

Создание закрытого ключа для корневого сертификата

openssl genrsa -out root.key 2048

Создание корневого сертификата

openssl req -x509 -new -nodes -key root.key -sha256 -days 1024 -out root.crt -subj "/C=US/ST=North Dakota/L=Fargo/O=Contoso/CN=contoso-root"

Создание закрытого ключа для сертификата клиента

openssl genrsa -out client.key 2048

Создание запроса подписи сертификата для сертификата клиента

openssl req -new -key client.key -out client.csr -subj "/C=US/ST=North Dakota/L=Fargo/O=Contoso/CN=contoso-client"

Создание сертификата клиента, подписанного корневым сертификатом

openssl x509 -req -in client.csr -CA root.crt -CAkey root.key -CAcreateserial -out client.crt -days 1024 -sha256

Развертывание необходимых ресурсов API шлюза

Создание шлюза

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway-01
  namespace: test-infra
  annotations:
    alb.networking.azure.io/alb-namespace: alb-test-infra
    alb.networking.azure.io/alb-name: alb-test
spec:
  gatewayClassName: azure-alb-external
  listeners:
  - name: mtls-listener
    port: 443
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: Same
    tls:
      mode: Terminate
      certificateRefs:
      - kind : Secret
        group: ""
        name: listener-tls-secret
EOF

Примечание.

Когда контроллер ALB создает шлюз приложений для ресурсов контейнеров в Azure Resource Manager, он использует следующее соглашение об именовании для внешнего ресурса: fe-<eight randomly generated characters>

Если вы хотите изменить имя ресурса фронтенда, созданного в Azure, рассмотрите возможность использования стратегии развертывания «принеси свой».

После создания ресурса шлюза убедитесь, что состояние является допустимым, прослушиватель запрограммирован, а адрес назначен шлюзу.

kubectl get gateway gateway-01 -n test-infra -o yaml

Пример выходных данных успешного создания шлюза:

status:
  addresses:
  - type: IPAddress
    value: xxxx.yyyy.alb.azure.com
  conditions:
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Valid Gateway
    observedGeneration: 1
    reason: Accepted
    status: "True"
    type: Accepted
  - lastTransitionTime: "2023-06-19T21:04:55Z"
    message: Application Gateway For Containers resource has been successfully updated.
    observedGeneration: 1
    reason: Programmed
    status: "True"
    type: Programmed
  listeners:
  - attachedRoutes: 0
    conditions:
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Listener is accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T21:04:55Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    name: https-listener
    supportedKinds:
    - group: gateway.networking.k8s.io
      kind: HTTPRoute

После создания шлюза создайте ресурс HTTPRoute.

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-route
  namespace: test-infra
spec:
  parentRefs:
  - name: gateway-01
  rules:
  - backendRefs:
    - name: echo
      port: 80
EOF

После создания ресурса HTTPRoute убедитесь, что маршрут принимается, а ресурс Шлюз приложений для контейнеров запрограммирован.

kubectl get httproute https-route -n test-infra -o yaml

Убедитесь, что состояние ресурса Шлюз приложений для контейнеров успешно обновлено.

status:
  parents:
  - conditions:
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: ""
      observedGeneration: 1
      reason: ResolvedRefs
      status: "True"
      type: ResolvedRefs
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Route is Accepted
      observedGeneration: 1
      reason: Accepted
      status: "True"
      type: Accepted
    - lastTransitionTime: "2023-06-19T22:18:23Z"
      message: Application Gateway For Containers resource has been successfully updated.
      observedGeneration: 1
      reason: Programmed
      status: "True"
      type: Programmed
    controllerName: alb.networking.azure.io/alb-controller
    parentRef:
      group: gateway.networking.k8s.io
      kind: Gateway
      name: gateway-01
      namespace: test-infra

Создайте секрет Kubernetes с помощью kubectl, содержащего цепочку сертификатов для сертификата клиента.

kubectl create secret generic ca.bundle -n test-infra --from-file=ca.crt=root.crt

Создание политики TLS для фронтенда

kubectl apply -f - <<EOF
apiVersion: alb.networking.azure.io/v1
kind: FrontendTLSPolicy
metadata:
  name: mtls-policy
  namespace: test-infra
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: gateway-01
    namespace: test-infra
    sectionNames:
    - mtls-listener
  default:
    verify:
      caCertificateRef:
        name: ca.bundle
        group: ""
        kind: Secret
        namespace: test-infra
EOF

После создания объекта FrontendTLSPolicy проверьте состояние объекта, чтобы убедиться, что политика действительна:

kubectl get frontendtlspolicy mtls-policy -n test-infra -o yaml

Пример выходных данных при допустимом создании объекта FrontendTLSPolicy:

status:
  conditions:
  - lastTransitionTime: "2023-06-29T16:54:42Z"
    message: Valid FrontendTLSPolicy
    observedGeneration: 1
    reason: Accepted
    status: "True"
    type: Accepted

Проверка доступа к приложению.

Теперь мы готовы отправить трафик нашему примерному приложению через полное доменное имя, назначенное фронтенду. Чтобы получить полное доменное имя, используйте следующую команду:

fqdn=$(kubectl get gateway gateway-01 -n test-infra -o jsonpath='{.status.addresses[0].value}')

Обращение к FQDN вашего фронтенда с помощью curl без использования клиентского сертификата.

curl --insecure https://$fqdn/

Обратите внимание, что ответ оповещает, что сертификат является обязательным.

curl: (56) OpenSSL SSL_read: OpenSSL/1.1.1k: error:1409445C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required, errno 0

Curl полное доменное имя, представляющее созданный клиентский сертификат.

curl --cert client.crt --key client.key --insecure https://$fqdn/

Обратите внимание, что ответ получен от серверной службы за Шлюзом приложений для контейнеров.

Поздравляем, вы установили контроллер ALB, развернули серверное приложение, прошли проверку подлинности через сертификат клиента и вернули трафик из серверной службы через Шлюз приложений для контейнеров.