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