﻿# 解說 FTP Protocol 的運作原理

我想 FTP 可能有人每天都在用，但卻很少人知道 FTP 運作原理，更尤其是在連不上 FTP 的時候常常都是一頭霧水，在問別人時也可能會發現有人可以連、有人不能連，有的人連的上可以登入成功但是卻無法列出檔案清單，種種的問題只要能了解 FTP 的運作原理就可以很輕易的了解問題出在哪裡，進而解決問題。

**基本觀念**

使用 FTP 傳輸時，至少會使用到兩個 Port 來建立連線通道：

-   一個為指令通道(Command Channel)，預設使用 Port 21 建立連線，用來傳輸 FTP 指令，例如：列出檔案清單(LIST)、變更目錄(CWD)、取得目前的目錄(PWD)、......等。
-   另一個為資料通道(DATA Channel)，預設使用 Port 20，但是會因 FTP Client 選擇使用的「連線模式」不同而有所不同。

一般來說，指令通道的連線與下指令都沒有什麼問題，有問題的通常是在資料通道的建立，而資料通道的建立方式是由 FTP Client 所下的指令決定的，以 FileZilla 設定為例（如下圖）：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/06bcfc34d6626a5acc07-image_3.png)

FTP Client (e.g. FileZilla) 每次建立連線時都會下 PORT 或 PASV 指令，如下範例：

```
指令:    PASV
回應:    227 Entering Passive Mode (59,37,124,43,158,251)
```

而每次下指令傳輸資料時，都會建立一次 data connection，包括取得遠端的檔案清單(LIST)時回傳的檔案列表、下載檔案、或上傳檔案。

**連線模式**

FTP 的連線模式分兩種：主動模式 ( Active mode ) 與 被動模式 ( Passive mode )

-   **主動模式 ( Active mode )**

> FTP Client 跟 FTP Server 連線後，會主動利用 PORT 指令提出 DATA Channel 連線的要求，如下：
> 
> ```
> 指令:    PORT 10,18,53,171,17,114
> 回應:    200 Port command successful.
> ```
> 
> 這裡的 PORT 指令是由 FTP Client 送出的，當需要建立 DATA Channel 時，FTP Server 會主動利用 Server 主機的 Port 20 發出連線到 FTP Client 的主機，而 PORT 指令後的參數說明如下：
> 
> -   前四個數字是 FTP Client 的 IP 位址：10.18.53.171
> -   後兩個數字是 FTP Client 接受連線的 Port 埠號，埠號的計算方式是 (第五個數字 \* 256 + 第六個數字)，以此範例來說，FTP Client 接受的連線埠號是 17 \* 256 + 114 = 4,466
> 
> 由此可知，如果 FTP Client 處於 NAT 的環境下的話，FTP Server 幾乎無法正常的連線到 FTP Client 的主機，所以現在大部分的連線模式幾乎都建議使用者使用被動模式(Passive mode)。

-   **被動模式 ( Passive mode )**

> FTP Client 跟 FTP Server 連線後，會主動利用 PASV 指令提出 DATA Channel 連線的要求，如下：
> 
> ```
> 指令:    PASV
> 回應:    227 Entering Passive Mode (59,37,124,43,158,251)
> ```
> 
> 你可以看到由 FTP Client 送出的 PASV 指令並沒有送出其他的參數，而是在 FTP Server 回應的時候出現了 (59,37,124,43,158,251) 字串，當需要建立 DATA Channel 時，這時就會由 FTP Client 主動連接至 FTP Server 動態開放的 Port 供 FTP Client 連接，其中 (59,37,124,43,158,251) 的說明如下：
> 
> -   前四個數字是 FTP Server 的 IP 位址：59.37.124.43
> -   後兩個數字是 FTP Server 接受連線的 Port 埠號，埠號的計算方式是 (第五個數字 \* 256 + 第六個數字)，以此範例來說，FTP Server 可接受的連線埠號是 158 \* 256 + 251 = 40,699
> 
> 由此可知，使用被動模式(Passive mode)對 FTP Server 的系統管理員來說，可掌控的部分是比較多的，因為 FTP Server 無法決定使用者是否可使用主動模式連線，但若改使用被動模式連線的話，就幾乎能讓所有人正常的使用 FTP 服務。

**其他資訊**

-   在 IIS 的 FTP 服務中，當使用 Passive mode 時，IIS FTP 會自動開啟短暫的 Port 用以建立 DATA Channel 供 FTP Client 連接，IIS 預設會動態使用 Port 1024 ~ 65535 進行 DATA Channel 的連線，若要修改預設的 Port Range 可以參考我昨天的文章：[如何調整 IIS FTP 在 Passive mode 使用的 Port Range](/post/2008/06/28/Adjust-IIS-FTP-Passive-mode-Port-Range)。
-   在 Linux kernel 中，若有設定 MASQ 的話，Kernel 已經支援「動態開啟 FTP DATA PORT」功能，也就是說在 FTP Client 端在 NAT 內部也能以 Active mode 使用 FTP，這就是為什麼有些人在公司內部使用虛擬 IP 也能夠使用主動模式(Active mode)傳輸檔案的情形。

**相關連結**

-   Active FTP vs. Passive FTP, a Definitive Explanation
-   [如何調整 IIS FTP 在 Passive mode 使用的 Port Range](/post/2008/06/28/Adjust-IIS-FTP-Passive-mode-Port-Range)
