版權聲明:可以任意轉載,但轉載時必須標明原作者charlee、原始鏈接http://tech.idv2.com/2004/12/02/make-ftp-with-proftpd-in-lan/以及本聲明。
由于最近很多人詢問關于如何在內網架設FTP的問題,因此在這里把經驗總結一下供大家分享。
本文將分為四個部分。第一部分闡述“什么是內網架設FTP”的問題。第二部分分析FTP協議的原理。第三部分闡述在內網中架設FTP服務器時會遇到的問題以及解決方法,使外網的用戶能夠訪問位于內網的FTP服務器。第四部分為總結。建議讀者能夠將這五部分全部讀完。如果只想要一個快速安裝指南,那么請閱讀第一部分和第四部分。
本文所使用的FTP服務器為proftpd。
內網FTP服務器的概念
設想下面的這種環(huán)境:幾臺計算機組成一個局域網,該局域網中擁有一臺DHCP服務器負責為局域網中每臺計算機分配IP地址。其中有一臺計算機(或網絡設備)作為網關(可以與DHCP服務器為同一臺設備),網關通過撥號或其他方式連接到Internet,獲取一個真實IP地址。局域網內的計算機通過網關的轉發(fā)來實現與Internet的連接。我們定義該局域網內部為內網,相對地,定義Internet為外網。
舉個例子,假設我們擁有兩臺計算機A、B和一個擁有撥號和DHCP功能的網關G。各自的網絡配置如下:
網關G:
局域網IP地址:192.168.0.1(由網關硬件指定)
局域網子網掩碼:255.255.255.0(由網關硬件指定)
廣域網IP地址:12.34.56.78(撥號之后獲得)
計算機A:
局域網IP地址:192.168.0.10(通過網關的DHCP功能獲得)
局域網子網掩碼:255.255.255.0(通過網關的DHCP功能獲得)
網關:192.168.0.1(通過網關的DHCP功能獲得)
計算機B:
局域網IP地址:192.168.0.11(通過網關的DHCP功能獲得)
局域網子網掩碼:255.255.255.0(通過網關的DHCP功能獲得)
網關:192.168.0.1(通過網關的DHCP功能獲得)
這樣,從A、B發(fā)出的所有網絡請求都會被發(fā)送到網關G(192.168.0.1),網關再將這些請求變換之后通過12.34.56.78發(fā)送到Internet,以實現A、B與Internet的連接。
需要提醒一點的是,你的網關必須擁有端口映射(Port Mapping)的功能(也稱轉發(fā),Forwarding),這是下文架設服務器的先決條件。所謂端口映射功能,就是指網關能夠將從外網發(fā)送到網關的指定端口的包轉發(fā)到內網中指定的IP地址上。舉個例子,假如我們定義了如下一條規(guī)則:將端口21映射到192.168.0.10上。那么
從外網發(fā)送到網關的一個包,其信息為源地址:200.12.34.56:7890,目的地址:12.34.56.78:21
那么網關將修改該包的目的地址,結果為源地址:200.12.34.56:7890,目的地址:192.168.0.10:21
并將該包發(fā)送到局域網中的192.168.0.10上。這樣對于192.168.0.10來說,這個包仿佛是從Internet上直接發(fā)給自己的一樣。
FTP協議原理
一般我們說,FTP協議使用TCP端口21。實際上這這并不準確;FTP協議使用TCP的21端口傳送的是控制命令,同時使用隨機端口來傳送數據。也就是說,下載一個文件至少需要在客戶端與服務器之間建立兩個TCP連接,這兩個連接分別稱為控制連接和數據連接。
控制連接總是由客戶端主動連接服務器的21端口來建立的;而數據連接則不一定。根據數據連接的建立方式的不同,FTP傳送方式可分為主動方式和被動方式兩種。主動方式下,服務器連接客戶端的某個端口以建立數據連接;被動方式下,客戶端連接服務器的某個端口來建立數據連接。
主動方式的連接過程如下:
- 客戶端用隨機端口連接服務器的21端口,建立控制連接,并發(fā)送用戶名和密碼進行登錄。
- 客戶端打開一個隨機端口P進行監(jiān)聽,并通過控制連接將自己的IP地址和P端口的信息通知服務器。
- 服務器用自己的隨機端口連接客戶端的端口P,建立數據連接,并進行數據傳送。
- 數據傳送完畢之后,數據連接斷開。
- 客戶端通過控制連接發(fā)送結束命令,以斷開控制連接,FTP交互過程結束。
被動方式的連接過程如下:
- 客戶端用隨機端口連接服務器的21端口,建立控制連接,并發(fā)送用戶名和密碼進行登錄。(與主動方式相同)
- 客戶端通過控制連接通知服務器使用被動方式。
- 服務器選擇一個隨機端口P進行監(jiān)聽,并通過控制連接將自己的IP地址和P端口的信息通知客戶端。
- 客戶端用自己的隨機端口連接服務器的端口P,建立數據連接,并進行數據傳送。
- 數據傳送完畢之后,數據連接斷開。(與主動方式相同)
- 客戶端通過控制連接發(fā)送結束命令,以斷開控制連接,FTP交互過程結束。(與主動方式相同)
舉個實際的例子來說明。下文中以S:開頭的為服務器返回的信息,C:開頭的為客戶端命令。主動方式:
S: 220 ProFTPD 1.2.10 Server(控制連接建立,服務器返回歡迎信息)
C: USER foo(發(fā)送用戶名)
S: 331 Password required for foo.
C: PASS mypassword (發(fā)送密碼)
S: 230 User foo logged in. (登錄成功)
C: SYST (獲取服務器類型)
S: 215 UNIX Type: L8
C: PWD (獲取當前目錄)
S: 257 "/" is current directory.
C: PORT 192,168,0,11,10,171 (客戶端監(jiān)聽端口2731,并將IP地址和端口2731通過PORT命令通知服務器。2731為10*256+171)
S: 200 PORT command successful
C: TYPE A (設置傳輸方式為文本方式)
S: 200 Type set to A
C: LIST (發(fā)出獲取文件列表的命令)
S: 150 Opening ASCII mode data connection for file list (服務器嘗試連接客戶端的2731端口以建立數據連接)
(通過數據連接發(fā)送文件列表……)
S: 226 Transfer complete. (文件列表傳送完畢,數據連接斷開)
C: QUIT (退出命令)
被動方式:
S: 220 ProFTPD 1.2.10 Server(控制連接建立,服務器返回歡迎信息)
C: USER foo(發(fā)送用戶名)
S: 331 Password required for foo.
C: PASS mypassword (發(fā)送密碼)
S: 230 User foo logged in. (登錄成功)
C: SYST (獲取服務器類型)
S: 215 UNIX Type: L8
C: PWD (獲取當前目錄)
S: 257 "/" is current directory.
C: PASV (通知服務器使用被動方式)
S: 227 Entering Passive Mode (192,168,0,10,132,29).
(服務器監(jiān)聽端口33821,并將IP地址和端口33821通過PORT命令通知服務器。33821為132*256+29)
C: TYPE A (設置傳輸方式為文本方式)
S: 200 Type set to A
C: LIST (發(fā)出獲取文件列表的命令)
S: 150 Opening ASCII mode data connection for file list (客戶端嘗試連接服務器的33821端口以建立數據連接)
(通過數據連接發(fā)送文件列表……)
S: 226 Transfer complete. (文件列表傳送完畢,數據連接斷開)
C: QUIT (退出命令)
內網FTP服務器的問題及解決方案
在這里我們沿用第一部分的網絡實例,并假設FTP服務器架設在計算機A(192.168.0.10)上。
如何使外網的客戶端能夠與內網的FTP服務器建立控制連接
由于控制連接的服務器端端口為21,因此我們只需要在網關的端口映射上添加一條規(guī)則,將21端口映射到192.168.0.10即可。
如何建立數據連接
在主動方式下,數據連接由服務器發(fā)起,相當于內網的服務器主動去連接外網的客戶端,這種連接可以穿過網關正常建立,因此不需要做任何特殊設置即可實現。問題是被動連接。由于被動方式下服務器會監(jiān)聽隨機端口并需要將自己的IP地址和端口號通知客戶端,這樣就產生了以下兩個問題: a) 服務器僅知道自己的內網IP地址(192.168.0.10),它會將這個IP地址通知給外網的客戶端,而客戶端從外網是無法連接這個內網IP地址的(客戶端不知道該如何路由); b) 服務器需要監(jiān)聽隨機端口,范圍為1024-65535,出于安全起見,也考慮到可能存在其它的服務也使用該范圍內的端口,因此不可能在網關上將這些端口全部映射給192.168.0.10。
由于以上的問題的存在,我們經常可以看到連接服務器時下方的連接日志停在
150 Opening ASCII mode data connection for file list
處遲遲不動,這就是因為被動數據連接無法建立。
對此proftpd提供了如下的解決方案。
- 通過MasqueradeAddress命令指定服務器通知給客戶端的IP地址。即使得FTP服務器不再將自己的內網IP地址192.168.0.10通知給客戶端,而是將MasqueradeAddress命令指定的IP地址通知給客戶端。在proftpd.conf中添加如下命令:
MasqueradeAddress 12.34.56.78 (指定為網關的外網地址)
如果網關的外網地址不固定(例如通過撥號獲取IP的情況),那么你需要為你的網關申請一個動態(tài)域名,并用MasqueradeAddress命令將域名指定給服務器。
MasqueradeAddress myftpserver.vicp.net
- 通過PassivePorts命令來限制被動方式下監(jiān)聽的端口的范圍。例如
PassivePorts 60000 65535
這樣服務器在被動方式下將僅使用60000-65535之間的端口,而不是原來的1024-65535。然后在網關上添加規(guī)則,將60000-65535的所有端口映射到192.168.0.10上。
這樣,外網的客戶端就可以正常訪問FTP服務器了。
但是上面的方法并不是十全十美的。我們用MasqueradeAddress命令強制FTP通知網關的IP地址,這對于客戶端位于外網的情況下是正確的,但是當客戶端位于內網時,客戶端可能會無法解析網關的IP地址,導致無法建立數據連接。
總結
內網架設FTP服務器的方法:
- 在proftpd.conf中利用MasqueradeAddress命令將網關的IP地址或域名指定給FTP服務器,例如
MasqueradeAddress myftpserver.vicp.net
或
MasqueradeAddress 12.34.56.78
然后通過PassivePorts命令來限制被動方式下監(jiān)聽的端口的范圍,例如
PassivePorts 60000 65535
- 在網關的端口映射上將第一步中指定的端口范圍(例中為60000-65535)以及FTP端口21映射到FTP服務器的內網地址上。