Невозможно подключиться к экземпляру AWS VPC RDS (mysql или postgres)
(Я публикую этот вопрос по факту из-за времени, которое потребовалось, чтобы найти основную причину и решение. Есть также большая вероятность того, что другие люди столкнутся с той же проблемой)
У меня есть экземпляр RDS (в VPC), к которому я пытаюсь подключиться из приложения, работающего в классическом экземпляре EC2, подключенного через ClassicLink. Группы безопасности и DNS не проблема.
Я могу установить сокет-соединения с экземпляром RDS, но не могу подключиться с помощью инструментов CLI (psql, mysql и т. Д.) Или инструментов GUI БД, таких как toad или mysql workbench.
Прямые соединения через сокеты с telnet или nc приводят к тому, что TCP-соединения находятся в состоянии "ESTABLISHED" (вывод из netstat).
Соединения из CLI DB, инструментов GUI или приложений приводят к тайм-аутам и TCP-соединениям, которые застряли в состоянии "SYN".
ОБНОВЛЕНИЕ: основной причиной в моем случае была проблема с размером MTU и EC2 ClassicLink. Ниже я опубликовал некоторые общие сведения об устранении неполадок в ответе на случай, если другие люди столкнутся с аналогичными проблемами с подключением RDS.
1 ответ
Дополнительная информация для людей, которые могут столкнуться с подобными проблемами при попытке подключиться к RDS или RedShift:
1) Проверьте группы безопасности
Убедитесь, что группа безопасности для экземпляра RDS разрешает доступ из группы безопасности, к которой принадлежит исходный сервер (или его IP-адрес добавляется напрямую, если он является внешним по отношению к AWS). Группа безопасности, на которую вы должны обратить внимание, - это группа, указанная в атрибутах экземпляра RDS в пользовательском интерфейсе консоли RDS (называемая "группа безопасности").
ПРИМЕЧАНИЕ. Группы безопасности базы данных могут отличаться от групп безопасности AWS EC2. Если ваш экземпляр RDS находится в классическом / общедоступном EC2, вам следует проверить это в разделе "Группа безопасности базы данных" пользовательского интерфейса RDS. Для пользователей VPC группа безопасности будет обычной группой безопасности VPC (имя sg-xxx будет указано в атрибутах экземпляра RDS).
2) Убедитесь, что DNS не проблема.
Amazon использует разделенный DNS, поэтому внешний поиск DNS для AWS вернет общедоступный IP-адрес, а внутренний поиск AWS вернет частный IP-адрес. Если вы подозреваете, что это проблема DNS, подтвердили ли вы, что разные IP-адреса возвращаются из разных зон доступности? Если разные AZ получают разные IP-адреса, вам необходимо обратиться в службу поддержки AWS.
3) Подтвердите сетевое соединение, установив сокетное соединение.
Такие инструменты, как tracepath и traceroute, скорее всего, не помогут, поскольку RDS в настоящее время отбрасывает трафик ICMP.
Протестируйте подключение к порту, пытаясь установить сокет-соединение с экземпляром RDS на порту 3306 (mysql или 5432 для postgres). Начните с поиска IP-адреса экземпляра RDS и использования telnet или nc (обязательно используйте внутренний / частный IP-адрес при подключении из AWS):
telnet x.x.x.x 3306
nc -vz x.x.x.x 3306
a) Если ваша попытка подключения не удалась и сразу не удалась, порт, вероятно, заблокирован или на удаленном хосте не запущена служба на этом порту. Вам, возможно, потребуется задействовать поддержку AWS для дальнейшего устранения неполадок. При подключении из-за пределов AWS попробуйте сначала подключиться из другого экземпляра внутри AWS (так как ваш брандмауэр может блокировать эти подключения).
б) Если ваше соединение не установлено и вы получили тайм-аут, вероятно, пакеты сбрасываются / игнорируются брандмауэром или пакеты возвращаются по другому сетевому пути. Вы можете подтвердить это, запустив netstat -an | grep SYN
(из другого сеанса ssh в ожидании тайм-аута команды telnet/nc).
Соединения в состоянии SYN означают, что вы отправили запрос на соединение, но ничего не получили обратно (SYN_ACK или reject/block). Обычно это означает, что брандмауэр или группа безопасности игнорируют или отбрасывают пакеты.
Это также может быть проблемой с NAT-маршрутизацией или несколькими путями из нескольких интерфейсов. Убедитесь, что вы не используете iptables или шлюз NAT между вашим хостом и экземпляром RDS. Если вы находитесь в VPC, также убедитесь, что вы разрешаете исходящий / исходящий трафик с исходного хоста.
c) Если ваш тест подключения к сокету был успешным, но вы не можете подключиться с помощью клиента mysql (CLI, верстак, приложение и т. д.), посмотрите на вывод команды netstat, чтобы узнать, в каком состоянии находится соединение (замените xxxx с фактическим IP-адресом экземпляра RDS):
netstat -an | grep x.x.x.x
Если вы устанавливаете соединение при использовании telnet или NC, но вы видите состояние "SYN" при использовании клиента mysql, возможно, вы столкнулись с проблемой MTU.
RDS на момент написания этой статьи может не поддерживать пакеты ICMP, используемые для PMTUD ( https://en.wikipedia.org/wiki/Path_MTU_Discovery). Это может быть проблемой, если вы пытаетесь получить доступ к RDS или RedShift из VPC из классического экземпляра ec2 через ClassicLink. Попробуйте понизить MTU следующим образом, а затем снова протестировать:
sudo ip link show
# take note of the current MTU (likely 1500 or 9001)
sudo ip link set dev eth0 mtu 1400
Если более низкий MTU сработал, обязательно обратитесь за помощью в службу поддержки клиентов AWS и упомяните, что вы видите проблему MTU при попытке подключения к вашему экземпляру RDS. Это может произойти, если пакеты TCP обернуты инкапсуляцией для туннелирования, что приводит к снижению пригодного MTU для пакетных данных / полезной нагрузки. Снижение MTU на исходном сервере позволяет обернутым пакетам по-прежнему помещаться под пределом MTU при прохождении через туннельный шлюз.
Если это не помогло, установите MTU на значение по умолчанию и включите поддержку AWS для дальнейшего устранения неполадок.