FTP聯(lián)機(jī)的兩種模式
FTP采用 Client/Server 架構(gòu),F(xiàn)TP 協(xié)議比較特別的地方在于它在使用時(shí)必須建立二個(gè)聯(lián)機(jī):一個(gè)用來(lái)傳輸指令、一個(gè)用來(lái)傳輸檔案。當(dāng)我們使用 FTP 軟件連到 FTP 服務(wù)器時(shí),客戶(hù)端會(huì)先連到服務(wù)器的連接端口21,并建立一條「控制聯(lián)機(jī)」。接下來(lái),您會(huì)輸入賬號(hào)、密碼等指令,這些指令及 FTP 的響應(yīng)都是使用都是使用「控制聯(lián)機(jī)」。當(dāng)您要下載檔案時(shí),或者是執(zhí)行 ls 以列出目錄中的檔案時(shí),檔案或目錄列表的下載是經(jīng)另一個(gè)聯(lián)機(jī)「數(shù)據(jù)聯(lián)機(jī)」?!笖?shù)據(jù)聯(lián)機(jī)」和「控制聯(lián)機(jī)」不同的是數(shù)據(jù)聯(lián)機(jī)所傳輸?shù)臄?shù)據(jù)比較大,而控制聯(lián)機(jī)只是用來(lái)傳輸指令及簡(jiǎn)單的響應(yīng)。
基本上,一個(gè)完整的 FTP 聯(lián)機(jī)建立過(guò)程為:
客戶(hù)端打開(kāi)自已機(jī)器大于 1024 的連接端口,并連到服務(wù)器的連接端口21,建立「控制聯(lián)機(jī)」。
客戶(hù)端開(kāi)始對(duì)服務(wù)器下指令,告訴服務(wù)器客戶(hù)端用來(lái)傳輸檔案的連接端口為何。
服務(wù)器從連接端口20 連到客戶(hù)端所開(kāi)放的端口號(hào) (大于 1024),以建立「數(shù)據(jù)聯(lián)機(jī)」。
上述這種聯(lián)機(jī)建立的方式是由服務(wù)器主動(dòng)建立「數(shù)據(jù)聯(lián)機(jī)」,我們稱(chēng)之為「主動(dòng)模式」(Active Mode)?;旧现鲃?dòng)模式的運(yùn)作在沒(méi)有防火墻或 NAT 的情形下沒(méi)有什么問(wèn)題,但若客戶(hù)端有防火墻,則可能會(huì)無(wú)法建立聯(lián)機(jī)。基本上,如果客戶(hù)端使用的是 FreeBSD 的 NAT 不會(huì)有這種問(wèn)題,F(xiàn)reeBSD 會(huì)自動(dòng)做轉(zhuǎn)換,但若是使用其它的防火墻就不一定可以支持 FTP 的 Active Mode。
要解決 FTP Active Mode 的問(wèn)題,可以在聯(lián)機(jī)時(shí)改用「被動(dòng)模式」(Passive Mode)。所謂的被動(dòng)模式就是由服務(wù)器打開(kāi)一個(gè)連接端口,被動(dòng)地等客戶(hù)端連過(guò)來(lái)建立「數(shù)據(jù)聯(lián)機(jī)」。被動(dòng)模式的聯(lián)機(jī)建立過(guò)程為:
客戶(hù)端打開(kāi)自已機(jī)器大于 1024 的連接端口,并連到服務(wù)器的連接端口21,建立「控制聯(lián)機(jī)」。
客戶(hù)端開(kāi)始對(duì)服務(wù)器下指令,告訴服務(wù)器進(jìn)入「被動(dòng)模式」。
服務(wù)器打開(kāi)一個(gè)大于 1024 的連接端口,等待客戶(hù)端的聯(lián)機(jī)。
客伺端打開(kāi)自已機(jī)器大于 1024 的連接端口,并連到服務(wù)器以建立「數(shù)據(jù)聯(lián)機(jī)」。
由于控制聯(lián)機(jī)及數(shù)據(jù)聯(lián)機(jī)都是由客戶(hù)端主動(dòng)連過(guò)去服務(wù)器,如此即可避開(kāi)防火墻及 NAT 的問(wèn)題。
當(dāng)您登入一臺(tái) FTP 服務(wù)器后,如果您輸入 ls,卻等了很久都沒(méi)有響應(yīng),您可以輸入 Ctrl>+C 以中斷命令。接著輸入 passive 以進(jìn)入被動(dòng)模式,再打 ls 如果可以看到目錄內(nèi)容,則無(wú)法聯(lián)機(jī)的問(wèn)題一定是主動(dòng)模式的原故。
設(shè)定 FTP 服務(wù)器
FreeBSD 內(nèi)建有 FTP 服務(wù)器的功能,如果您要使用內(nèi)建的 ftpd,我們不需要特別進(jìn)行任何安裝的動(dòng)作,只要做好設(shè)定即可。
1 啟動(dòng)FTP服務(wù)器
有二種方式啟動(dòng) ftpd,一種是使用 standalone daemon,另一種是使用 inetd。
使用 inetd 我們可以管理許多系統(tǒng)服務(wù),例如 telnet、ssh、ftp 等,大部份的系統(tǒng)服務(wù)都是使用 inetd 來(lái)啟動(dòng),使用它的好處在于可以統(tǒng)一管理各種服務(wù),并經(jīng)由它來(lái)設(shè)定服務(wù)規(guī)則,例如是否要阻擋某些 IP 來(lái)源等。不過(guò),使用 inetd 的方式缺點(diǎn)是每次有聯(lián)機(jī)要求時(shí),inetd 的 daemon 必須依聯(lián)機(jī)的種類(lèi)去執(zhí)行相對(duì)映的指令,所以速度比較慢。另一種啟動(dòng) FTP 的方式是使用 standalone daemon,也就是直接執(zhí)行 FTP daemon,當(dāng)它接收到新的聯(lián)機(jī)時(shí),就 fork() 出來(lái)處理,這種方式聯(lián)機(jī)建立的速度較快,比較適合專(zhuān)門(mén)的 FTP 服務(wù)器。
使用 inetd,首先編輯 /etc/inetd.conf,將 ftp 設(shè)定開(kāi)頭的 # 移除:
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l
接下來(lái),我們必須使用下列指令重跑 inetd:
#
kill -1 `cat /var/run/inetd.pid`
現(xiàn)在您就可以開(kāi)始使用 FreeBSD 的 FTP 服務(wù)了。
如果您要以獨(dú)立的 daemon 方式啟動(dòng) FTP,請(qǐng)先確定在 inetd.conf 中沒(méi)有啟動(dòng) FTP 服務(wù)。接下來(lái),請(qǐng)?jiān)谛略鲆粋€(gè)檔案 /usr/local/etc/rc.d/ftpd.sh 內(nèi)容如下:
#!/bin/sh
ftpd_program="/usr/libexec/ftpd"
ftpd_flags="-D -l"
case $1 in
start)
echo "Starting FTPD"
$ftpd_program $ftpd_flags
;;
stop)
echo "Stopping FTPD"
killall ftpd
;;
restart)
$0 stop
sleep 1
$0 start
;;
esac
編輯完后,我們必須將該檔案變成可執(zhí)行:
#
chmod 755 /usr/local/etc/rc.d/ftpd.sh
接下來(lái),您就可以使用下列指令啟動(dòng) FTPD 了:
#
/usr/local/etc/rc.d/ftpd.sh tart
如果您要停止 FTPD 服務(wù),則使用下列指令:
#
/usr/local/etc/rc.d/ftpd.sh stop
2 編輯歡迎信息
當(dāng)我們聯(lián)機(jī)到一個(gè) FTP 站點(diǎn)時(shí),我們可以看到二個(gè)歡迎訊息,一個(gè)是登入前的訊息,另一個(gè)是登入后的訊息。開(kāi)頭為 220- 的就是登入前的訊息,我們稱(chēng)它為歡迎訊息。以 230- 為開(kāi)頭的是登入后的訊息,我們稱(chēng)它為本日訊息 (Message of the day)。這二種訊息我們都可以自行設(shè)定。
如果您要設(shè)定的是登入前的訊息,請(qǐng)新增一個(gè)檔案 /etc/ftpwelcome,并將您的訊息寫(xiě)入該文件中。您不需要寫(xiě) 220- 等數(shù)據(jù),F(xiàn)TP 服務(wù)器會(huì)自動(dòng)幫您加上這種代碼。而登入后的訊息是存放在 /etc/ftpmotd,您可以編輯該檔以進(jìn)行設(shè)定。
3 FTP服務(wù)器管理
在啟動(dòng) FTP 服務(wù)器時(shí),我們可以加入一些參數(shù)以調(diào)整服務(wù)器的行為。例如,修改預(yù)設(shè)的連接端口、記錄使用者上傳、下載的檔案等等。有些參數(shù)必須要在使用獨(dú)立的 daemon 方式啟動(dòng)時(shí)才有用,而有的參數(shù)在 inetd 模式下也可以使用。下表為我們常用的參數(shù):
參數(shù) |
是否只能在 Daemon 模式下使用 |
意義 |
-a |
是 |
當(dāng)您有二張網(wǎng)絡(luò)卡或是二個(gè) IP 時(shí),我們可以設(shè)定只接受聯(lián)機(jī)到某一個(gè) IP 的聯(lián)機(jī)要求。例如: ftpd -D -a 192.168.0.1
此范例表示只接受使用者聯(lián)機(jī)到 192.168.0.1 這個(gè) IP。
|
-d |
否 |
記錄 FTP 的除錯(cuò)訊息。除了加入這個(gè)參數(shù)外,您必須修改 /etc/syslog.conf,并加入下列內(nèi)容以記錄 FTP 的訊息。
!ftpd*.* /var/log/ftpd.log
|
-h |
否 |
不要顯示 FTP 服務(wù)器的主機(jī)名稱(chēng)、軟件信息、版本等。 |
-l |
否 |
記錄 FTP 登入成功及失敗的訊息。如果您使用二次 -l,則使用者上傳、下載、刪除、建立目錄時(shí)都會(huì)留下記錄。預(yù)設(shè)的記錄會(huì)留在 /var/log/xferlog 中。 |
-P |
是 |
我們知道 FTP 預(yù)設(shè)會(huì)****連接埠 21,以接受客戶(hù)端的聯(lián)機(jī)要求。不過(guò)如果您是以獨(dú)立的 daemon 方式啟動(dòng) FTP,則 可以使用 -P 加上連接埠號(hào)以改變預(yù)設(shè)連接埠。 |
另外,還有很多用來(lái)控制使用者權(quán)限的參數(shù),將在后面說(shuō)明。
如果您要修改 ftpd 啟動(dòng)的參數(shù),在 inetd 模式下,您可以修改 /etc/inetd.conf,并在 ftp 設(shè)定的最后面加入?yún)?shù),如下列粗體字所示:
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -l -d
ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l -l -d
上面的范例中,我們多加入了參數(shù) -l -d,以記錄更多 ftpd 的訊息。
如果您是以獨(dú)立的 Daemon 方式啟動(dòng) ftpd,則請(qǐng)修改 /usr/local/etc/rc.d/ftpd.sh:
#!/bin/sh
ftpd_program="/usr/libexec/ftpd"
ftpd_flags="-D -l -l -d"
...
我們只要修改 ftpd_flags 的部份,加入您所要的參數(shù)即可。
4 FTP權(quán)限控制
預(yù)設(shè)的 FTP 啟動(dòng)后,使用者可以上傳、下載任何他們有權(quán)存取的檔案。在登入后,使用者可以進(jìn)到任何系統(tǒng)中的目錄 (如果目錄權(quán)限允許的話(huà))。
我們可以設(shè)定限制某些賬號(hào)不可以使用 FTP 登入。使用者在登入 FTP 服務(wù)器時(shí),有幾個(gè)規(guī)則會(huì)拒絕該賬號(hào)登入:
如果 /var/run/nologin 存在,則所有賬號(hào)都不可以登入。這個(gè)檔案可以用來(lái)暫時(shí)停止 FTP 服務(wù)。
使用者一定要有密碼才能登入,沒(méi)有密碼的使用者無(wú)法登入。
使用者名稱(chēng)不可以出現(xiàn)在 /etc/ftpusers 中。
使用者群組不可以出現(xiàn)在 /etc/ftpusers 中。
使用者所使用的 shell 必須要時(shí)合法的 shell。合法的 shell 會(huì)被定義在 /etc/shells 中。
除了匿名模式外,使用者名稱(chēng)不可以是 ftp 或 anonymous。
/etc/ftpusers 定義了不可以使用 FTP 服務(wù)的使用者及群組。看一下該檔案的內(nèi)容,我們可以看到該檔案中已經(jīng)有一些使用者不可以登入 FTP。這些使用者都是系統(tǒng)預(yù)設(shè)的賬號(hào),我們也可以經(jīng)由修改它來(lái)加入其它使用者。在 /etc/ftpusers 中,如果開(kāi)頭是 "@" 表示群組名稱(chēng)。
除了控制使用者賬號(hào)外,在「inetd」模式下,我們還可以控制聯(lián)機(jī)來(lái)源。所有 FreeBSD 中由 inetd 所啟動(dòng)的服務(wù)都可以經(jīng)由修改 /etc/hosts.allow 以使用 TCP Wrappd 來(lái)限制聯(lián)機(jī)來(lái)源。下列為預(yù)設(shè)的 /etc/hosts.allow 內(nèi)容:
# Provide a small amount of protection for ftpd
ftpd : localhost : allow
ftpd : .nice.guy.example.com : allow
ftpd : .evil.cracker.example.com : deny
ftpd : ALL : allow
如果我們要限制某幾個(gè) IP 或網(wǎng)域不能使用 FTP,可以使用下列范例:
# Provide a small amount of protection for ftpd
ftpd : localhost : allow
ftpd : 210.122.13.5 : deny
ftpd : .evil.cracker : deny
ftpd : ALL : allow
如果您要設(shè)定只有某些來(lái)源可以使用 FTP,而拒絕大多數(shù)的主機(jī),則可以設(shè)定:
# Provide a small amount of protection for ftpd
ftpd : localhost : allow
ftpd : 192.168.0. : allow
ftpd : my.friend.com : allow
ftpd : ALL : deny
在使用者登入后,只要目錄、檔案權(quán)限許可,它們可以自由的上傳、下載檔案。如果您希望加以限制讀寫(xiě)的權(quán)限,可以在啟動(dòng) FTP 時(shí)加上下列幾個(gè)參數(shù):
參數(shù) |
意義 |
-o |
限制所有使用者只能上傳檔案,而無(wú)法下載任何檔案。 |
-r |
限制所有使用者對(duì)于服務(wù)器內(nèi)所有檔案只能只讀,不可以建立目錄、上傳、更改檔名、或任何會(huì)動(dòng)到檔案目錄的指令。 |
上述的參數(shù)必須在啟動(dòng) FTP 服務(wù)器時(shí)指定
一般使用者登入后,預(yù)設(shè)會(huì)進(jìn)入自己的家目錄中。使用者可以改變工作路徑到系統(tǒng)的任何目錄中。如果您希望使用者登入后只能在自己的家目錄中活動(dòng),而不能進(jìn)入其它系統(tǒng)目錄中,可以使用 chroot 的功能。所謂的 chroot 就是將某一個(gè)目錄變成使用者看到的根目錄。例如,我們讓使用者 alex 登入后,將 /home/alex 變成根目錄。則 alex 在使用指令「cd /」時(shí),還是會(huì)停留在 /home/alex。如果他使用指令「pwd」查看目前所在路徑,則會(huì)顯示 /。如此一來(lái),我們就可以確保使用者不會(huì)到處亂跑,進(jìn)入一些不該進(jìn)入的地方。這個(gè)功能對(duì)于提升 FTP 的安全性有莫大的助益。
設(shè)定 chroot 的方法很簡(jiǎn)單,只要修改 /etc/ftpchroot 即可。下面是一個(gè)范例:
alex
@guest
john /var/ftp
@other /var/ftp
其中第一行是設(shè)定使用者 alex 登入后,以自己的家目錄為根目錄。第二行的 @guest 表示只要是群組為 guest 的使用者,都以自己的家目錄為根目錄。而第三、四行分別表示使用者 john 及群組 other 都以 /var/ftp 為根目錄。
只要我們善用 chroot 的功能,就可以加強(qiáng)保護(hù)系統(tǒng)其它目錄,讓沒(méi)有權(quán)利的使用者不可以進(jìn)入系統(tǒng)目錄中。建議您在開(kāi)放 FTP 服務(wù)時(shí),將所有使用者都加入 /etc/ftpchroot 中。
我們平常在登入 FreeBSD 的 FTP 站臺(tái)時(shí),可以使用 anonymous 或是 ftp 這二個(gè)使用者登入,而且在登入時(shí),任何密碼都可以通過(guò)。這種可以使用 anonymous 登入的 FTP 就叫作匿名 FTP。anonymous 及 ftp 這二個(gè)賬號(hào)是預(yù)設(shè)的匿名賬號(hào),當(dāng)使用者以匿名登入時(shí),服務(wù)器會(huì)將匿名賬號(hào)對(duì)映到系統(tǒng)內(nèi)的真實(shí)使用者 ftp。所以,如果您要提供匿名的 FTP 服務(wù),請(qǐng)使用下列指令新增使用者賬號(hào) ftp:
#
pw adduser ftp
#
mkdir /home/ftp
#
chown ftp:ftp /home/ftp
我們建立了使用者 ftp 及其家目錄 /home/ftp。使用 pw 指令所建立的使用者在 /etc/master.passwd 中的密碼字段預(yù)設(shè)為 *,表示不可以登入。這個(gè)使用者除了匿名 FTP 外,將不可以使用 telnet、SSH、或是其它服務(wù)。
在新增了使用者 ftp 之后,我們就已經(jīng)支持匿名 FTP 的功能了?,F(xiàn)在您可以使用 anonymous 或 ftp 賬號(hào)登入,而且不需任何密碼。由于開(kāi)放了匿名 FTP 后,任何人都可以登入系統(tǒng),所以匿名賬號(hào)登入后一定會(huì)使用 chroot,以將匿名使用者限制在家目錄中。
除了強(qiáng)制使用 chroot 外,我們還可以在啟動(dòng) FTP 時(shí)加上一些參數(shù),以針對(duì)匿名使用者進(jìn)行更多的限制。下表為啟動(dòng) FTP 服務(wù)時(shí)可以使用的參數(shù):
參數(shù) |
意義 |
-M |
禁止匿名使用者建立新的目錄。 |
-m |
允許匿名使用者覆寫(xiě)一個(gè)存在的檔案。預(yù)設(shè)啟動(dòng) FTP 時(shí),并不允許匿名使用者覆寫(xiě)已經(jīng)存在的檔案。當(dāng)使用者上傳檔案時(shí),如果已經(jīng)有同檔名的檔案存在,系統(tǒng)會(huì)自動(dòng)為上傳的檔案改名。 |
-O |
讓匿名使用者只能上傳檔案,下載檔案的功能會(huì)被取消。 |
匿名使用者權(quán)限除上表中的幾個(gè)參數(shù)外,一樣可以使用 -r、-o 等用來(lái)控制一般使用者權(quán)限的參數(shù)來(lái)控制匿名使用者。
匿名的 FTP 服務(wù)器可以說(shuō)是危險(xiǎn)的開(kāi)始,如果您沒(méi)有對(duì)匿名的使用者進(jìn)行權(quán)限控制,在開(kāi)于匿名 FTP 后,將會(huì)產(chǎn)生許多安全性的問(wèn)題。
以上只是針對(duì)FreeBSD系統(tǒng)自帶的簡(jiǎn)單ftpd進(jìn)行的配置應(yīng)用,如果希望架設(shè)更強(qiáng)大的FTP服務(wù)器,可以選用proftpd等工具來(lái)實(shí)現(xiàn),而且在/usr/ports/ftp目錄下就已經(jīng)加入了proftpd這個(gè)工具,具體配置參考本人后續(xù)文章。