Как сделать 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.
Решение на основе собственных сервисов AWS
Мой подход, который я рекомендую для использования в производственных средах, основан на балансировщике нагрузки приложений AWS (ALB). Nginx можно пропустить, поскольку ALB предоставляет ту же функциональность, что и Nginx, для всех основных сценариев и не требует дополнительной настройки или автоматизации.
AWS ALB указывает на целевую группу IP-адресов, которая содержит набор частных IP-адресов OpenSearch, а кластер OpenSearch должен быть настроен в режиме VPC. В этой конфигурации также важно настроить перенаправление HTTP на уровне ALB, как показано на изображении ниже.
Цели ALB также должны требовать настройки проверок работоспособности, поскольку без них IP-адреса OpenSearch будут удалены из пулов IP-адресов. Помните, что http-код 401
необходимо добавить в список успешных кодов проверки работоспособности, когда вы используете базовую HTTP-аутентификацию.
Однократной настройки целевой группы 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.< /п>
Особенности безопасности
В этой статье безопасность не рассматривается, но я не могу выделить два критических момента:
- Не забудьте правильно настроить группы безопасности AWS; вам нужно разрешить только необходимый порт (в нашем примере 443). Используйте AWS Trust Advisor, чтобы заблокировать все ненужные порты.
- Было бы неплохо иметь разных пользователей с разными типами прав при использовании базовой аутентификации OpenSearch HTTP. Не используйте пользователя-администратора с полным доступом к кластеру. Было бы предпочтительнее иметь несколько пользователей, каждый из которых имеет доступ к подмножеству индексов OpenSearch. Вы можете хранить всю информацию о паролях в AWS Secret Manager для упрощения управления паролями. ол>
- Можно избежать использования кластера Nginx высокой доступности в вашей архитектуре. Это сэкономит вам деньги и время на настройку.
- Вместо использования таких инструментов, как Terraform или Pulumi, используйте лямбда-функцию, чтобы поддерживать актуальность целевой группы вашего ALB. Крайне важно регулярно проверять достоверность целевого пула.
- Не забывайте о безопасности, когда дело доходит до реализации. Обратите внимание на подсети AWS, группы безопасности и пользователей OpenSearch.
- Используйте как можно больше собственных компонентов AWS. Все их можно настроить с помощью инструментов IaC, таких как Terraform, Pulumi или CloudFormation.
- Хотя инстансы EC2 можно настроить с помощью инструментов IaC, время подготовки, настройки и запуска существенно дольше, чем при использовании чистого AWS ALB. ол>