如何在AWS Lambda Python函数中使用RAW_SOCKET等底层网络API
在AWS Lambda中使用RAW_SOCKET的权限问题及解决方法
问题描述
尝试在AWS Lambda的Python代码中通过RAW_SOCKET发送流量,代码如下:
import socket import struct # 假设已定义以下变量 TCP_SRC = 12345 TCP_DST = 80 SOURCE_IP = "192.168.1.100" DESTINATION_IP = "1.1.1.1" tcp_header = struct.pack("!HHLLBBHHH", TCP_SRC, TCP_DST, 0, 0, socket.IPPROTO_TCP, 64, 0, 0, 0) ip_header = struct.pack("!BBHHHBBH4s4s", 0x45, 0x00, 0, 0, 0, socket.IPPROTO_TCP, 0, 40, socket.inet_aton(SOURCE_IP), socket.inet_aton(DESTINATION_IP)) raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) raw_socket.sendto(ip_header+tcp_header, (DESTINATION_IP,0))
执行时触发权限错误:
{ "errorMessage": "[Errno 1] Operation not permitted", "errorType": "PermissionError", "stackTrace": [ " File \"/var/task/ebpf_lambda_test/__init__.py\", line 23, in dataplane_test\n raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)\n", " File \"/var/lang/lib/python3.8/socket.py\", line 231, in __init__\n _socket.socket.__init__(self, family, type, proto, fileno)\n" ] }
在EC2实例中通过sudo执行该脚本可正常运行,需解决Lambda中的权限问题。
原因分析
创建RAW_SOCKET需要操作系统级的CAP_NET_RAW权限,Lambda默认执行环境使用非root用户(如sbx_user1051)运行,该用户无此权限;而EC2中sudo会以root身份执行,自然具备该权限。
解决方法
方法一:使用Lambda容器镜像并添加CAP_NET_RAW权限
Lambda支持通过容器镜像部署函数,可自定义镜像并赋予进程CAP_NET_RAW权限,步骤如下:
- 创建Dockerfile,基于官方Python镜像,示例如下:
FROM public.ecr.aws/lambda/python:3.8 # 安装依赖(如果有) COPY requirements.txt ${LAMBDA_TASK_ROOT} RUN pip install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" # 复制函数代码 COPY ebpf_lambda_test/ ${LAMBDA_TASK_ROOT}/ebpf_lambda_test/ # 给Python二进制文件添加CAP_NET_RAW权限,无需root即可创建RAW_SOCKET RUN setcap cap_net_raw+ep /var/lang/bin/python3.8 # 设置Lambda入口点 CMD ["ebpf_lambda_test.__init__.dataplane_test"]
- 构建镜像并推送到AWS ECR仓库;
- 创建Lambda函数时选择“容器镜像”,指定推送至ECR的镜像,即可正常运行代码。
方法二:以root用户运行容器镜像(不推荐)
也可在Dockerfile中指定以root用户运行,但会降低函数安全性:
# 在Dockerfile中添加以下行 USER root
部署后Lambda函数将以root身份执行,自动具备CAP_NET_RAW权限,但此方式不符合最小权限原则,建议优先使用方法一。
内容的提问来源于stack exchange,提问作者user2066671
相关产品推荐
相关产品推荐

