## задний план
Это кажется очевидным вопросом.
В Node.js каждое TCP-соединение имеетremoteAddressсвойство, через которое запрошенный IP-адрес может быть получен напрямую. И в HTTP-запросе мы можем передатьrequest.socket.remoteAddress
доступ к этому свойству.
Но все действительно так просто?
Вообще говоря, наши службы приложений не будут напрямую получать внешние запросы, а будут развертывать службы за уровнем доступа, чтобы обеспечить балансировку нагрузки нескольких машин и плавный выпуск служб для обеспечения высокой доступности. Например, обратный прокси-сервер Alibaba Cloud SLB или Nginx.
В этот момент мы проходимremoteAddress
IP - получить прокси-сервер, а не реальный IP пользователя.
## Регулярное решение
X-Forwarded-Forзаголовок запроса.
X-Forwarded-For
X-Forwarded-For: client, proxy1, proxy2
Проблема кажется идеальным решением.
## Это действительно решено?
Но всегда есть «умные» пользователи, у которых возникает озарение, когда они сталкиваются с ограничениями IP на сервисе: если мы добавим его прямо в запросX-Forwarded-For
Заголовок запроса, не должен ли запрашиваться IP-маскарад?
curl -H 'X-Forwarded-For: 1.2.3.4' http://iplimit.resource.com/api/resources
согласно сX-Forwarded-For
Как это работает, первый обратный прокси-сервер, который его получит, будет думать, что исходный адрес запроса1.2.3.4
, затем добавьте реальный IP-адрес пользователя в качестве «первого прокси» вX-Forwarded-For
, окончательный результат на прикладном уровне будет таким:
X-Forwarded-For: 1.2.3.4, client, proxy1, proxy2
## решение
Чтобы избежать получения поддельных IP-адресов пользователей, мы можем сделать еще один шаг и определить, сколько обратных прокси-сервисов у нас есть в нашей архитектуре развертывания, чтобы мы моглиX-Forwarded-For
При запросе получения реального IP-заголовка пользователь должен отфильтровать фиктивный IP-адрес.
// 伪代码
// [ illegalIp, clientRealIp, proxyIp1, proxyIp2 ...]
const val = ctx.get('X-Forwarded-For');
let ips = val ? val.split(/\s*,\s*/) : [];
ips = ips.slice(-(maxProxyCount + 1));
Глупо получилось, не правда ли? Но решения по обеспечению безопасности часто настолько грязны и преследуют практические цели.
В то же время, как среда Node.js корпоративного уровня,Egg.jsПрямой встроенный предоставляет соответствующее решение.
Просто простая конфигурация:
// config/config.default.js
config.proxy = true;
config.maxProxyCount = 1;
Разработчики приложений могут получить правильную информацию без восприятия:
ctx.ip // 获取用户的 IP 地址
ctx.host // 获取用户请求的域名
ctx.protocol // 获取用户请求的协议
Для подробного плана заинтересованные студенты могут расширить, чтобы прочитать следующееДокументация
X-Forwarded-For
Может это?
proxy_set_header X-Forwarded-For $remote_addr;
- Не все уровни унифицированного доступа контролируются пользователями.Например, в коммерческих службах балансировки нагрузки, таких как Alibaba Cloud SLB, вы не сможете настроить эти требования.
- Платформа предпочитает использовать стандартное (де-факто стандартное) решение для конвергенции функций.Поскольку унифицированный доступ верхнего уровня соответствует стандарту, инфраструктура может быть напрямую подключена и настроена единообразно, не требуя от пользователей реализации различных реализаций в соответствии с различными слои доступа.
- Два не конфликтуют, фреймворк полностью реализован, по умолчанию хороший.
## Об этой статье
Эта программа происходит отязык птицаРеальный случай атаки и защиты от инженеров@мертвая лошадь.
Оригинальный адрес:https://www.yuque.com/egg/nodejs/coopsc
Yuque, ваша эксклюзивная база знаний — «инструмент для создания и обмена знаниями», созданный на основе технологии опыта Ant Financial.