TLS Passthrough#

Функция TLS Passthrough позволяет ANIC принимать TLS-соединения на порту 443 и направлять их на соответствующие серверы-бекенды без расшифровки. Маршрутизация осуществляется на основе SNI (Server Name Indication), что позволяет клиентам указывать имя сервера (например, example.com) во время SSL-рукопожатия. При этом ANIC продолжает обрабатывать обычный HTTPS-трафик на том же порту 443, терминируя TLS-соединения с использованием сертификатов и ключей, заданных в ресурсах Ingress или VirtualServer.

Ниже приведен пример использования ресурса TransportServer для настройки балансировки нагрузки в режиме TLS Passthrough. В примере будет развернуто бекенд-приложение (Secure App), прослушивающее TLS-трафик на порту 8443. ANIC будет маршрутизировать соединения к этому приложению с помощью TransportServer.

О Secure App#

Secure App — это pod с Angie (не путать с pod-ом ANIC, который также использует Angie), настроенный на обслуживание HTTPS-трафика на порту 8443 для хоста app.example.com. Для терминации TLS используются самоподписанный TLS-сертификат и ключ. Приложение отвечает на HTTPS-запросы клиентов простым текстовым сообщением:

hello from pod <имя pod-а>

Предварительные действия#

  1. Установите ANIC.

  2. Убедитесь, что развернуто определение пользовательского ресурса для TransportServer.

  3. Запустите ANIC с параметрами -enable-custom-resources и -enable-tls-passthrough, чтобы включить поддержку TLS Passthrough.

  4. Сохраните публичный IP-адрес ANIC в переменной оболочки:

    $ IC_IP=XXX.YYY.ZZZ.III
    
  5. Сохраните HTTPS-порт ANIC в переменной оболочки:

    $ IC_HTTPS_PORT=<номер порта>
    

Настройка TLS Passthrough#

  1. Разверните Secure App:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: secure-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: secure-app
      template:
        metadata:
          labels:
            app: secure-app
        spec:
          containers:
            - name: secure-app
              image: angiesoftware/angie-hello:plain-text
              ports:
                - containerPort: 8443
              volumeMounts:
                - name: secret
                  mountPath: /etc/angie/ssl
                  readOnly: true
                - name: config-volume
                  mountPath: /etc/angie/conf.d
          volumes:
            - name: secret
              secret:
                secretName: app-tls-secret
            - name: config-volume
              configMap:
                name: secure-config
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: secure-app
    spec:
      ports:
        - port: 8443
          targetPort: 8443
          protocol: TCP
          name: https
      selector:
        app: secure-app
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: secure-config
    data:
      app.conf: |-
        server {
          listen 8443 ssl;
          listen [::]:8443 ssl;
    
          server_name app.example.com;
    
          ssl_certificate /etc/angie/ssl/tls.crt;
          ssl_certificate_key /etc/angie/ssl/tls.key;
    
          default_type text/plain;
    
          location / {
            return 200 "hello from pod $hostname\n";
          }
        }
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: app-tls-secret
    data:
      tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURGRENDQWZ3Q0NRQ3EzQWxhdnJiaWpqQU5CZ2txaGtpRzl3MEJBUXNGQURCTU1Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhGakFVQmdOVkJBY01EVk5oYmlCR2NtRnVZMmx6WTI4eEdEQVdCZ05WQkFNTQpEMkZ3Y0M1bGVHRnRjR3hsTG1OdmJUQWVGdzB5TURBek1qTXlNekl3TkROYUZ3MHlNekF6TWpNeU16SXdORE5hCk1Fd3hDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJREFKRFFURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWoKYVhOamJ6RVlNQllHQTFVRUF3d1BZWEJ3TG1WNFlXMXdiR1V1WTI5dE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTJCRXhZR1JPRkhoN2VPMVlxeCtWRHMzRzMrVEhyTEZULzdEUFFEQlkza3pDCi9oZlprWCt3OW1NNkQ1RU9uK2lpVlNhUWlQMm1aNFA3N29pR0dmd3JrNjJ0eEQ5cHphODM5NC9aSjF5Q0dXZ1QKK2NWUEVZbkxjQktzSTRMcktJZ21oWVIwUjNzWWRjR1JkSXJWUFZlNUVUQlk1Z1U0RGhhMDZOUEIraitmK0krWgphWGIvMlRBekJhNHozMWpIQzg2amVQeTFMdklGazFiY3I2cSsxRGR5eklxcWxkRDYvU3Q4Q2t3cDlOaDFCUGFhCktZZ1ZVd010UVBib2s1cFFmbVMrdDg4NHdSM0dTTEU4VkxRbzgyYnJhNUR3emhIamlzOTlJRGhzbUt0U3lWOXMKaWNJbXp5dHBnSXlhTS9zWEhRQU9KbVFJblFteWgyekd1WFhTQ0lkRGtRSURBUUFCTUEwR0NTcUdTSWIzRFFFQgpDd1VBQTRJQkFRQ0tsVkhOZ1k5VHZLaW9Xb0tvdllCdnNRMmYrcmFOOEJwdWNDcnRvRm15NUczcGIzU2lPTndaCkF2cnhtSm4vR3lsa3JKTHBpQVA1eUNBNGI2Y2lYMnRGa3pQRmhJVFZKRTVBeDlpaEF2WWZwTUFSdWVqM29HN2UKd0xwQk1iUnlGbHJYV29NWUVBMGxsV0JueHRQQXZYS2Y4SVZGYTRSSDhzV1JJSDB4M2hFdjVtQ3VUZjJTRTg0QwpiNnNjS3Z3MW9CQU5VWGxXRVZVYTFmei9rWWZBa1lrdHZyV2JUcTZTWGxodXRJYWY4WEYzSUMrL2x1b3gzZThMCjBBcEFQVE5sZ0JwOTkvcXMrOG9PMWthSmQ1TmV6TnlJeXhSdUtJMzlDWkxuQm9OYmkzdlFYY1NzRCtYU2lYT0cKcEVnTjNtci8xRms4OVZMSENhTnkyKzBqMjZ0eWpiclcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
      tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRRFlFVEZnWkU0VWVIdDQKN1Zpckg1VU96Y2JmNU1lc3NWUC9zTTlBTUZqZVRNTCtGOW1SZjdEMll6b1BrUTZmNktKVkpwQ0kvYVpuZy92dQppSVlaL0N1VHJhM0VQMm5OcnpmM2o5a25YSUlaYUJQNXhVOFJpY3R3RXF3amd1c29pQ2FGaEhSSGV4aDF3WkYwCml0VTlWN2tSTUZqbUJUZ09GclRvMDhINlA1LzRqNWxwZHYvWk1ETUZyalBmV01jTHpxTjQvTFV1OGdXVFZ0eXYKcXI3VU4zTE1pcXFWMFByOUszd0tUQ24wMkhVRTlwb3BpQlZUQXkxQTl1aVRtbEIrWkw2M3p6akJIY1pJc1R4VQp0Q2p6WnV0cmtQRE9FZU9LejMwZ09HeVlxMUxKWDJ5SndpYlBLMm1Bakpveit4Y2RBQTRtWkFpZENiS0hiTWE1CmRkSUloME9SQWdNQkFBRUNnZ0VCQUxYaW16ODZrT1A0bkhBcTFPYVEyb2l3dndhQTczbTNlUytZSm84eFk4NFcKcmxyNXRzUWR5dGxPcEhTd05yQjBSQnNNTU1XeFNPQ0JJWlltUlVVZ200cGd2Uk9rRWl2OG9VOThQMkE4SnFTKwprWHBFRjVCNi84K2pXRmM0Z1Q4SWhlMEZtR0VJQllvelhYL08wejBsV0h4WXg2MHluWUoycU9vS1FKT3A5YjlsCmpiUVBkaC9mN2ErRWF0RzZNUFlrNG5xSEY3a0FzcmNsRXo2SGUvaEx6NmRkSTJ1N2RMRjB6QlN0QjM5WDFRZysKZ1JzTittOXg1S1FVTXYxMktvajdLc2hEelozOG5hSjd5bDgycGhBV1lGZzBOZHlzRlBRbmt0WmlNSUxOblFjNwpOeUt0cHNQaUxIRE9ha05hdEZLU2lOaUJrUk1lY1ZUMlJNMzMzUG54bFVFQ2dZRUEvYTY5MEEralU4VFJNbVZyCk4vRnlYWkxYa1c5b2NxVjBRbTA0TDMrSExybFNCTlRWSzk2U1pVT203VjViTzIxNmd4S2dJK3IwYm5kdE5GTUQKLzFncDhsdlJNcUlIeGZTeUo4SHpsSzViT0lnaUpxRGhzK3BKWTZmLytIVzZ1QkZyN3NGS3lxbVlIQlA0SC9BdApsT3lLeEVjMHFXazFlT2tCMWNNSGx0WDRwemtDZ1lFQTJncDhDVDVYWjNMSWRQN2M1SHpDS1YwczBYS1hGNmYyCkxzclhPVlZaTmJCN1NIS1NsOTBIU2VWVGx3czdqSnNxcC9yWFY2aHF0eUdEaTg4aTFZekthcEF6dXl3b0U3TnEKMUJpd2ZYSURQeTlPNUdGNXFYNXFUeENzSWNIcmo2Z21XMEZVQWhoS1lQcDRxd1JMdzFMZkJsd3U1VmhuN3I3ego0SkZBTEFpdlp4a0NnWUJicnpuKzVvZjdFSmtqQTdDYWlYTHlDczVLUzkrTi8rcGl6NktNMkNSOWFKRVNHZkhwClp3bTErNXRyRXIwYVgxajE0bGRxWTlKdjBrM3ZxVWs2a2h5bThUUk1mbThjeG5GVkdTMzF3SVpMaWpmOWlndkkKd0paQnBFaEkvaE83enVBWmJGYWhwR1hMVUJSUFJyalNxQ01IQ1UwcEpWTWtIZUtCNVhqcXRPNm5VUUtCZ0NJUAp6VHlzYm44TW9XQVZpSEJ4Uk91dFVKa1BxNmJZYUU3N0JSQkIwd1BlSkFRM1VjdERqaVh2RzFYWFBXQkR4VEFrCnNZdFNGZ214eEprTXJNWnJqaHVEbDNFLy9xckZOb1VYcmtxS2l4Tk4wcWMreXdDOWJPSVpHcXJUWG5jOHIzRkcKRFZlZWI5QWlrTU0ya3BkYTFOaHJnaS8xMVphb1lmVE0vQmRrNi9IUkFvR0JBSnFzTmFZYzE2clVzYzAzUEwybApXUGNzRnZxZGI3SEJyakVSRkhFdzQ0Vkt2MVlxK0ZWYnNNN1FTQVZ1V1llcGxGQUpDYzcrSEt1YjRsa1hRM1RkCndSajJLK2pOUzJtUXp1Y2hOQnlBZ1hXVnYveHhMZEE3NnpuWmJYdjl5cXhnTVVjTVZwZGRuSkxVZm9QVVZ1dTcKS0tlVVU3TTNIblRKUStrcldtbUxraUlSCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
    

    Примените настройки:

    $ kubectl apply -f secure-app.yaml
    
  2. Настройте балансировку нагрузки.

    Создайте ресурс TransportServer:

    apiVersion: k8s.angie.software/v1alpha1
    kind: TransportServer
    metadata:
      name: secure-app
    spec:
      listener:
        name: tls-passthrough
        protocol: TLS_PASSTHROUGH
      host: app.example.com
      upstreams:
        - name: secure-app
          service: secure-app
          port: 8443
      action:
        pass: secure-app
    

    Примените настройки:

    $ kubectl apply -f transport-server-passthrough.yaml
    
  3. Проверьте успешность применения конфигурации, просмотрев события TransportServer:

    $ kubectl describe ts secure-app
    

    Вывод команды может выглядеть так:

    Events:
      Type    Reason          Age   From                      Message
      ----    ------          ----  ----                      -------
      Normal  AddedOrUpdated  9s    anic                      Configuration for default/secure-app was added or updated
    
  4. Проверьте доступ к Secure App с помощью curl. Используйте параметр --insecure, чтобы отключить проверку сертификатов (так как используется самоподписанный сертификат), а также --resolve, чтобы указать IP-адрес и HTTPS-порт ANIC для домена app.example.com:

    $ curl --resolve app.example.com:$IC_HTTPS_PORT:$IC_IP https://app.example.com:$IC_HTTPS_PORT --insecure
    

    Ожидаемый ответ:

    hello from pod secure-app-d986bcf6b-jwm2s