我在另一个 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 实现此功能,我做了以下几件事:
- 更改了现有 vsfptd 服务的 conf 文件
- 监听端口 2121
- 使用外部 IP 进行响应
- 将防火墙上的 21 端口转发到 ftp 服务器上的 2121 端口
- 添加了第二个 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 的情况。
- 创建
/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
- 创建
/etc/iptables/rules.v4
具有规则的文件
注意:请记住安装iptables
并iptables-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
- 创建
/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
- 创建一个名为
/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如果你想查看更多详细信息