如果我尝试通过脚本连接,我的 Centos 7 防火墙会阻止与外部 FTP 客户端的文件交换(导入和导出)。如果我禁用防火墙,一切都会正常。您知道文件交换是否需要特定端口,或者是否还有其他问题?
# sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: dhcpv6-client ftp http https smtp ssh
ports: 2222/tcp 587/tcp 25/tcp 465/tcp 21/tcp 80/tcp 40000/tcp 443/tcp 22/tcp 53/udp 53/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
# lsmod | grep nf_conntrack_ftp
nf_conntrack_ftp 18478 1 nf_nat_ftp
nf_conntrack 139264 8 nf_nat_ftp,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_conntrack_ftp,nf_conntrack_ipv4,nf_conntrack_ipv6
# iptables-save -c
# Generated by iptables-save v1.4.21 on Thu Aug 13 19:59:02 2020
*nat
:PREROUTING ACCEPT [81930:11078515]
:INPUT ACCEPT [14712:902333]
:OUTPUT ACCEPT [24878:1693871]
:POSTROUTING ACCEPT [24878:1693871]
:OUTPUT_direct - [0:0]
:POSTROUTING_ZONES - [0:0]
:POSTROUTING_ZONES_SOURCE - [0:0]
:POSTROUTING_direct - [0:0]
:POST_public - [0:0]
:POST_public_allow - [0:0]
:POST_public_deny - [0:0]
:POST_public_log - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[81930:11078515] -A PREROUTING -j PREROUTING_direct
[81930:11078515] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[81930:11078515] -A PREROUTING -j PREROUTING_ZONES
[24878:1693871] -A OUTPUT -j OUTPUT_direct
[24878:1693871] -A POSTROUTING -j POSTROUTING_direct
[24878:1693871] -A POSTROUTING -j POSTROUTING_ZONES_SOURCE
[24878:1693871] -A POSTROUTING -j POSTROUTING_ZONES
[19315:1359674] -A POSTROUTING_ZONES -o eth0 -g POST_public
[5563:334197] -A POSTROUTING_ZONES -g POST_public
[24878:1693871] -A POST_public -j POST_public_log
[24878:1693871] -A POST_public -j POST_public_deny
[24878:1693871] -A POST_public -j POST_public_allow
[81930:11078515] -A PREROUTING_ZONES -i eth0 -g PRE_public
[0:0] -A PREROUTING_ZONES -g PRE_public
[81930:11078515] -A PRE_public -j PRE_public_log
[81930:11078515] -A PRE_public -j PRE_public_deny
[81930:11078515] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Thu Aug 13 19:59:02 2020
# Generated by iptables-save v1.4.21 on Thu Aug 13 19:59:02 2020
*mangle
:PREROUTING ACCEPT [477222:238129658]
:INPUT ACCEPT [447004:234240830]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [415842:656698573]
:POSTROUTING ACCEPT [415842:656698573]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[477222:238129658] -A PREROUTING -j PREROUTING_direct
[477222:238129658] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[477222:238129658] -A PREROUTING -j PREROUTING_ZONES
[447004:234240830] -A INPUT -j INPUT_direct
[0:0] -A FORWARD -j FORWARD_direct
[415842:656698573] -A OUTPUT -j OUTPUT_direct
[415842:656698573] -A POSTROUTING -j POSTROUTING_direct
[384088:64944119] -A PREROUTING_ZONES -i eth0 -g PRE_public
[93134:173185539] -A PREROUTING_ZONES -g PRE_public
[477222:238129658] -A PRE_public -j PRE_public_log
[477222:238129658] -A PRE_public -j PRE_public_deny
[477222:238129658] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Thu Aug 13 19:59:02 2020
# Generated by iptables-save v1.4.21 on Thu Aug 13 19:59:02 2020
*security
:INPUT ACCEPT [409931:227948926]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [415842:656698573]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
[409931:227948926] -A INPUT -j INPUT_direct
[0:0] -A FORWARD -j FORWARD_direct
[415842:656698573] -A OUTPUT -j OUTPUT_direct
COMMIT
# Completed on Thu Aug 13 19:59:02 2020
# Generated by iptables-save v1.4.21 on Thu Aug 13 19:59:02 2020
*raw
:PREROUTING ACCEPT [477222:238129658]
:OUTPUT ACCEPT [415842:656698573]
:OUTPUT_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[477222:238129658] -A PREROUTING -j PREROUTING_direct
[477222:238129658] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[477222:238129658] -A PREROUTING -j PREROUTING_ZONES
[415842:656698573] -A OUTPUT -j OUTPUT_direct
[384088:64944119] -A PREROUTING_ZONES -i eth0 -g PRE_public
[93134:173185539] -A PREROUTING_ZONES -g PRE_public
[477222:238129658] -A PRE_public -j PRE_public_log
[477222:238129658] -A PRE_public -j PRE_public_deny
[477222:238129658] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Thu Aug 13 19:59:02 2020
# Generated by iptables-save v1.4.21 on Thu Aug 13 19:59:02 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [322708:483513034]
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]
:FORWARD_direct - [0:0]
:FWDI_public - [0:0]
:FWDI_public_allow - [0:0]
:FWDI_public_deny - [0:0]
:FWDI_public_log - [0:0]
:FWDO_public - [0:0]
:FWDO_public_allow - [0:0]
:FWDO_public_deny - [0:0]
:FWDO_public_log - [0:0]
:INPUT_ZONES - [0:0]
:INPUT_ZONES_SOURCE - [0:0]
:INPUT_direct - [0:0]
:IN_public - [0:0]
:IN_public_allow - [0:0]
:IN_public_deny - [0:0]
:IN_public_log - [0:0]
:OUTPUT_direct - [0:0]
[389741:226716526] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[5566:334317] -A INPUT -i lo -j ACCEPT
[51697:7189987] -A INPUT -j INPUT_direct
[51697:7189987] -A INPUT -j INPUT_ZONES_SOURCE
[51697:7189987] -A INPUT -j INPUT_ZONES
[73:4550] -A INPUT -m conntrack --ctstate INVALID -j DROP
[37000:6287354] -A INPUT -j REJECT --reject-with icmp-host-prohibited
[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -i lo -j ACCEPT
[0:0] -A FORWARD -j FORWARD_direct
[0:0] -A FORWARD -j FORWARD_IN_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_IN_ZONES
[0:0] -A FORWARD -j FORWARD_OUT_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_OUT_ZONES
[0:0] -A FORWARD -m conntrack --ctstate INVALID -j DROP
[0:0] -A FORWARD -j REJECT --reject-with icmp-host-prohibited
[93134:173185539] -A OUTPUT -o lo -j ACCEPT
[322708:483513034] -A OUTPUT -j OUTPUT_direct
[0:0] -A FORWARD_IN_ZONES -i eth0 -g FWDI_public
[0:0] -A FORWARD_IN_ZONES -g FWDI_public
[0:0] -A FORWARD_OUT_ZONES -o eth0 -g FWDO_public
[0:0] -A FORWARD_OUT_ZONES -g FWDO_public
[0:0] -A FWDI_public -j FWDI_public_log
[0:0] -A FWDI_public -j FWDI_public_deny
[0:0] -A FWDI_public -j FWDI_public_allow
[0:0] -A FWDI_public -p icmp -j ACCEPT
[0:0] -A FWDO_public -j FWDO_public_log
[0:0] -A FWDO_public -j FWDO_public_deny
[0:0] -A FWDO_public -j FWDO_public_allow
[51697:7189987] -A INPUT_ZONES -i eth0 -g IN_public
[0:0] -A INPUT_ZONES -g IN_public
[51697:7189987] -A IN_public -j IN_public_log
[51697:7189987] -A IN_public -j IN_public_deny
[51697:7189987] -A IN_public -j IN_public_allow
[2121:165216] -A IN_public -p icmp -j ACCEPT
[6239:372132] -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[760:43448] -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[3894:222151] -A IN_public_allow -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[32:1852] -A IN_public_allow -p tcp -m tcp --dport 25 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[105:5552] -A IN_public_allow -p tcp -m tcp --dport 21 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[88:4644] -A IN_public_allow -p tcp -m tcp --dport 2222 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[17:984] -A IN_public_allow -p tcp -m tcp --dport 587 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 25 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[1337:80164] -A IN_public_allow -p tcp -m tcp --dport 465 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 21 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 40000 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[0:0] -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[27:1740] -A IN_public_allow -p udp -m udp --dport 53 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[4:200] -A IN_public_allow -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
COMMIT
# Completed on Thu Aug 13 19:59:02 2020
答案1
所使用的端口可能会根据 FTP 连接使用的“模式”而有所不同。
在主动模式下,客户端通过命令端口 (21) 连接到服务器。它还为服务器提供了一个随机的、非特权端口(> 1023)。服务器使用该随机端口作为目的地连接回客户端。
在被动模式下,客户端通过命令端口 (21) 连接到服务器。然后,服务器在其一端打开一个随机的非特权端口,并将该信息发送到客户端。客户端以该随机端口作为目的地连接回服务器。
您可以参考以下文章以获得更详细的解释:主动 FTP 与被动 FTP,权威解释。
根据您对错误的描述,您的 FTP 客户端必须以被动模式连接。如上所述,服务器将在其一侧打开一个随机的非特权端口,并期望客户端连接回它。然后防火墙会阻止传入连接,从而导致整个过程失败。
要支持被动模式,建议的方法是将 FTP 服务器配置为使用特定范围的端口,然后在防火墙上打开同一范围。您需要打开的端口数量取决于您想要支持的客户端数量。
如果可行,您可能还想将 SFTP 作为替代方案。 SFTP 是一个完全不同的协议,它构建在 SSH 之上。它使用单个标准 SSH 端口 (22) 运行,该端口更容易在防火墙级别处理。 SFTP 还对所有通信进行加密,这对于传统 FTP 来说是不可能的。
答案2
这是 Haxiel 答案的另一个答案。如果使用加密(例如:使用AUTH TLS
)那么 Haxiel 的答案仍然必须使用:将 FTP 服务器配置与防火墙配置相匹配,以使用保留的端口范围。
某些协议(通常是旧协议)对防火墙不太友好。 FTP 就是其中之一:对于发送的每个命令,它都会在客户端和服务器之间协商一个额外的动态临时端口来发送数据。根据主动或被动 FTP 模式,为此数据连接进行的命令、回复和连接方向会有所不同。
Linux 内核 Netfilter 的 conntrack 子系统提供了一些特定的协议帮助程序来处理其中一些协议。当然它为FTP提供了这样一个帮手,nf_conntrack_ftp
:
帮助文本
跟踪 FTP 连接是有问题的:需要特殊的帮助程序来跟踪它们,并对它们进行伪装和其他形式的网络地址转换。
这是对第 3 层独立连接跟踪的 FTP 支持。
加载模块后nf_conntrack_ftp
,只要 FTP 未加密(即:不加密AUTH TLS
:加密可防止监听),内核的 Netfilter conntrack 子系统就会监听 TCP 端口 21 并分析所有命令以提前了解需要哪个端口,并且使用以下命令预先允许此类端口iptables'-m conntrack --ctstate RELATED
(或者nftables' ct state related
):
RELATED
该数据包正在启动新连接,但与现有连接相关联,例如 FTP 数据传输或 ICMP 错误。
当然防火墙在其规则集中使用此类规则,因为它同样也允许应用程序接收回 ICMP 错误等。
如果系统正在执行 NAT,nf_nat_ftp
则将扩展一个附加模块连线还可以拦截数据并更改协商端口,以便它对客户端和服务器透明地工作。
简而言之:
modprobe nf_conntrack_ftp
应该可以解决OP的问题。它适用于所有 FTP 情况(在客户端或服务器上,主动或被动 FTP)。要在 CentOS7 上启动时加载此模块,可以添加一个文件/etc/modules-load.d/
并让它由 systemd 处理。例如,作为 root:
# echo nf_conntrack_ftp > /etc/modules-load.d/local-nfhelpers.conf
# systemctl enable systemd-modules-load
# systemctl restart systemd-modules-load
如果服务器以某种方式执行 NAT(在其他端口上重定向 FTP 端口、路由专用 LAN、托管虚拟机或容器...),则还可以考虑添加该模块,nf_nat_ftp
以便 NAT 也能得到正确处理。
默认情况下,这就是 CentOS 7 内核 3.10 所需的全部内容。
笔记:
在较新的内核上,尤其是 >= 4.7 的内核,默认情况下禁用自动协议端口分配(例如:对于 FTP,跟踪端口 21)iptables应添加规则来选择应为给定流程激活帮助程序的确切情况。现在可以与防火墙的工作,所以它可能会变得更加复杂。人们当然可以重新启用前一种方式,但选择什么条件将激活窥探被认为更安全。
有关此内容的更多信息,请参阅此博客(由一些 netfilter 维护者制作):Linux 及更高版本!安全使用 iptables 和连接跟踪助手。