我正在尝试通过 HaProxy 将 FTP 流量引导到 IIS FTP 服务器。我也尝试设置 FileZilla FTP 服务器,但问题类似 - 被动模式不起作用。
这是我的haproxy.cfg
listen FTP
mode tcp
bind <HAPROXY_SERVER_IP>:21 transparent
bind <HAPROXY_SERVER_IP>:50000-55000 transparent
server ftp01 <IIS_FTP_SERVER_IP>
IIS 上的被动端口配置:
我看过类似的问题 -通过 haproxy 建立 ftp 连接- 然而建议的答案(基于这篇博文) 对我来说不起作用。FTP 登录有效,但目录列表命令 ( ls
) 出现错误:
425 Cannot open data connection.
我也看过这个要点同时寻找将客户端 IP 转发到 FTP 服务器的选项。由于 FTP 连接是基于 TCP 的,因此我无法使用(1) X-Forwarded-For
HTTP 标头。据我所知,FileZilla 和 IIS FTP 服务不支持(2)proxyprotocol。这只剩下选项(3):
source 0.0.0.0 usesrc clientip
看起来配置相当复杂!
我这里漏掉了什么?这肯定不是一项艰巨的任务!
我的系统
HaProxy虚拟机
操作系统:Ubuntu 20.04.4 LTS
HaProxy 版本:HAProxy version 2.4.14-1ppa1~focal 2022/02/25
FTP 服务器虚拟机
操作系统:Windows Server 2019
IIS 版本:10.0.17763.1
虚拟机连接到同一个本地网络。
更新
我将包含失败会话的客户端和服务器日志
客户
# Note: h1, h2, h3, h4 make up the <IIS_FTP_SERVER_IP>
ftp -p <HAPROXY_SERVER_IP>
Connected to <HAPROXY_SERVER_IP>.
220 Microsoft FTP Service
Name (<HAPROXY_SERVER_IP>:<LOCAL_PC_USERNAME>): <FTP_USERNAME>
331 Password required
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> ls
227 Entering Passive Mode (h1,h2,h3,h4,195,80).
150 Opening ASCII mode data connection.
425 Cannot open data connection.
ftp> bye
221 Goodbye.
IIS FTP 服务器
#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2022-07-12 23:01:15
#Fields: date time c-ip cs-username s-ip s-port cs-method cs-uri-stem sc-status sc-win32-status sc-substatus x-session x-fullpath
2022-07-12 23:01:15 <HAPROXY_SERVER_IP> - <IIS_FTP_SERVER_IP> 21 ControlChannelOpened - - 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:29 <HAPROXY_SERVER_IP> - <IIS_FTP_SERVER_IP> 21 USER <FTP_USERNAME> 331 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:52 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 PASS *** 230 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 /
2022-07-12 23:01:52 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 SYST - 215 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:54 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 PASV - 227 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:54 <FTP_CLIENT_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 50000 DataChannelOpened - - 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:54 <FTP_CLIENT_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 50000 DataChannelClosed - - 1236 38 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:01:54 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 LIST - 425 1236 38 a46aa445-e3be-46ba-9da2-3f5520e3c419 /
2022-07-12 23:02:06 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 QUIT - 221 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
2022-07-12 23:02:06 <HAPROXY_SERVER_IP> <IIS_SERVER_MACHINE_NAME>\<FTP_USERNAME> <IIS_FTP_SERVER_IP> 21 ControlChannelClosed - - 0 0 a46aa445-e3be-46ba-9da2-3f5520e3c419 -
答案1
FTP 是一种糟糕的协议,需要两个连接:
对于被动 FTP,最初只有一个连接,即控制连接。该连接由客户端建立,通常连接到默认端口 TCP 21。
为了实际传输数据(获取目录列表是一种数据传输),客户端需要建立第二个 TCP 连接,即数据连接。
当 FTP 客户端使用PASV
控制字请求被动 ftp 连接时,FTP 服务器会选择一个“随机可用的临时”非默认端口,并使用 PORT 响应宣布该端口。
响应PORT
通常包含 6 个八位字节,例如,PORT h1,h2,h3,h4,p1,p2
其中h1.h2.h3.h4
是服务器的 IPv4 IP 地址,TCP 端口号是,(p1*256) + p2
即xxx,x,xxx,xxx,196,107
代表端口(196 * 256) + 107 = 50283
为了与防火墙很好地配合,管理员通常会建立一个固定的端口范围,而不是允许 FTP 服务器为数据连接选择任何“随机可用的临时”端口。
看起来您确实修复了该端口范围,但是您是否也打开了所需的防火墙端口?
现在第二件事是PORT
响应包含服务器的 IP 地址。您需要确保 FTP 客户端收到的是他们要连接的 HAProxy 服务器的 IP 地址,而不是 IIS 服务器的 IP 地址。
您的屏幕截图显示 IIS 提供了这样的选项,“防火墙的外部 IP 地址”允许管理员调整将在 PORT 响应中使用的 IP 地址。响应中将使用自定义 IP 地址,而不是绑定到服务器的实际 IP 地址PORT
。这通常是解决端口转发引起的问题的方法,因此得名,但这也是您的 HAProxy 的解决方案。
或者,执行端口转发的设备(在本例中为 HAProxy)需要用自己的 IP 地址重写 PORT 响应中的 IP 地址。
据我所知,HAProxy 不提供标准的方法来执行此操作。
检查:您的 FTP 客户端收到的 PORT 响应是什么?