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 для поддержки протокола прокси таким образом, можно найти здесь:

https://chrislea.com/2014/03/20/using-proxy-protocol-nginx/

Ответ 2

Вы можете получить любой 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
  }
}