Firewall

設置用於與 Linux 的 ftp 客戶端進行被動 FTP 連接的埠

  • July 20, 2021

我正在嘗試連接到防火牆後面的 FTP 伺服器,該伺服器僅允許 6100-6200 範圍內的傳入連接。我已成功連接到此伺服器,使用curl如下:

curl --ftp-port :6100-6200 --list-only ftp.server

但我想用其他更友好的 Python 客戶端重現此 curl 命令的行為。原則上是 Linux 的ftp,但如果有人提出好的建議,我願意接受其他選擇。我試過 ftplib 但似乎這個庫不允許你選擇埠;我試過了,不成功

目前我不能使它與ftp

230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
227 Entering Passive Mode (XXX,XXX,XXX,XXX,202,251).
ftp: connect: Connection refused

同一組命令在我的筆記型電腦上工作,因此很明顯問題出在防火牆上。

如何強制ftp在 6100-6200 範圍內的埠中協商數據連接,從而模擬curl?

當您在被動模式下使用 FTP 時,伺服器會告訴客戶端使用哪個(伺服器端)數據埠。眾所周知的 FTP 協議不允許客戶端在伺服器端使用哪個埠範圍來表達請求。可能有一些擴展可以改變這一點,但不一定得到廣泛支持。

在您的範例中,消息

227 Entering Passive Mode (XXX,XXX,XXX,XXX,202,251).

直接來自 FTP 伺服器,因為它告訴客戶端:“我正在偵聽來自您的 IP 地址 XXX.XXX.XXX.XXX 埠 51683 的數據連接”(= 202*256 + 251)。

每個 TCP 連接都有兩個埠號:一個本地埠號和一個遠端埠號。通常,傳出連接只會選擇作業系統指定的埠範圍中的第一個空閒本地埠用於傳出連接,而遠端埠是根據正在使用的服務指定的。在被動 FTP 的情況下,伺服器將根據其配置選擇遠端埠,並以 FTP 227 響應的形式告訴客戶端。

在防火牆中處理被動 FTP 通常有兩種方法:

a) 防火牆和 FTP 伺服器需要共同配置以接受/使用特定範圍的埠用於被動 FTP 數據連接,因此伺服器甚至不會嘗試選擇防火牆不允許通過的埠,

或者 b) 防火牆需要監聽 FTP 命令通道流量,確定每個數據連接使用的埠號,並使用命令通道上聲明的埠號動態允許 FTP 客戶端和伺服器之間的被動 FTP 數據連接。

如果您使用的是 Linux iptables/netfilter防火牆,這正是 FTP 的特定協議 conntrack 擴展模組所做的。你只需要告訴它允許監聽哪些控制連接,因為之前監聽所有通過防火牆系統的 FTP 控制連接的策略被證明可以被壞人利用,現在這樣的擴展將不再是自動使用。有關詳細資訊,請參閱 U&L SE 上的此頁面此問題


curl實際上預設情況下在被動模式下使用 FTP ,但是當您使用該--ftp-port選項時,它會切換到主動模式。從手冊頁(突出顯示我的):

-P,–ftp 埠

(FTP) 與 FTP 連接時,顛倒預設的發起者/偵聽者角色。**此選項使 curl 使用活動模式。**curl 然後告訴伺服器連接回客戶端指定的地址和埠,而被動模式要求伺服器設置一個 IP 地址和埠以供其連接。


關於 Python 和ftplib,請注意您提到的問題已有 10 多年的歷史,現在 Marcus Müller 添加了一個新答案:

從 Python 3.3 開始,ftplib建立連接的函式需要一個source_addr參數來允許您執行此操作。

引用自:https://unix.stackexchange.com/questions/659153