You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda中ftplib RETR小文件卡住,PORT地址异常求助

问题分析与解决方案

核心原因

AWS Lambda执行环境采用NAT网络架构,默认情况下ftplib在主动模式(PORT模式)下会自动绑定到本地链路本地地址(如169.254.76.1),这个地址无法被工业HMI控制面板访问——因为HMI需要主动连接PORT命令指定的IP:端口来传输数据,而链路本地地址属于不可路由的内网地址,最终导致下载超时卡住。

本地测试正常是因为你的机器有可被HMI访问的局域网IP,ftplib会自动使用这个IP构造PORT命令。

解决方案:自定义FTPLib类强制指定可路由IP

要解决这个问题,需要重写ftplib.FTP的makeport方法,让它使用Lambda执行环境的可路由IP(公网出口IP或VPC私有IP,取决于HMI的网络可达性)来构造PORT命令。

代码示例

场景1:HMI可访问公网(Lambda使用公网NAT)

import ftplib
import socket
import requests

class HMI_FTP(ftplib.FTP):
    def makeport(self):
        # 获取Lambda公网出口IP(通过AWS官方检测服务)
        public_ip = requests.get('http://checkip.amazonaws.com').text.strip()
        # 创建监听socket,绑定随机端口
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('', 0))
        sock.listen(1)
        port = sock.getsockname()[1]
        # 构造PORT命令格式:将IP拆分为四段,端口拆分为高低字节
        ip_segments = public_ip.split('.')
        port_high = port // 256
        port_low = port % 256
        self.sendport(*ip_segments, port_high, port_low)
        return sock

# 使用自定义类连接HMI并下载文件
with HMI_FTP("HMI_FTP_HOST") as ftp:
    ftp.login("USERNAME", "PASSWORD")
    with open("/tmp/downloaded_file", "wb") as f:
        ftp.retrbinary("RETR target_file.txt", f.write)

场景2:HMI与Lambda在同一VPC/可路由私有网络

如果HMI仅能访问私有网络,替换公网IP获取逻辑为VPC私有IP:

# 替换makeport中的IP获取部分
private_ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4').text.strip()

必要的网络配置检查

  1. 安全组规则:
    • Lambda所在安全组需允许入站:HMI的IP/子网访问所有TCP端口(因为主动模式的传输端口是随机分配的)
    • Lambda所在安全组需允许出站:访问HMI的FTP端口(默认21)
  2. 网络可达性:
    • 若使用VPC,确保HMI所在网络与Lambda的VPC通过对等连接、Direct Connect等方式打通
    • 若使用公网,确保HMI的防火墙/网关允许访问Lambda的公网出口IP

无关操作说明

你之前尝试的下载到/tmp目录、添加SITE CHMOD命令无法解决问题,因为核心故障是网络层面的PORT地址不可达,这些操作不影响FTP主动模式的网络握手流程。

内容的提问来源于stack exchange,提问作者Shenanigator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:15:05