为什么 vsftpd(防火墙后面)会为 pasv 地址返回其内部 ip 地址?

为什么 vsftpd(防火墙后面)会为 pasv 地址返回其内部 ip 地址?

我在另一个 Debian 防火墙后面的 Debian 服务器上使用 vsftpd。natting 正确,我可以从外部连接到 ftp 服务器。但是,当客户端发出命令时PASV,ftp 服务器返回其内部 IP(192.168.0.19)。

我没有pasv_address在conf文件中设置指令,因此“地址取自传入的连接套接字”(复制自手册)在我看来,当外部客户端发出时PASV,应该返回防火墙的外部IP地址,而当内部客户端连接时,应该返回内部FTP服务器的IP。

当我将pasv_address指令设置为防火墙的外部 IP 时,外部一切正常,但内部却出现故障。当我将其设置为内部 IP 地址或注释掉 时pasv_address,内部客户端可以工作,但外部客户端则无法工作。

有人对此有任何见解吗?

编辑1:这是服务器端日志文件:

Thu Sep  7 10:36:15 2017 [pid 9093] FTP command: Client "x.x.x.x", "USER yyy"
Thu Sep  7 10:36:15 2017 [pid 9093] [yyy] FTP response: Client "x.x.x.x", "331 Please specify the password."
Thu Sep  7 10:36:15 2017 [pid 9093] [yyy] FTP command: Client "x.x.x.x", "PASS <password>"
Thu Sep  7 10:36:15 2017 [pid 9092] [yyy] OK LOGIN: Client "x.x.x.x"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "230 Login successful."
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP command: Client "x.x.x.x", "OPTS utf8 on"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "200 Always in UTF8 mode."
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP command: Client "x.x.x.x", "PWD"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "257 "/""
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP command: Client "x.x.x.x", "CWD /DownloadProduction/"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "250 Directory successfully changed."
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP command: Client "x.x.x.x", "TYPE A"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "200 Switching to ASCII mode."
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP command: Client "x.x.x.x", "PASV"
Thu Sep  7 10:36:15 2017 [pid 9094] [yyy] FTP response: Client "x.x.x.x", "227 Entering Passive Mode (192,168,0,19,192,27)."

编辑2:我能够使用 ProFTPD 来实现这一点。以下是 serverfault 案例:防火墙后面的 ProFTPd 服务器返回用于 WAN 和 LAN 连接的内部 IP 地址

答案1

如果您位于外部防火墙后面,则传入连接实际上来自外部防火墙。因此服务器 IP 地址是其内部 IP 地址。您描述的是“正确”的行为。FTP 服务器不知道(也不可能知道)防火墙的外部 IP 地址。


您可以为 FTP 服务器分配两个 IP 地址。一个用于外部的使用和一个内部的使用。并配置 FTP 服务器返回防火墙外部 IP 地址,用于连接外部的IP 地址;以及用于连接的内部 IP 地址内部的IP地址。

虽然我不确定 vsftpd 是否允许这样的配置。但 ProFTPD 允许。

答案2

为了使用 vsfptd 实现此功能,我做了以下几件事:

  1. 更改了现有 vsfptd 服务的 conf 文件
    • 监听端口 2121
    • 使用外部 IP 进行响应
  2. 将防火墙上的 21 端口转发到 ftp 服务器上的 2121 端口
  3. 添加了第二个 vsftpd 服务(名为 vsftpd-internal)
    • 监听默认端口 21
    • 使用内部 IP 进行响应

这使得现有服务仅处理外部连接,而新的 vsftpd-internal 服务仅处理内部连接。

编辑以显示配置选项(在评论中请求)

外部(/etc/vsftpd.conf):

listen_port=2121
pasv_address=x.x.x.x # External IP - port forwarded from FW to this machine

内部(/etc/vsftpd-internal.conf):

# nothing special in this one, mostly default

答案3

FTP 经常会让人头疼,因为它不会在已经建立的控制连接上传输数据,而是需要打开一个额外的连接来传输数据。FTP 的第一个版本要求服务器打开这个到客户端的连接 - 这是在 NAT 未知的时候。为了使它与 NAT 一起工作,发明了 PASV,这样客户端就可以打开第二个连接。更好,但 - 正如您所体验到的 - 不是最佳的。

我想到三种选择:

  • 您改用 sftp - 它不会遇到此问题,因为它本质上是使用 ssh 在一个且只有一个连接中控制和传输数据。当然,这是一个不同的协议,因此根据您的环境,这可能不是一个选项。
  • 您不需要在 Debian 防火墙上使用 NAT,而是使用一些 ftp 代理软件,例如“ftp-proxy”。
  • 您设置了两个 vsftp 服务器,一个在标准端口上监听内部连接,另一个在 2121 上监听外部连接,该服务器将 pasv_address 配置为防火墙的外部 IP。需要调整 NAT 以将端口 21 转换为端口 2121。

答案4

扩展自 Lifz 的回答。下面是我在具有外部和内部 IP 的 AWS EC2 上配置 vsftpd 的情况。

  1. 创建/etc/vsftpd.conf用于在端口 21 上使用内部 IP 进行响应
...

# your desire's FTP options - mostly is default

...
# Here is the main things for make vsftpd respond with internal IP on port 21
pasv_enable=YES
pasv_min_port=10000
pasv_max_port=11000
connect_from_port_20=NO
listen_port=21
  1. 创建/etc/iptables/rules.v4具有规则的文件

注意:请记住安装iptablesiptables-persistent预先添加此rules.v4文件,以便使规则在启动时持久化(我使用的是 Ubuntu 20.04)。

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:ftpport - [0:0]
-A PREROUTING -p tcp -m tcp --dport 21 -j ftpport

-A ftpport -s 192.168.0.0/24 -j RETURN
-A ftpport -s 127.0.0.0/24 -j RETURN
-A ftpport -p tcp -j DNAT --to-destination :2121
-A POSTROUTING -p tcp -m tcp --sport 2120 -j SNAT --to-source :20
COMMIT

然后启动netfilter-persistent服务使规则生效

sudo systemctl start netfilter-persistent
sudo systemctl enable netfilter-persistent
  1. 创建/etc/vsftpd-nat.conf
...
# all from vsftpd.conf file with a slight difference as below
... 
pasv_enable=YES
pasv_min_port=10000
pasv_max_port=11000
# Here is the difference we make vsftpd-nat.conf listen on port 2121 and handle connections from external ip
listen_port=2121
pasv_address=<your external IP>
connect_from_port_20=YES
ftp_data_port=2120
  1. 创建一个名为/etc/systemd/system/vsftpd-nat.service
[Unit]
Description=vsftpd-nat FTP server
After=network.target

[Service]
Type=simple
ExecStart=/usr/sbin/vsftpd /etc/vsftpd-nat.conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStartPre=-/bin/mkdir -p /var/run/vsftpd/empty

[Install]
WantedBy=multi-user.target

启动vsftpd-nat服务

sudo systemctl start vsftpd-nat
sudo systemctl enable vsftpd-nat

这就是我们所需要的——我写了一篇关于如何配置防火墙后面的 VSFTPD 服务器以处理内部和外部 IP如果你想查看更多详细信息

相关内容