亚马逊 ELB 后面带有 node-js 的远程 IP 地址
Posted
技术标签:
【中文标题】亚马逊 ELB 后面带有 node-js 的远程 IP 地址【英文标题】:Remote IP address with node-js behind amazon ELB 【发布时间】:2011-10-31 15:33:10 【问题描述】:我在弹性负载均衡器 (elb) 后面的亚马逊实例存储机器上有一个节点应用程序。但是,远程 IP 地址似乎总是相同的。我使用此代码在节点中获取客户端的 IP 地址(通过 connect/express):
req.socket.remoteAddress
我没有从节点文档中得到任何其他信息。有什么提示吗?
【问题讨论】:
如果您在 TCP 模式下使用 ELB,请参阅***.com/q/17981943/201952 【参考方案1】:这是一个解决方案如果您使用的是 express:
根据documentation,您可以为您的快速实例启用trust proxy
,然后req.ip
将填充正确的IP 地址。
通过 app.enable('trust proxy') 启用“信任代理”设置, Express 将知道它位于代理后面,并且 X-Forwarded-* 标头字段可能是可信的,否则可能是 很容易被欺骗。
启用此设置会产生一些微妙的影响。其中第一个 是反向代理可以设置 X-Forwarded-Proto 来告诉 应用程序,它是 https 或只是 http。这个值反映在 req.protocol.
第二个改变是 req.ip 和 req.ips 值将是 填充了 X-Forwarded-For 的地址列表。
这是一个例子:
var app = express();
app.enable('trust proxy');
// ...
app.use(function(req, res, next)
console.log('client ip address:', req.ip);
return next();
);
【讨论】:
过去几年我实际上一直在使用这个,但忘记了这个问题 :) 感谢您再次提出! express 4 改变了trust proxy
选项的处理方式,因此您可以使用app.set('trust proxy', 1)
之类的东西来只信任您的负载均衡器
顺便说一下,在亚马逊的情况下,我认为该值必须是2
,一个用于实际机器上的 nginx,另一个是实际的负载均衡器。【参考方案2】:
答案对我有用,谢谢。但你可以试试:
var ip_address = null;
if(req.headers['x-forwarded-for'])
ip_address = req.headers['x-forwarded-for'];
else
ip_address = req.connection.remoteAddress;
sys.puts( ip_address );
【讨论】:
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; 没有req.connection.remoteAddress
- 它在 NodeJS 中被删除了吗?【参考方案3】:
您收到 ELB 实例的 IP,您需要从标头中获取 x-forwarded-for 值。由于我不是 node.js 大师,我在 http://forum.webfaction.com/viewtopic.php?id=4500 找到了这段代码
例子:
var http = require( 'http' ),
sys = require( 'sys' );
http.createServer(
function( req, res )
var ip_address = null;
try
ip_address = req.headers['x-forwarded-for'];
catch ( error )
ip_address = req.connection.remoteAddress;
sys.puts( ip_address );
);
【讨论】:
很酷,谢谢,刚刚尝试过,它可以工作。我不知道那个标题。 如果req.headers['x-forwarded-for']
不存在,则不是错误。 ip_address
将只是 undefined
。 ip_address = req.headers['x-forwarded-for'] || req.connection.remoteAddress
;` 将完成这项工作【参考方案4】:
此处选择的正确答案很危险,因为 AWS ELB 会按预期切换顺序:https://github.com/koajs/koa/issues/1094#issuecomment-345861282
Express、koa等一般取最左边的item,而ELB则取最右边的item
(表达文档):
如果为 true,则客户端的 IP 地址被理解为 X-Forwarded-For 标头中最左侧的条目。
【讨论】:
【参考方案5】:如果 express.js 正在使用中:
app.set('trust proxy', 2)
而不是
app.enable('trust proxy')
因为app.enable('trust proxy')
使用 x-forwarded-for 标头中最左边的 ip,因此只需手动提供 x-forwarded-for 标头即可轻松进行欺骗。
虽然app.set('trust proxy', 2)
指定了从 x-forwarded-for 标头的右到左计数的跃点数。 IE。如果有一个 AWS 负载均衡器,那么 2 将是正确的计数,因为每个新的跃点 ip 都会添加到 x-forwarded-for 标头的末尾。
如果您正在使用其他东西,请执行类似的方法。只需获取req.headers['x-forwarded-for']
,用逗号分割,然后从右到左计算跃点,直到不排除负载均衡器 ip。
【讨论】:
以上是关于亚马逊 ELB 后面带有 node-js 的远程 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章
在 AWS ELB 后面带有嵌入式 Undertow 的 Spring Boot - HTTP 到 HTTPS 重定向
如何配置 AWS ELB 以阻止某些 IP 地址? (已知的垃圾邮件发送者)[关闭]
为啥从亚马逊弹性负载均衡器后面发送重定向时收到 502 错误网关?
如何在 ELB 应用程序负载均衡器上将 HTTPS 重定向到 HTTP