Play Framework - извлечение клиентского IP при использовании балансировки нагрузки TCP
Случай использования: приложение Play за Amazon ELB, которое настроено для балансировки нагрузки TCP.
Amazon ELB предоставляет информацию о подключении клиента через Прокси-протокол 1.
Как получить эту информацию в Play?
Ответ 1
Если вы включили поддержку протокола прокси-сервера, он добавляет заголовок протокола прокси-сервера haproxy, как первое, что отправлено в запросе TCP. Фактически он добавляет следующую строку перед HTTP-запросом:
PROXY TCP4 192.168.0.1 192.168.0.11 56324 443
Это недопустимый HTTP, поэтому Play не поддерживает его, если Play получает такой запрос, он просто вернет ошибку.
Что вы можете сделать, это установить прокси-сервер на EC2 node, который поддерживает протокол прокси-сервера, а затем добавить этот IP-адрес прокси-протокола в заголовок X-Forwarded-For для приложения Play. Инструкции о том, как настроить nginx для поддержки протокола прокси таким образом, можно найти здесь:
Вы можете получить любой HTTP-заголовок из запроса. Если информация прокси доступна в HTTP-заголовке (я не знаком с ELB Amazon и каким HTTP-заголовком, который он использует, но я предполагаю, что он будет использовать сортировку HTTP-заголовков), вы можете проанализировать его самостоятельно, например:
val maybeClientIp: Option[String] = request.headers.get("PROXY").flatMap { header =>
val proxyProtocolHeader = header.split(" ")
if (proxyProtocolHeader.length > 2) {
Some(proxyProtocolHeader(2))
} else {
None
}
}