Как развернуть диспетчеры API за ELB на AWS и сохранить заголовки X-Forwarded?

У меня есть несколько RESTfull API, развернутых на AWS, в основном на Elasticbeanstalk.

Моя компания постепенно внедряет архитектуру микросервисов, и поэтому я хочу начать управлять этими API более профессионально и автоматизированно. Следовательно, я хочу принять какой-то менеджер API для предоставления стандартных функций, таких как маршрутизация и обнаружение.

Кроме того, я хочу использовать такой диспетчер API для предоставления доступа к некоторым из моих API в Интернете. Менеджер будет иметь доступ к Интернету только через SSL и должен требовать какой-либо проверки подлинности от внешних потребителей, прежде чем направлять их запросы на внутренние API. В моем случае будет достаточно простого ключа API в заголовке авторизации каждого запроса.

В настоящее время я рассматриваю два продукта в качестве менеджеров API: WSO2 и Kong. Первый — это несколько новый проект с открытым исходным кодом, размещенный на Github.

Во всех сценариях развертывания, которые я рассматриваю, менеджеры API должны быть развернуты на инстансах AWS EC2. Кроме того, они должны быть развернуты как минимум в двух разных зонах доступности и за Elastic Load Balancer (ELB), чтобы обеспечить высокую доступность управляемых API.

Большинство моих API придерживаются ограничений HATEOAS. Поэтому многие из их ответов JSON содержат ссылки на другие ресурсы, которые должны создаваться динамически на основе исходного запроса.

Например:

Если пользователь отправил запрос из Интернета через открытый диспетчер API, URL-адрес будет выглядеть так: https://apimanager.mycompany.com/accounts/123

В результате пользователь должен получить ответ JSON, содержащий ресурс Account со ссылкой, скажем, на ресурс Subscription. URL-адрес ссылки должен основываться на протоколе, хосте и порте исходного запроса и, следовательно, иметь вид: https://apimanager.mycompany.com/subscriptions/789.

Чтобы соответствовать упомянутым выше требованиям динамической генерации ссылок, мои API полагаются на HTTP-заголовки X-Forwarded-Proto, X-Forwarded-Host и X-Forwarded-Port. Они должны содержать протокол (http или https), имя хоста и порт, используемые потребителем в исходном запросе, независимо от того, через сколько прокси прошел запрос.

Однако я заметил, что когда запросы проходят через ELB, заголовки X-Forwarded-Proto и X-Forwarded-Port изменяются на значения, которые относятся к последнему ELB, через который прошел запрос, вместо значений, которые были в исходном запросе.

Например: если первоначальный запрос попадает в диспетчер API через HTTPS, диспетчер перенаправляет запрос во внутренний API через HTTP; таким образом, когда запрос достигает второго ELB, ELB изменяет заголовок X-Forwarded-Proto на «http». В результате исходное значение «https» заголовка X-Forwarded-Proto теряется. Следовательно, API не может создавать правильные ссылки с протоколом https в URL-адресах.

По-видимому, ELB нельзя настроить на другое поведение. Я не смог найти никаких настроек, которые могли бы повлиять на это поведение в документации AWS.

Более того, кажется, что нет лучшей альтернативы ELB от AWS. Если я решу использовать другой продукт, такой как HAProxy, или выполнять балансировку нагрузки через сам API Manager, мне придется установить его на обычный инстанс EC2 и, следовательно, создать единую точку отказа.

Я включаю неофициальную диаграмму, чтобы лучше передать мою точку зрения.

Диаграмма

Кроме того, я не смог найти подходящего обсуждения сценариев развертывания для WSO2 или Kong, которое каким-либо образом касалось бы этих вопросов. Мне непонятно, как эти продукты должны относиться к ELB AWS.

Комментарии от других пользователей с похожей средой будут приветствоваться.

Спасибо.


person Gabriel C    schedule 09.06.2015    source источник


Ответы (1)


Интересный вопрос/задача. Я не знаю, как настроить поведение заголовка Elastic Load Balancer X-Forwarded-* . Однако вы можете обойти это, используя различные типы слушателей для двух поддерживаемых сетевых уровней модели OSI< /а>:

Прослушиватель TCP/SSL без прокси-протокола

Вместо того, чтобы использовать прослушиватель HTTP (уровень 7 OSI), который имеет смысл для терминации SSL и т. д., вы можете просто использовать ненавязчивый прослушиватель TCP/SSL (уровень 4 OSI) для внутренних балансировщиков нагрузки, см. Протоколы:

Когда вы используете TCP (уровень 4) как для интерфейсных, так и для внутренних подключений, ваш балансировщик нагрузки перенаправляет запрос на серверные экземпляры без изменения заголовков. [...] [выделено мной]

Я не пробовал это, но ожидаю, что заголовки X-Forwarded-*, добавленные внешним балансировщиком нагрузки HTTP/HTTPS, будут переданы без изменений внутренним балансировщиком нагрузки TCP/SSL в этом сценарии.

Прослушиватель TCP/SSL с прокси-протоколом

В качестве альтернативы вы также можете использовать более продвинутый/последний прокси-протокол. Немедленная поддержка вашего балансировщика нагрузки, см. вводную запись в блоге Elastic Load Balancing добавляет поддержку прокси-протокола, чтобы узнать больше об этом:

До сегодняшнего дня ELB позволял вам получать IP-адреса клиентов, только если вы использовали балансировку нагрузки HTTP(S), которая добавляет эту информацию в X-Forwarded-For. Поскольку X-Forwarded-For используется только в заголовках HTTP, вы не сможете получить IP-адрес клиента, если ELB настроен для балансировки нагрузки TCP. Многие из вас сказали нам, что вам нужна аналогичная функциональность для TCP-трафика, поэтому мы добавили поддержку протокола Proxy. Он просто добавляет удобочитаемый заголовок с информацией о подключении клиентов к данным TCP, отправляемым на ваш сервер. [...] Прокси-протокол полезен, когда вы обслуживаете не-HTTP-трафик. В качестве альтернативы вы можете использовать его, если вы отправляете HTTPS-запросы и не хотите разрывать SSL-соединение на балансировщике нагрузки. [...]

Помимо заголовков X-Forwarded-*, вы можете enable и отключить обработку прокси-протокола. С другой стороны, ваши серверные уровни могут еще не поддерживать протокол прокси автоматически и должны быть соответствующим образом адаптированы.

person Steffen Opel    schedule 27.06.2015