”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在 AWS Lambda 中使用 Application Load Balancer (ALB) 时获取实际客户端 IP

在 AWS Lambda 中使用 Application Load Balancer (ALB) 时获取实际客户端 IP

发布于2024-08-06
浏览:831

Getting the Actual Client IP When Using Application Load Balancer (ALB) in AWS Lambda

当我刚接触 AWS 时,我在执行对文档进行数字签名的任务时遇到了一个有趣的挑战,该任务需要客户的 IP 作为电子签名的一部分。最初,当第一次实现似乎完美运行时,我感到很兴奋。然而,我的兴奋是短暂的。在测试过程中,我注意到即使我从不同的机器访问应用程序,也会返回相同的 IP 地址。就在那时,我意识到我收到的 IP 地址不是实际的客户端 IP,而是负载均衡器的 IP。

这个发现带领我走上了一条调查和学习的道路。我必须更深入地了解发生了什么以及如何检索真实的客户端 IP。在这篇博客中,我将分享我的经验,并提供有关如何使用 AWS Lambda 和 Python 实现此目标的全面指南,确保您在使用应用程序负载均衡器 (ALB) 时能够准确捕获客户端的 IP 地址。

了解挑战

当客户端通过 ALB 向您的应用程序发出请求时,负载均衡器充当中介。因此,您的应用程序看到的 IP 地址是 ALB 的 IP 地址,而不是客户端的 IP 地址。为了解决这个问题,ALB 在 X-Forwarded-For HTTP 标头中包含客户端的 IP。如果请求通过多个代理,此标头可以包含多个 IP 地址。

这是我们需要处理的:

  • 提取客户端IP:检索并解析X-Forwarded-For标头。

  • 处理多个IP:即使涉及多个代理,也确保我们获得正确的客户端IP。

安全考虑

由于潜在的安全风险,应谨慎使用 X-Forwarded-For 标头。只有由网络内受到适当保护的系统添加的条目才被认为是可信的。这确保了客户端IP不被篡改且可靠。

选择正确的工具

AWS Lambda 和 Python

AWS Lambda 是一种无服务器计算服务,让您无需预置或管理服务器即可运行代码。 Python 以其简单性和可读性,是在 Lambda 函数中处理此任务的绝佳选择。

关键部件

  1. AWS Lambda Function:处理传入请求的核心函数。

  2. Application Load Balancer (ALB):将请求转发到 Lambda 函数的负载均衡器。

实施细节

使用 ALB 设置 AWS Lambda

首先,确保您的 Lambda 函数已设置并与 ALB 集成。如果需要,请遵循 AWS 的官方指南:使用 Lambda 函数作为应用程序负载均衡器的目标。

Lambda 函数代码

让我们深入研究 Lambda 函数的 Python 代码。此函数将从 X-Forwarded-For 标头中提取客户端的 IP 地址。

import json

def lambda_handler(event, context):
    # Extract the 'X-Forwarded-For' header
    x_forwarded_for = event['headers'].get('x-forwarded-for')

    if x_forwarded_for:
        # The first IP in the list is the client's IP
        client_ip = x_forwarded_for.split(',')[0]
    else:
        # Fallback if header is not present
        client_ip = event['requestContext']['identity']['sourceIp']

    # Log the client IP
    print(f"Client IP: {client_ip}")

    # Respond with the client IP
    return {
        'statusCode': 200,
        'body': json.dumps({'client_ip': client_ip})
    }

解释

  • 提取标头:从传入请求中检索 X-Forwarded-For 标头。

  • 解析Header:取第一个IP,代表客户端的原始IP。

  • 回退机制:如果标头不存在,则使用请求上下文中的源 IP。

  • 记录和响应:记录并返回客户端的IP以进行验证。

请求和响应示例

要求:

{
    "headers": {
        "x-forwarded-for": "203.0.113.195, 70.41.3.18, 150.172.238.178"
    },
    "requestContext": {
        "identity": {
            "sourceIp": "70.41.3.18"
        }
    }
}

回复:

{
    "client_ip": "203.0.113.195"
}

结论

识别 ALB 后面的 AWS Lambda 函数中的实际客户端 IP 需要仔细处理 X-Forwarded-For 标头。这种方法可确保准确的 IP 日志记录并增强应用程序个性化和保护用户交互的能力。

参考文献

  • AWS ALB 文档:

  • AWS Lambda 中的 Python:

  • HTTP 标头解释

版本声明 本文转载于:https://dev.to/rkj180220/getting-the-actual-client-ip-when-using-application-load-balancer-alb-in-aws-lambda-4fcn?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何在其容器中为DIV创建平滑的左右CSS动画?
    如何在其容器中为DIV创建平滑的左右CSS动画?
    通用CSS动画,用于左右运动 ,我们将探索创建一个通用的CSS动画,以向左和右移动DIV,从而到达其容器的边缘。该动画可以应用于具有绝对定位的任何div,无论其未知长度如何。问题:使用左直接导致瞬时消失 更加流畅的解决方案:混合转换和左 [并实现平稳的,线性的运动,我们介绍了线性的转换。这...
    编程 发布于2025-07-02
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    在使用GO MOD时,在GO MOD 中克服模块路径差异时,可能会遇到冲突,其中3个Party Package将另一个PAXPANCE带有导入式套件之间的另一个软件包,并在导入式套件之间导入另一个软件包。如回声消息所证明的那样: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    编程 发布于2025-07-02
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-07-02
  • 如何从PHP中的数组中提取随机元素?
    如何从PHP中的数组中提取随机元素?
    从阵列中的随机选择,可以轻松从数组中获取随机项目。考虑以下数组:; 从此数组中检索一个随机项目,利用array_rand( array_rand()函数从数组返回一个随机键。通过将$项目数组索引使用此键,我们可以从数组中访问一个随机元素。这种方法为选择随机项目提供了一种直接且可靠的方法。
    编程 发布于2025-07-02
  • 如何同步迭代并从PHP中的两个等级阵列打印值?
    如何同步迭代并从PHP中的两个等级阵列打印值?
    同步的迭代和打印值来自相同大小的两个数组使用两个数组相等大小的selectbox时,一个包含country代码的数组,另一个包含乡村代码,另一个包含其相应名称的数组,可能会因不当提供了exply for for for the uncore for the forsion for for ytry...
    编程 发布于2025-07-02
  • Java数组中元素位置查找技巧
    Java数组中元素位置查找技巧
    在Java数组中检索元素的位置 利用Java的反射API将数组转换为列表中,允许您使用indexof方法。 (primitives)(链接到Mishax的解决方案) 用于排序阵列的数组此方法此方法返回元素的索引,如果发现了元素的索引,或一个负值,指示应放置元素的插入点。
    编程 发布于2025-07-02
  • Java字符串非空且非null的有效检查方法
    Java字符串非空且非null的有效检查方法
    检查字符串是否不是null而不是空的 if(str!= null && str.isementy())二手: if(str!= null && str.length()== 0) option 3:trim()。isement(Isement() trim whitespace whitesp...
    编程 发布于2025-07-02
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-07-02
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-07-02
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-07-02
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-07-02
  • `console.log`显示修改后对象值异常的原因
    `console.log`显示修改后对象值异常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    编程 发布于2025-07-02
  • PHP与C++函数重载处理的区别
    PHP与C++函数重载处理的区别
    作为经验丰富的C开发人员脱离谜题,您可能会遇到功能超载的概念。这个概念虽然在C中普遍,但在PHP中构成了独特的挑战。让我们深入研究PHP功能过载的复杂性,并探索其提供的可能性。在PHP中理解php的方法在PHP中,函数超载的概念(如C等语言)不存在。函数签名仅由其名称定义,而与他们的参数列表无关。...
    编程 发布于2025-07-02
  • 解决Spring Security 4.1及以上版本CORS问题指南
    解决Spring Security 4.1及以上版本CORS问题指南
    弹簧安全性cors filter:故障排除常见问题 在将Spring Security集成到现有项目中时,您可能会遇到与CORS相关的错误,如果像“访问Control-allo-allow-Origin”之类的标头,则无法设置在响应中。为了解决此问题,您可以实现自定义过滤器,例如代码段中的MyFi...
    编程 发布于2025-07-02
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-07-02

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3