Ноутбук разработчика попадает на приватный экземпляр RDS через VPN сотрудников, а приложение на EC2 вообще не может подключиться. Это не сломанное развёртывание. У ноутбука есть туннель, который экземпляр EC2 никогда не наследует, а «приватный» в RDS означает, что у базы данных нет публичной конечной точки, а не то, что людские пользователи VPN — единственные разрешённые вызывающие. Приложению нужен собственный разрешённый путь, собственные отношения с группой безопасности и собственная идентичность в базе данных, и порядок выбора этих трёх экономит большую часть отладки. Сначала решите маршрут, затем разрешения, а затем проверяйте из развёрнутой среды, а не со своего стола.

VPN ноутбука — не путь приложения

Что бы VPN сотрудников ни делал для людей, для экземпляра он не делает ничего, если только этот экземпляр явно не является частью того же сетевого пути. Экземпляр EC2 в приватной подсети достигает RDS через маршрутизацию VPC, группы безопасности и сетевые ACL. Он не наследует человеческий туннель, человеческую сессию или человеческие учётные данные и не должен: подключение приложений без сопровождения и удалённый доступ сотрудников должны работать независимо.

Эта независимость — преимущество. Когда VPN недоступен, приложение продолжает работать. Когда приложение ведёт себя неправильно, никто не теряет удалённый доступ. Проекты, которые сливают оба в один путь, обычно обнаруживаются во время инцидента, в худший возможный момент.

Решение 1: та же VPC, прямой путь

Когда приложение и база данных находятся в одной VPC с прямой маршрутизацией и без промежуточного устройства инспекции между ними, путь прост, а ссылка на группу безопасности — самый мощный доступный инструмент. Дайте приложению собственную группу, а затем разрешите порт базы данных из этой группы, а не из диапазона адресов:

aws ec2 authorize-security-group-ingress --group-id sg-0db123   --protocol tcp --port 5432 --source-group sg-0app456

aws rds describe-db-instances --db-instance-identifier prod-db   --query 'DBInstances[0].{Endpoint:Endpoint.Address,Port:Endpoint.Port,Public:PubliclyAccessible,Groups:VpcSecurityGroups}'

Порт приведён для примера и должен соответствовать движку. Ссылка на группу разрешает трафик от экземпляров приложения; она не копирует их правила и не создаёт вход в базу данных. Две отдельные проблемы, два отдельных исправления.

Затем проверьте остальную часть пути, а не останавливайтесь на только что добавленном правиле. Исходящая политика приложения, полный набор групп, привязанных к базе данных, таблицы маршрутизации подсети и любые сетевые ACL — всё должно согласовываться. Правила групп безопасности сохраняют состояние, тогда как пользовательский сетевой ACL должен разрешать запрос и обратный трафик отдельными правилами, включая эфемерные порты. Новое узкое правило для базы данных также не отменяет более старое широкое разрешение, которое уже было привязано.

Решение 2: другая VPC или другая учётная запись

Если приложение находится в другой VPC, владельцы сети выбирают поддерживаемое частное соединение: peering, транзитный проект или схему общей VPC. Тогда должны существовать оба направления маршрутизации, разрешение имён должно работать для конечной точки RDS, а источник, который оценивает политика базы данных, должен совпадать с тем, что действительно приходит. Совпадающие имена учётных записей или общие отношения выставления счетов не дают ничего из этого.

Ссылка на группу безопасности — это та часть, которая меняется. Она работает в нескольких проектах частных соединений, но перестаёт работать в тот момент, когда промежуточное устройство перезаписывает источник или завершает соединение, потому что тогда база данных видит промежуточное устройство, а не вашу группу приложения. Сценарии VPC для RDS отделяют доступ внутри одной VPC от других схем, и стоит проверить вашу конкретную топологию на их фоне, прежде чем предполагать, что стиль правила переносится.

Не решайте проблему отсутствующего маршрута, делая базу данных общедоступной. Это другое решение о раскрытии с другим владельцем, и обычно его предлагает тот, кто дальше всех от последствия.

Решение 3: какую идентичность принимает база данных

Сетевой доступ и аутентификация в базе данных — отдельные слои, и их смешение порождает самые вводящие в заблуждение ошибки. Роль экземпляра — это идентичность AWS для вызова API AWS. Это не пользователь базы данных. Аутентификация в базе данных через IAM — поддерживаемая функция там, где движок и конфигурация это позволяют, и она по-прежнему является сопоставлением с пользователем базы данных, а не его заменой.

Используйте имя конечной точки RDS в конфигурации приложения вместо адреса, полученного из одного поиска. Переключение при отказе Multi-AZ меняет адрес за этим именем, и приложение, привязанное к IP, откажет именно в тот момент, когда оно нужно. Оставьте проверку TLS движка включённой, вместо того чтобы отключать её ради исчезновения ошибки, потому что сбой проверки говорит вам что-то о конечной точке, до которой вы дошли.

Затем предоставьте учётной записи базы данных минимум, необходимый приложению, в той схеме, которую оно действительно использует. Эта работа скучна, она поддаётся аудиту, и именно о ней спросит разбор инцидента.

Проверьте из развёрнутой среды

Тестируйте с экземпляра или из задачи, работающей с той же группой, подсетью и ролью. Четыре сбоя выглядят с ноутбука одинаково и легко различаются оттуда: имя, которое не разрешается, соединение, которое завершается по тайм-ауту, сбой проверки TLS и отклонённый вход в базу данных. Каждый указывает на другую границу, и менять раскрытие базы данных, не зная, какой именно у вас, — это догадки.

psql "host=prod-db.abc123.eu-west-1.rds.amazonaws.com port=5432 dbname=app sslmode=verify-full" -c 'select 1'

Если соединение успешно с экземпляра и неудачно с вашего стола, путь приложения в порядке, и исправлять нужно ваш доступ. Если оно неудачно с обоих, начните с проверок группы и маршрута выше, а не с учётных данных. Это единственное сравнение предотвращает большую часть суеты, которую создают эти заявки.

Похожие статьи