FTP資料埠連線

雲逸之發表於2020-09-29

FTP基於TCP,可以配置SSL,此時便可成為FTPS。同於HTTP配置SSL後協議名變為HTTPS。

但FTP互動通常會使用兩個通道。命令通道與資料通道

命令通道的建連:

  • 常說的FTP埠一般指命令通道的埠,命令通道的監聽是在FTP服務啟動的時候開始監聽。
  • FTP連線的發起,由客戶端主動發起,先建立TCP三次握手。
  • 如果是配置SSL/TLS。需要客戶端在SSL握手前傳送 AUTH TLS ,服務端也會從TCP明文通道回覆 234 AUTH。(‘234’ 是FTP服務端響應 的狀態碼。)
  • 之後客戶端才會發起SSL握手,建立加密通道後,再進行其他命令互動,進行一些設定,使用者登入。
  • 再通過一些命令查詢檔案列表,傳輸檔案。而檔案列表以及檔案的資料流,並不是通過命令通道進行輸入輸出。這些資料需要通過資料通道來傳輸。

資料通道


以下是一段點選ftp客戶端上顯示的資料夾(tem),進入一個新的FTP目錄的FTP命令的日誌

[16:34:45] [R] CWD tem
[16:34:45] [R] 250 Directory changed to /tem
[16:34:45] [R] PWD
[16:34:45] [R] 257 "/tem" is current directory.
[16:34:45] [R] PASV
[16:34:45] [R] 227 Entering Passive Mode (10,148,129,95,234,88)
[16:34:45] [R] 正在開啟資料連線 IP: 10.148.129.95 埠: 59992
[16:34:45] [R] MLSD
[16:34:45] [R] TLSv1.2 協商成功...
[16:34:45] [R] TLSv1.2 已加密會話正在使用密碼 ECDHE-RSA-AES256-GCM-SHA384 (256 位)
[16:34:45] [R] 150 File status okay; about to open data connection.
[16:34:45] [R] 226 Closing data connection.

執行CWD(改變工作目錄)和PWD(列印當前工作目錄)後,傳送了一個PASV命令,響應的報文中,帶了一個地址。而執行MLSD的時候進行了TLS協商。

MLSD 是獲取檔案列表的命令,具體解析如下:

Causes a list to be sent from the server to the passive DTP

獲取檔案列表之前傳送PASV。PASV則是建立資料通道的連線的一種方式。PASV命令返回了一個服務端的地址,FTP服務端在這個地址完成了一個監聽,然後等待客戶端去連,這種成為被動模式。

被動模式

如上述,客戶端傳送PASV,服務端隨機一個1024以上的埠監聽,然後將地址發給客戶端。有些FTP伺服器是可以配置隨機埠的範圍。但被動模式下這種隨機埠,可能被服務端防火牆遮蔽,造成FTP可以登入無法傳檔案

其中FTP地址編碼,如下(apache FTP server的實現)。是將IP的’.‘替換成’,’,將埠(埠範圍1~0xffff,16位) 前8位的值用埠數字右移8位取出,放入第四個逗號與第五個逗號之間,而剩下的8位值與0xff做與運算取出拼在最後。上述埠為234,88 通過(234<< 8) | 88 可得出埠號。(可以使用Python nodejs jjs等命令列進行快捷計算。)

public static String encode(InetSocketAddress address) {
        InetAddress servAddr = address.getAddress();
        int servPort = address.getPort();
        return servAddr.getHostAddress().replace('.', ',') + ','
                + (servPort >> 8) + ',' + (servPort & 0xFF);
    }

將FTP客戶端設定為主動模式後,進行上述操作,其日誌如下:

[17:18:52] [R] CWD /tem
[17:18:52] [R] 250 Directory changed to /tem
[17:18:52] [R] PWD
[17:18:52] [R] 257 "/tem" is current directory.
[17:18:52] [R] 正在偵聽埠: 13565,正在等待連線。
[17:18:52] [R] PORT 10,148,129,225,52,253
[17:18:52] [R] 200 Command PORT okay.
[17:18:52] [R] MLSD
[17:18:52] [R] TLSv1.2 協商成功...
[17:18:52] [R] TLSv1.2 已加密會話正在使用密碼 ECDHE-RSA-AES256-GCM-SHA384 (256 位)
[17:18:52] [R] 150 File status okay; about to open data connection.
[17:18:52] [R] 226 Closing data connection.
主動模式

主動模式,客戶端會在本地啟一個埠的監聽,然後將地址通過PORT 命令傳送給服務端,用來建立資料通道的連線。

據網上資料,客戶端與服務端命令通道建連 的本地的隨機埠數值(N),在主動模式下會監聽(N+1)的埠。

經過實測,發現是連線後的首次開啟資料埠監聽會監聽N + 1埠。再次需要開啟資料埠重新傳輸資料,本人並未得出明顯規律。

也就是說在這種情況下,客戶端會監聽相對未知 的埠,也會面臨被客戶端資料埠所在機器的防火牆遮蔽的問題

NAT組網下,資料埠無法建連 的問題

  • 本人對NAT組網認識比較淺粗,對這種場景不能做很細節的分析。

  • 本人將NAT理解為在內網中,通過內網中已經接入外網的NAT路由器將內網地址轉成外網,來與外界通訊。

  • 這種場景,內網與網外的地址並不是通的,FTP建立資料埠連線的時候,通過PASV或者PORT命令互動的地址存在報文中,當另一端去訪問那個地址時,就不能建立連線。這種情況下,需要在NAT路由器的地方使用應用閘道器 **ALG(Application Level Gateway)**將地址進行轉換,來建立連線。

設定資料埠的加密 PROT 命令

FTPS情況下並不一定安全,資料埠在命令通道加密的情況下,也可以走建立非加密通道。

涉及一個命令 PROT (protection )。這個命令容易與PORT命令混淆,這個命令用於設定資料通道的加密與非加密。

Data channel protection level.

引數有兩種 C和P。PROT C PROT P 目前沒有找到文件對C和P的詳細解釋,從原始碼中,得出C的情況 ,啟資料埠監聽是普通TCP通道的監聽,而P的情況下會建立SSL通道的監聽。當發起連線的時候,需要SSL握手,再進行資料流傳輸。

相關文章