微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在防火墙后面通过 python 的 ftplib 连接到 FTP 时控制使用的端口号

如何解决在防火墙后面通过 python 的 ftplib 连接到 FTP 时控制使用的端口号

我正在尝试从仅接受端口范围 6100-6200 的输出的防火墙后面连接到 FTP 服务器。我(相当天真,但基于对 the documents 的阅读)尝试:

from ftplib import FTP

host_address="the.ftp.ip.address"
ftp = FTP()
ftp.connect(host=hostaddress,source_address=("127.0.0.1",6100))

但这给出了错误

In [42]: ftp = FTP(host_address,source_address=('127.0.0.1',6100))
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-42-071ac06087bd> in <module>
----> 1 ftp = FTP(destination,6100))

~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/ftplib.py in __init__(self,host,user,passwd,acct,timeout,source_address,encoding)
    117         self.timeout = timeout
    118         if host:
--> 119             self.connect(host)
    120             if user:
    121                 self.login(user,acct)

~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/ftplib.py in connect(self,port,source_address)
    154             self.source_address = source_address
    155         sys.audit("ftplib.connect",self,self.host,self.port)
--> 156         self.sock = socket.create_connection((self.host,self.port),self.timeout,157                                              source_address=self.source_address)
    158         self.af = self.sock.family

~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/socket.py in create_connection(address,source_address)
    841     if err is not None:
    842         try:
--> 843             raise err
    844         finally:
    845             # Break explicitly a reference cycle

~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/socket.py in create_connection(address,source_address)
    829             if source_address:
    830                 sock.bind(source_address)
--> 831             sock.connect(sa)
    832             # Break explicitly a reference cycle
    833             err = None

OSError: [Errno 22] Invalid argument

在同一台机器上,我可以使用 curl 成功列出文件

curl --ftp-port :6100-6200 --list-only $ftpserver

如何使用 ftplib 绕过本地防火墙连接到常规(即端口 21)FTP 服务器?

解决方法

curl --ftp-port switch 允许使用 active 模式并设置本地 listening 端口用于传入数据连接.

这不是你的代码所做的。您的代码使用被动模式并设置传出控制连接的端口。


首先,如果您需要使用主动模式,这通常意味着您的 FTP 服务器或防火墙配置错误。主动模式实际上比被动模式需要更多的防火墙配置。您应该使用被动模式。这是一种工作量更少但更强大的解决方案。

请注意,在被动模式下,您无法控制所使用的端口,因为这是服务器的决定,而不是客户端的决定。您必须配置本地防火墙(如果有)以允许服务器使用的数据连接端口。


如果您确实需要使用主动模式,请使用 FTP.set_pasv

ftp = FTP()
ftp.set_pasv(False)
ftp.connect(host=hostaddress)

ftplib 不允许您控制活动模式的端口。您必须在 ftplib makeport 类中编辑 FTP 方法或在您的代码中覆盖它。让它监听 sock.bind 中的特定端口:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。