Как сделать AWS OpenSearch общедоступным без прокси-сервера nginx

Как сделать AWS OpenSearch общедоступным без прокси-сервера nginx

3 января 2024 г.

О чем мы здесь говорим?

В рамках своей работы я консультирую множество клиентов, использующих AWS. Многие из них создают сложные системы на базе сервисов AWS. AWS OpenSearch обычно включается в системный ландшафт, чтобы охватить широкий спектр различных бизнес-сценариев, для некоторых из которых требуется доступный через Интернет кластер с базовой аутентификацией HTTP. AWS не предоставляет эту возможность «из коробки»; поэтому в этой статье я покажу, как использовать собственные сервисы AWS для публикации кластера OpenSearch в Интернете.

Текущие ограничения

Кластер OpenSearch можно развернуть в двух режимах со следующими функциями

| на базе VPC | Общественное достояние | |----|----| | Только частная конечная точка в следующем формате: https://vpc-имя-домена | Публичная конечная точка в следующем формате: https://имя-домена-поиска | | Вкладка «Состояние кластера» не содержит информации о сегментах, а вкладка «Индексы» отсутствует. | Доступна вся информация о работоспособности кластера и индексах | | Безопасность основана на группах безопасности AWS | Безопасность основана на политиках доступа на основе IP | | Панели мониторинга доступны только из VPC, и для их доступа требуется VPN или что-то еще | Панели мониторинга доступны публично для диапазона IP-адресов, настроенного с помощью политик доступа на основе IP |

В настоящее время AWS не предоставляет готовых способов публикации кластера OpenSearch с базовой HTTP-аутентификацией в Интернете для любого диапазона IP-адресов (например: 0.0.0.0/0). Можно настроить политику AWS IAM, чтобы разрешить определенный диапазон IP-адресов или использовать общедоступный открытый кластер с авторизацией SAML; однако это не подходит для таких случаев, как мобильные клиенты или ТВ-приставки, где клиент может иметь любой непредсказуемый IP-адрес, а команда разработчиков не имеет возможности для реализации SAML.

Возможно, в будущем появится что-то вроде прокси-сервера RDS, но пока у AWS нет публичных планов относительно этой функции.

Решения

Официальное предложение AWS на базе Nginx

В документации AWS рекомендуется использовать обратный прокси-сервер на основе высокодоступного кластера EC2 Nginx. Это хороший подход, но он требует много дополнительных усилий для обслуживания Nginx, что было бы неудобно в случае большого количества OpenSearch. Кроме того, поскольку AWS не предоставляет высокодоступный Nginx в качестве услуги, вы не сможете настроить свою инфраструктуру с помощью одного инструмента, такого как Terraform, Pulumi или CloudFormation.

https://docs.aws.amazon.com/solutions/latest/centralized-logging-with-opensearch/access-proxy-1.html

Решение на основе собственных сервисов AWS

Мой подход, который я рекомендую для использования в производственных средах, основан на балансировщике нагрузки приложений AWS (ALB). Nginx можно пропустить, поскольку ALB предоставляет ту же функциональность, что и Nginx, для всех основных сценариев и не требует дополнительной настройки или автоматизации.

The basic architecture based on AWS Application load balancer

AWS ALB указывает на целевую группу IP-адресов, которая содержит набор частных IP-адресов OpenSearch, а кластер OpenSearch должен быть настроен в режиме VPC. В этой конфигурации также важно настроить перенаправление HTTP на уровне ALB, как показано на изображении ниже.

AWS Application load balancer listeners configuration

Цели ALB также должны требовать настройки проверок работоспособности, поскольку без них IP-адреса OpenSearch будут удалены из пулов IP-адресов. Помните, что http-код 401 необходимо добавить в список успешных кодов проверки работоспособности, когда вы используете базовую HTTP-аутентификацию.

AWS target group health checks' configuration

Однократной настройки целевой группы ALB недостаточно. Любое изменение кластера OpenSearch может привести к изменению IP-адреса, поэтому, чтобы гарантировать, что целевые группы всегда содержат все IP-адреса OpenSearch, пул IP-адресов должен поддерживаться простой функцией Lambda, которая запускается один раз в час и проверяет, что все IP-адреса OpenSearch присутствуют и актуальны. Полный код функции AWS приведен ниже.

import boto3
import socket

def lambda_handler(event, context):
    # Initialize AWS clients
    elasticsearch = boto3.client('es')
    elbv2 = boto3.client('elbv2')

    # Retrieve target group ARN and OpenSearch domain name from event
    target_group_arn = event.get('targetGroupARN')
    open_search_domain_name = event.get('openSearchDomainName')

    # Describe OpenSearch cluster to retrieve DNS endpoint
    response = elasticsearch.describe_elasticsearch_domain(DomainName=open_search_domain_name)
    opensearch_dns = response['DomainStatus']['Endpoints']['vpc']

    # Resolve DNS to get IP addresses
    opensearch_ips = socket.gethostbyname_ex(opensearch_dns)[2]
    print(f"OpenSearch IPs are: {opensearch_ips}")

    # Describe existing IPs in the EC2 target group
    target_group_info = elbv2.describe_target_health(TargetGroupArn=target_group_arn)
    existing_ips = [target['Target']['Id'] for target in target_group_info['TargetHealthDescriptions']]

    # Compare IPs to determine new ones and remove old ones
    ips_to_add = list(set(opensearch_ips) - set(existing_ips))
    ips_to_remove = list(set(existing_ips) - set(opensearch_ips))

    # Update the target group
    if ips_to_add:
        elbv2.register_targets(TargetGroupArn=target_group_arn, Targets=[{'Id': ip} for ip in ips_to_add])
    if ips_to_remove:
        elbv2.deregister_targets(TargetGroupArn=target_group_arn, Targets=[{'Id': ip} for ip in ips_to_remove])

    return {
        'statusCode': 200,
        'body': 'Updated EC2 target group with OpenSearch IPs.'
    }

Лямбда-функция может быть развернута в режиме VPC. Это более безопасно, но не обязательно. Вначале вы можете предоставить только разрешения es:* для вашей роли IAM Lambda, как показано в фрагменте кода ниже.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/test-user"
        ]
      },
      "Action": [
        "es:*"
      ],
      "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*"
    }
  ]
}

По ряду причин подключаться к кластеру OpenSearch с плавающим IP-адресом неудобно. Все современные архитектуры используют DNS для сокрытия чистого IP-адреса. Мы сделаем то же самое через AWS Route53.

К сожалению, DNS-записи Route53 недостаточно, поскольку ALB будет отображать проблемы, связанные с несоответствием сертификатов HTTP. Мы должны сгенерировать действительный сертификат TLS и прикрепить его к прослушивателю ALB, чтобы избежать проблем с соединением HTTPS при использовании DNS. Менеджер сертификатов AWS можно использовать для выдачи приобретенного сертификата, но я отдавайте предпочтение бесплатным сертификатам Let’s Encrypt. AWS изначально не поддерживает интеграцию Let's Encrypt и диспетчера сертификатов, поэтому я давно создал AWS Lambda, которая автоматически выдает и обновляет сертификаты TLS, и предлагаю использовать ее в предложенном дизайне. Исходники этой Lambda можно найти по адресу https://github.com/kvendingoldo/aws-letsencrypt-lambda.< /п>

The final solution design

Особенности безопасности

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

  1. Не забудьте правильно настроить группы безопасности AWS; вам нужно разрешить только необходимый порт (в нашем примере 443). Используйте AWS Trust Advisor, чтобы заблокировать все ненужные порты.
  2. Было бы неплохо иметь разных пользователей с разными типами прав при использовании базовой аутентификации OpenSearch HTTP. Не используйте пользователя-администратора с полным доступом к кластеру. Было бы предпочтительнее иметь несколько пользователей, каждый из которых имеет доступ к подмножеству индексов OpenSearch. Вы можете хранить всю информацию о паролях в AWS Secret Manager для упрощения управления паролями.
  3. Сводка

    1. Можно избежать использования кластера Nginx высокой доступности в вашей архитектуре. Это сэкономит вам деньги и время на настройку.
    2. Вместо использования таких инструментов, как Terraform или Pulumi, используйте лямбда-функцию, чтобы поддерживать актуальность целевой группы вашего ALB. Крайне важно регулярно проверять достоверность целевого пула.
    3. Не забывайте о безопасности, когда дело доходит до реализации. Обратите внимание на подсети AWS, группы безопасности и пользователей OpenSearch.
    4. Используйте как можно больше собственных компонентов AWS. Все их можно настроить с помощью инструментов IaC, таких как Terraform, Pulumi или CloudFormation.
    5. Хотя инстансы EC2 можно настроить с помощью инструментов IaC, время подготовки, настройки и запуска существенно дольше, чем при использовании чистого AWS ALB.
    6. Полезные ссылки

      1. Прокси-сервер доступа AWS OpenSearch< /ли>
      2. AWS Давайте зашифруем лямбда

      3. Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE