當 client 向 server 提出主動連線請求時,會送出一個 TCP 的同步旗標 ( syn ) 給 server,此乃連線的第一個封包,接著 server 會回應一個帶有 syn 及 ack ( 回應旗標 ) 的封包給 client,最後再由 client 送出一個 ack 給 server,以作確認的動作,至此雙方的連線才正式成立,這就是所謂的 TCP Three-Way Handshake ( TCP 三段式交握 )。
任何電腦間要彼此能夠正常的溝通前,就必須先將連線建立起來,否則一切免談,所以我們往往可以利用這個特性把他運用在防火牆上,比如只要針對只含有 syn 同步旗標的 tcp 封包將其過濾掉,也就是主動連線的封包不允許其進入主機內,這樣就可以達到初步的防火牆功能。
了解了連線建立的過程後,底下我們就來說明 ftp 連線的過程。
當 client 端一開始要連上 ftp server 時,client 首先會隨機產生一個大於 1024 的 port ( 假設 3000 port ) 來對 server 做連線,由於 client 是屬於主動的一方,所以會送出一個含有 syn 同步旗標的封包給 server 的 21 port,然後完成三段式交握後,連線才正式建立起來。而這個 3000 port 與 21 port 所建立的通道叫命令通道。之所以會稱其為命令通道,當然是只能執行一些基本指令而已 ; 若是 client 端想要下載或上傳資料時還要建立另外一條資料通道來作為資料傳輸使用,不過資料通道的建立與 client 端所使用的 ftp 連線軟體有關係,因為一般 ftp 連線軟體有的預設是使用主動模式 ( active mode ),有的則是採取被動模式 ( passive mode ),所以底下我們分別就這兩種模式來說明資料通道建立的過程:
主動模式:
client 端提出主動模式的要求,可以把他想像成 client 要求 server 做主動連線,所以一開始 client 會透過命令通道跟 server 說我要採取主動模式,並且另外開一個大於 1024 的 port number,假設為 3500 port ( 有別於剛剛那個 3000 port ),等 server 主動來做連線,而在 server 收到這個訊息後就會以 20 port (大部分為 20 port,但也可以經由設定而使用另外的 port) 來主動跟 client 的 3500 port 做連線,因此時 server 是屬於主動的一方,所以一樣會送出一個 syn 旗標給 server,然後完成另外一次三段式交握後,此資料通道才正式建立起來,這樣 client 就可以開始做資料傳輸了。
被動模式:
client 端提出被動模式的要求,可以把他想像成 client 要求 server 做被動連線,也就是 client 希望能主動連 server,所以一開始 client 會透過命令通道通知 server 說我要採取被動模式,server 收到後就會開一個大於 1024 的 port ( 假設 5000 port ),並透過命令通道來通知 client 說我已經準備了一個 5000 port 等你主動來做連線,於是 client 就會隨機產生一個大於 1024 的 port ( 有別於 3000 port ) 來主動對 5000 port 送出一個含有 syn 旗標的 tcp 封包給 server,待完成了三段式交握後,資料通道就正式建立起來了。
了解了這個觀念後,底下我們來談談若 FTP Client 端是在 NAT 主機的後端,當其想要從 FTP Server 下載資料時會發生失敗的原因:
假設一開始 client 端是使用 3000 port 透過 NAT 主機來與 server 的 21 port 建立命令通道,因為 NAT 主機會記錄來源端的資訊,且 client 是屬於主動的一方,故此命令通道能夠被建立起來,若現在 client 端透過命令通道通知 server 說我要使用主動模式來做資料傳輸,且已經開好了 5000 port 等你來跟我做連線,此時 server 會主動以 20 port 來向 NAT 的 5000 port 送出一個含有 syn 旗標的 TCP 封包,但是 NAT 本身並沒有開啟這個 port,所以當然無法建立連線,自然就不能上傳及下載了。
要解決這個問題可以請 client 端改採被動模式,想想看為什麼 ? 另外一種解決的方式是在 NAT 主機上載入 ip_conntrack_ftp 及 ip_nat_ftp 模組。FTP的觀念就先介紹到這裡。