Получить IP-адрес источника запроса

Node.js

IP-трассировка в основном используется для получения реального IP-адреса запроса. Поскольку существующий сервис основан на Nginx для достижения балансировки нагрузки, получить реальный IP-адрес запроса сложно. В существующей реализации Matrix прослеживаемость IPgetIpФункция завершена, и ее конкретный код выглядит следующим образом.

/**
 * 获得请求发送方的 ip
 * @param   {Context}  ctx
 * @return  {string}
 */
export function getIp(ctx) {
  const xRealIp = ctx.get('X-Real-Ip');
  const { ip } = ctx;
  const { remoteAddress } = ctx.req.connection;
  return xRealIp || ip || remoteAddress;
}

Прежде чем обсуждать код более подробно, нам нужно проанализировать несколько общихПолучить IP-источник запросаПуть:

  • req.socket.remoteAddress
  • X-Forwarded-For
  • X-Real-IP

req.socket.remoteAddress

В официальной документации Node.jsnet_socket_remoteaddress, мы знаем, что можно пройтиreq.socket.remtoeAddressПолучите информацию об исходном IP-адресе подключения к сокету.

socket.remoteAddress

Added in: v0.5.10

  • String

The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'. Value may be undefined if the socket is destroyed (for example, if the client disconnected).

Согласно официальной документацииhttp_request_socketописание,req.connectionиreq.socketэквивалентно, мы также можем передатьreq.connection.remoteAddressПолучите информацию об исходном IP-адресе соединения сокета. Этот способ получения IP-источника запроса подходит дляПрямое подключение клиента к серверуместо действия.

Однако, поскольку существующий сервис Matrix использует Nginx для балансировки нагрузки сервисного кластера,req.socket.connectionПолучается IP-адрес Nginx, а не реальный IP-адрес запроса.

X-Forwarded-For

в соответствии сRFC 7239спецификация, прокси-серверы HTTP (такие как Nginx, Apache и т. д.) будут переписывать заголовок HTTP-запроса, добавляяX-Forwarded-ForПоле, используемое для отслеживания источника запроса, формат этого поля следующий:

X-Forwarded-For: client, proxy1, proxy2

следующая параX-Forwarded-ForПодробно объясняется процесс обработки поля:

  • Когда клиент (например, браузер) отправляет HTTP-запрос, по умолчаниюX-Forwarded-Forполе.
  • Когда запрос достигает первого прокси-сервера HTTP, прокси-сервер добавляет к заголовку запроса в соответствии со спецификацией RFC 7239.X-Forwared-Forполе и установите значениеIP-адрес клиента.
  • Если позади несколько HTTP-прокси (то есть запрос будет обрабатываться несколькими HTTP-прокси по очереди), каждый прокси будетX-Forwarded-Forв значении поляДобавить IP-адрес предыдущего прокси.
  • На бизнес-сервере мы можем передатьX-Forwarded-Forстоило тогоКрайний левый IP-адресПолучить IP-адрес клиента.

Но, к сожалению,X-Forwarded-Forдаподлог: если клиент устанавливает поддельный HTTP-запрос при выполнении HTTP-запросаX-Forwarded-Forполе, из-заПоследующие уровни прокси будут только добавлять это поле, а не перезаписывать его., поэтому IP-адрес клиента, окончательно полученный сервером службы, может быть поддельным адресом клиента.

Обычно нам нужно сделать дополнительную настройку, чтобы сделать поддержку NginxX-Forwarded-For.

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

X-Real-IP

HTTP-прокси-сервер можно указать в заголовке запроса.X-Real-IPзапрашивать исходную информацию, ноЭтого нет в спецификации RFC..

X-Real-IPдаКлиент не может быть подделанДа, ноМогу только описать реальный IP ближайшего прокси, если есть несколько уровней прокси, он по-прежнему недоступен, поскольку реальный IP-адрес запрошен клиентом. в реальной жизни,Многослойные агенты на самом деле относительно редки, а однослойные агенты распространены., поэтому в обычном случае используйтеX-Real-IPдостаточно для выполнения задачи, а относительноX-Forwarded-ForТам безопасность лучше.

Мы можем сделать поддержку Nginx следующими настройкамиX-Real-IPАвтоматическая настройка полей.

proxy_set_header X-Real-IP $remote_addr;

Сравнение нескольких способов

Ниже приводится мое резюме нескольких способов получения реального IP-адреса клиента, а также анализируются ограничения и сценарии применения каждого метода.

req.socket.remoteAddress X-Forwarded-For X-Real-IP
Можно ли подделать нет да нет
срок действия Только когда клиент напрямую подключается к серверу только если не подделка только если клиент не многоуровневый проксируется

использованная литература