2012-09-24

使用 yum 來做套件管理以及建置 yum Server

使用 yum 來做套件管理以及建置 yum Server


yum(全名 Yellowdog Updater Modified)是新一代 Linux 用來管理軟體套件(rpm 格式)相當方便的工具,它解決了使用 rpm 指令安裝、移除、更新各類軟體套件時,所遇到一些雜七雜八的狀況與問題,以安裝軟體來說,最常遇到的應該是「套件相依性」(dependencies)問 題,yum 會自動下載各個相依的套件包後再一併安裝,使得管理者不需自行下載相依的各個軟體套件後,再手動地執行安裝這類瑣碎又繁複的動作。 
  
溫馨提示:yum 將 rpm 程式包裝的更「人性化」並且更方便使用。

接下來就先從一台 RHEL5 安裝好之後開始談起吧!安裝的流程使用預設安裝方式即可,這樣子灌好的主機大約只佔兩GB左右磁碟空間;套件大概裝了七百個左右(如下圖) 

溫馨提示:RHEL5 安裝光碟較不易取得,若讀者手邊沒有 RHEL5 的話,使用 CentOS 或是 Fedora 取代也可以。



單機使用 YUM

如果管理者能夠記憶大多數的套件名稱(或是記得套件名稱的部份關鍵字),那麼使用 yum 來安裝、移除、更新軟體套件將會相當的方便,例如:想到 ftp Server 就想到關鍵字 ftpd、想到編譯工具就想到 gcc、想到 web Server 就想到關鍵字 httpd 或 Apache、想到 Office 軟體就想到 OpenOffice 等等。
輸入指令 yum 按下 Enter 後,會看到底下這樣的說明,說明內常用的功能像是 install(安裝)、remove(移除)、list(列出)、search(搜尋)、clean(清除)update(更新)等等



 在 Linux 安裝完成之後,將安裝光碟內所有的資料,都拷貝到硬碟內,這樣下次有需要加裝套件時,就不用再去光碟片內一片一片的找套件來安裝,這種作法其實在早期的 Windows 系統就已經習以為常,這樣子做確實是還蠻方便的。
  
拷貝光碟資料至硬碟

接下來我們使用 cp 或 rsync 指令將光碟資料拷貝到硬碟存放;放入第一片光碟後,沒有自動掛載光碟片的話就手動掛載(mount)吧!使用指令「mount /dev/cdrom /mnt」將光碟資料掛載在 /mnt 底下,接著使用指令「cp -r /mnt/. /data/」將光碟資料拷貝到 /data/ 底下,請注意那個 /mnt/ 後面的『.』要記得輸入,有「點」與沒有「點」差蠻多的,至於差異自行試試並觀察 /data/ 底下資料狀態便知!



溫馨提示:若光碟來源是 DVD 的話,通常是一片 DVD 就包含所有資料。

使用 eject 指令吐出光碟片是一個蠻方便的方法,而指令「eject -t」可將光碟吸進去,在拷貝第二片時,會有詢問是否覆蓋的訊息,即使加上 -f(force)參數也無效,經查詢後發現原來是 bash 命令別名功能(alias)造成的,暫時性的加上反斜線(\)跳脫即可(如下圖)。



溫馨提示:指令 rsync 對於資料同步很方便使用,例如使用指令 rsync -av /mnt/. /data/ 也可以拿來複製資料。

在資料都拷貝到硬碟後,該是使用 yum client 做套件管理的時候,請注意此時的架構是本機是 yum client 抓取本機電腦的硬碟資料(例 /data/ 底下)來做套件管理。要使用 yum client 之前,要先知道 yum client 會向「資料來源」(本處是指 /data/ 下)抓取 repodata 目錄內的 xml 檔案作為套件檔案列表,至於如何做出 repodata 目錄與 repodata 目錄下的 xml 檔案,則是使用 createrepo 指令。

createrepo 套件與指令應用

預設 RHEL5 是沒有安裝 createrepo 套件的,所以要使用 createrepo 指令的話,我們先使用指令「find /data/ -iname "*createrepo*"」將 createrepo 套件找出來看是放在那裡,接下來使用 rpm -ivh /data/Server/createrepo-0.4.4-2.fc6.noarch.rpm 將套件裝起來。
指令 find 選項 -iname 是忽略大小寫名稱之意;後端使用 "" 包住萬用字元 * 乃是防止 bash 遇到萬用字元會 filename expansion 而造成 find 指令執行失敗所作的保護。至於安裝的那一行 find 則是以找出來的資料再用做其他用途,也就是(-exec)執行 rpm -ivh 「找到的資料」(此指令與執行 rpm -ivh /data/Server/createrepo-0.4.4-2.fc6.noarch.rpm 結果無差異)。



下一步:使用指令「createrepo /data」做出 repodata 目錄以及此目錄下 xml 檔案。

溫馨提示:在 RHEL6 反而不用做 createrepo 這個動作,做了反而會壞掉,更新於 2012-06-13。

 


溫馨提示:RedHat 自 RHEL5 後,rpm 檔案放置目錄由原先「光碟目錄/RedHat/RPMS」改至「光碟目錄/Server」並且另外一些 Cluster、Strorage、Virtual Machine 相關技術套件,不一定都擺在 Server/ 目錄下(例:Cluster、ClusterStorage 與 VT)要小心注意(例如:虛擬機器 xen 有些套件就在 VT/ 目錄下,有些則在 Server/ 目錄下)。



yum client 以本機檔案當作資料來源方式

在我們使用 rpm 安裝套件的時候,最容易發生套件相依的情況,舉例來說:若我們想玩虛擬機器 xen,找到套件 xen 並下指令安裝時,就會出現如下圖的狀況,意思是 xen 還相依 bridge-utils、xen-libs 等等套件必須一併安裝,若要這樣子一個一個挑選套件來完成安裝也是可以的,只是操作上比較繁瑣些。



若是使用 yum client 來安裝就人性化多了,會自動幫您處理相依性的問題。概念上是編寫一個設定檔案(例 foo.repo)即可使用 yum 抓本機 /data 資料當作安裝來源,實際作法如下:
第一步:使用指令「cd /etc/yum.repos.d/」切換到 yum 放置 repository 設定檔案的目錄
第二步:使用指令「cp rhel-debuginfo.repo foo.repo」仿造原本內建的設定檔案做出 foo.repo(不一定要命名為 foo.repo 但一定要 .repo 結尾的檔名才有用,詳情請見 cat /etc/yum.conf 與 man yum.conf)
第三步:編寫修改 foo.repo 內容如下,筆者習慣將 [] 內的名稱以及 name 皆與檔名一致(本例為 foo)修改的重點在於「baseurl=file:///data」(抓取本機 /data/ 目錄下的檔案,請注意有三個正斜線,第三個正斜線是「根目錄」的意思)另外「enabled=1」也是很重要地(1 啟用 0 停用)。


[foo]
name=foo
baseurl=file:///data
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

溫馨提示:設定檔案內 baseurl 參數除了「file://」方式之外,還提供「ftp://」與「http://」兩種方式。


利用 yum 來新增移除套件

在完成設定「yum client 以本機檔案當作資料來源方式」後,接著使用指令「yum install xen」來安裝 xen 套件時,yum 會一併處理相依性(Dependency)問題,我們只要按下 y 鍵,就可以把 xen 套件以及其相關套件統統都裝好。





除此之外 yum -y 選項可自動回答 Y/N 的 y,例 yum -y install xen 對於使用上來說相當地方便,若是要移除,就將 install 改成 remove 即可,例 yum remove xen。

yum 搜尋功能

yum 在搜尋方面的功能也還不賴,例如使用指令「yum list」列出套件(也可配合管線及 grep 使用);「yum search 關鍵字」資料更是豐富;而「yum info 套件名稱」用來顯示套件資訊,「yum whatprovides 檔案名稱」可用來顯示此檔案是由那個套件提供的(不論是否已經安裝)。



例:指令「yum list | grep xen」列出所有套件後過濾出 xen 關鍵字的那幾行。
指令「yum search xen」列出所有與 xen 關鍵字相關套件。
指令「yum info xen」顯示 xen 套件相關資訊。
指令「yum whatprovides /etc/xen」顯示 /etc/xen 檔案是由 xen 套件提供。

yum 更新功能

若是您將 RedHat 原廠網站下載的更新套件放置到相關目錄下並且重新 createrepo 後,所有連到這台 yum Server 的 yum 客戶端就可以使用指令「yum update 套件名稱」來更新。底下以 kernel 這個套件為例,使用指令 mv 將 kernel rpm 檔案搬到 /data/Server 下,使用指令「createrepo /data」重新整理 xml 檔案(原來的套件數量由 2208 變成了 2209),隨後這台 yum Server 立刻充當成 yum Client 使用指令「yum update kernel」來更新 kernel 套件。



溫馨提示:設定檔案 foo.repo 內最後兩行「gpgcheck=1 gpgkey=...」意思是『檢查是否為原廠套件功能』若是您使用 RedHat 卻要使用「副廠套件」(例如 CentOS/Fedora)可將 gpgcheck 改成零(意思是「不檢查」),但是使用副廠套件會有一定的風險!



yum 清除功能

有時候 yum 客戶端會改 yum 設定檔案,改完後使用 yum 會發生 cache 現象,需使用 yum clean 系列的指令(例如 yum clean dbcache、yum clean all 等等)來清除 yum 的 cache,下圖為使用 yum clean all 來清除所有 cache。



應用 ftpd/httpd/nfsd 使 yum Server 提供網路服務

單機自行向自己使用 yum 方式已經大致上介紹完成,相信讀者應該感受到 yum 帶來的便利性。至於許多組織/企業內部通常會安裝多台 Linux 主機,理論上我們不會將架構部屬成為每一台都向自己更新的方式,取而代之是架設一台網路 yum Server 提供其他主機來安裝、移除與更新套件,架構完成的 yum Client/Server 方式對於管理所有 Linux 主機套件新增、移除與更新將會相當地方便輕鬆!底下就以 ftpd 為例(RedHat/Fedora 內建的 vsftpd)來實做 yum Server。

架設 yum Server(配置 vsftpd 為例)

預設 RHEL5 尚未安裝 vsftpd 套件,不囉唆地使用 yum 將之裝起來吧!(指令 yum -y install vsftpd)



接著啟動 vsftpd 並將安裝光碟資料搬移至匿名(anonymous)ftp 帳號家目錄下的 pub 目錄,指令解說如下:
指令「/etc/init.d/vsftpd start」啟動 vsftpd
指令「chkconfig vsftpd on」設定下次開機自動啟動 vsftpd
指令「grep ftp /etc/passwd」查出 RedHat Linux 的 ftp 帳號家目錄位於 /var/ftp(這與 SuSE 預設值不同)
接下來的 mv 那兩行是將原本位於 /data/ 目錄下的資料都搬到 /var/ftp/pub/ 目錄下(包括隱藏檔也搬過去)
rmdir /data 則是將功成身退的 /data/ 空資料夾給移除



設定 yum Client 抓取 ftp 來源資料

將先前配置 yum client 的 /etc/yum.repos.d/foo.repo 重要參數 baseurl 那一行由原來 file:// 改成 ftp://主機名稱或IP/ 方式,例如:
「baseurl=file:///data」是原先使用 file:/// 方式,在下圖中有被#字號註解掉
「baseurl=ftp://172.18.0.72/pub」是使用 ftp 方式到 172.18.0.72 主機 pub/ 目錄下存取套件資料,在下圖中有被#字號註解掉
「baseurl=ftp://a50/pub」同樣是以 ftp 方式,其中 a50 是短的主機名稱,短的主機名稱可利用指令 hostname -s 顯示出來,至於其他相同(或不同)網域名稱的主機可利用 /etc/resolv.conf 中「search 網域名稱」定義方式,以減少輸入網域名稱的機會,筆者範例網域名稱為 ol(OnLine 之意)。
設定正確後,測試 yum 新增、移出、列出與更新功能是否正常(更改 yum 設定最好清除一下 cache)。



httpd/nfsd 方式的 yum Server 重點提示

筆者在此只介紹 ftpd 的 yum Server 建置範例,至於 httpd 方式與 ftpd 相當類似,整理如下:



通訊方式FTPHTTP
RedHat/Fedora 的
FTP/HTTP服務資料擺放預設路徑
ftp 的家目錄在 /var/ftpDocumentRoot 在
/var/www/html
筆者建議或舉例的資料來源擺放路徑資料建議放置在 /var/ftp/pub/ 底下例如將資料放在
/var/www/html/el5/
ftpd/httpd 啟停 Scripts/etc/init.d/vsftpd/etc/init.d/httpd
baseurl 設定範例baseurl=ftp://主機名稱或IP/pubbaseurl=http://主機名稱或IP/el5

關於 NFS 方式則肇因 yum 在 baseurl 參數現階段只支援三種方式,分別為 file、http、ftp 且尚未支援 NFS 傳輸,所以若是 yum Server 只提供 NFS 通訊方式的話,權宜之計是先掛載 NFS yum 資料來源後,再使用 file:// 方式來指向到掛載的 yum 安裝來源目錄即可。

yum Server 兼任網路安裝來源主機

RedHat/Fedora 系列的 Linux 在一開始安裝時,可使用「linux askmethod」切換安裝時候的資料來源,這樣子就可以使用網路的安裝來源資料來建置 Linux 主機,至於資料來源除了最基本的光碟、硬碟外,來自網路的通訊方式有三個,分別為 ftp/http/nfs,既然 yum Server 通常使用 ftp/http 傳輸的話,不妨將 yum Server 兼任 install Server 應該會更便捷地使用及安裝 Linux。



下圖為選擇安裝資料來源的快照




作者 徐秉義
出處 NetAdmin 網管人雜誌

群組共享目錄的建置與權限配置範例

群組共享目錄的建置與權限配置範例


使用 Linux 遇到一些問題而卡住,有時候是權限不足所造成。權限調整的太過於安全,比較容易造成使用上的不方便;調整的太過於鬆散,又容易造成資安方面的問題。如何將 Linux 調整成適當的權限、開放的剛剛好,系統管理員對於權限的觀念,一定要特別的清楚才行,底下透過建置群組共享目錄的實際案例,來了解 Linux 設定檔案與目錄的權限觀念。

建置群組共享的目錄

在中小企業營運的期間,往往會接到一些專案,專案則是會有參與成員以及專屬資料夾,而與此專案無關的成員,就不會給予存取專案資料的權利。

接下來假設接到一個 project2 專案,而帳號 foo2、foo3 是 project2 專案的參與成員,於是就在 Linux 建立 project2 群組來實做群組共享目錄功能。

建立帳號與群組


使用指令「useradd foo2」、「useradd foo3」與「useradd foo4」建立帳號 foo2、foo3、foo4,按照原訂計畫,
foo2 與 foo3 稍後會附屬於 project2 群組,至於 foo4 則是用來代表『與此專案無關』的使用者。

使用指令「groupadd -g 50000 project2」建立群組 project2 且使用 GID 50000 號。

使用指令「id foo2」、「id foo3」與「id foo4」觀察使用者 UID、GID 以及附屬群組(groups)。



設定 foo2、foo3 附屬於 project2 群組


使用指令「vigr」(vi /etc/group 之意)編輯群組資訊檔案,來到檔案的尾端,
會看到『project2:x:50000:』這行
修改成『project2:x:50000:foo2,foo3』


請注意此檔案共四個欄位,以冒號(:)作為分隔符號,修改的是第四個欄位,內容填寫的是附屬於此群組的使用者,如果有多位使用者附屬於此群組,使用逗點(,)作為分隔使用者的符號。

溫馨提示:上述設定可仿造 /etc/group 檔案開頭那幾行的格式當成範本,例如:『sys:x:3:root,bin,adm』意思是 sys 群組有 root、bin、adm 這三個成員(member)使用者。

在指令「vigr」結束後,會詢問是否要順道改 /etc/gshadow(群組密碼檔),沒有要改的話按下 Enter 即可;接著二度使用 id 指令觀察 foo2 與 foo3 已經附屬於 project2 群組,而 foo4 依然沒有附屬於 project2 群組。


群組共享目錄權限設定


使用指令「mkdir /home/group_data/」建立此目錄用來放置各個群組共享資料用的,例如未來有 project3、project4 群組的共享目錄都預計建立在這裡。

使用指令「mkdir /home/group_data/project2」建立此目錄用來放置 project2 群組共享資料用的。

使用指令分別觀察 /home/、/home/group_data/ 以及 /home/group_data/project2 預設都屬於 root 使用者、root 群組,權限以數字方式表達是 755,意思是只有 root 可以完全控制這些資料夾,其餘帳號都只能讀取以及進入目錄而無法在這些目錄下產生新的檔案或子目錄。

使用指令「chgrp project2 /home/group_data/project2/」將此目錄改成 project2 群組的。

使用指令「chmod 2770 /home/group_data/project2/」將此目錄權限改成 2770,關於 2770 稍後會有更詳細的解說。

二度使用指令「ls -ld /home/group_data/project2/」觀察設定後的狀態。

 

上述設定的觀念剖析


上述設定針對 root 擁有者欄位來說,並沒有改變,仍然是完全控制;至於群組則是改成 project2 且開放 project2 群組的成員能夠完全控制此目錄;另外針對不是檔案擁有者 root、且不是 project2 群組的不相關帳號,則是無法存取的狀態。

在指令「ls -ld /home/group_data/project2/」顯示的狀態中:

開頭 rwx 針對檔案擁有者 root 是完全控制的,也就是 chmod 指令 2770 選項的第一個 7

中段 rws 設計給 project2 群組完全控制用的,是 chmod 指令 2770 選項的第二個 7

結尾 --- 是希望不相關帳號完全無法存取,是 chmod 指令 2770 選項的 0

如果讀者有仔細看的話,中段的 rws 不是 rwx 喔!

這個 s 是 chmod 指令 2770 選項的 2,也就是 set gid 權限,當 set gid 用在群組共享目錄的時候,會使得後續建立出來的檔案,鎖定成該群組,以上述的範例來說就是鎖定成 project2 群組,這就是 set gid 用在群組共享目錄的主要用意。

測試群組共享資料夾


使用指令「su - foo2」變換身份成 foo2
使用指令「mkdir /home/group_data/project2/foo2/」產生子資料夾。
使用指令「touch /home/group_data/project2/foo2/foo2.txt」產生子資料夾下的 foo2.txt 空白檔案。


開啟另一個 root 指令的視窗
使用指令「su - foo3」變換身份成 foo3
使用指令「rm /home/group_data/project2/foo2/foo2.txt」試著刪除 foo2 所產生子資料夾下的 foo2.txt 空白檔案。
使用指令「rmdir /home/group_data/project2/foo2」刪除 foo2 所產生的子資料夾。
以上兩個刪除動作皆成功。


再開啟另一個 root 指令的視窗
使用指令「su - foo4」變換身份成 foo4
使用指令「mkdir /home/group_data/project2/foo4/」會失敗,因為權限不足。
使用指令「ls /home/group_data/project2/」會失敗,同樣也是因為權限不足。
權限不足的主因是 foo4 不屬於 project2 專案的成員(不屬於 project2 群組)。

 

有無設定 set gid 的差異


在目錄有 set gid 的情況下,foo2 在 /home/group_data/project2/ 下建立檔案或目錄是屬於 project2 群組的。

例如:使用帳號 foo2 下指令「mkdir /home/group_data/project2/foo2」建立目錄是屬於 project2 群組的。

在目錄沒有 set gid 的情況下,foo2 建立檔案或目錄是屬於 foo2 群組的。

例如:使用帳號 foo2 下指令「mkdir foo2」在家目錄建立子目錄是屬於 foo2 群組的。


以 foo2 的家目錄來說,是沒有設定 set gid 的情況,因此所產生的子目錄,依照權限比對的順序,此時 foo3 並不是屬於同 foo2 群組的帳號,而是僅僅擁有其他人的權限(只有唯讀權利)則無法寫入 foo2 產生的資料(雖然 foo2、foo3 都是附屬於 project2 群組的成員)。

請注意到預設的 foo2 家目錄的權限是 700 而已,意思是只有 foo2 自己可以完全控制、其他帳號都無法存取才對。


下圖是使用 foo3 帳號存取 foo2 家目錄的情況,使用指令「mkdir /home/foo2/foo3」、「ls /home/foo2/」皆權限不足。


在帳號 foo2 使用指令「chmod 755 /home/foo2」開放自己的家目錄給他人唯讀的權限之後。


用帳號 foo3 再次使用指令「mkdir /home/foo2/foo3」依舊失敗;但「ls /home/foo2」是可以成功的,因為是唯讀的權限。

看到 /home/foo2/ 目錄下的子目錄 foo2 也是可以存取的(使用指令 ls 列出資料)。

特別注意:使用 foo2 帳號建立的 /home/foo2/foo2/ 目錄預設群組是 foo2 而不是 project2 所以使用帳號 foo3 時只有唯讀的權限。

所以下圖中使用 foo3 帳號執行指令「mkdir /home/foo2/foo2/foo3」會失敗,因為權限不足。


權限比對的順序與流程

用過 Linux 的人都知道 root 是 Linux 系統管理帳號,擁有至高無上的權利,可是對於電腦來說,主要是因為 root 帳號 UID 為 0、GID 為 0 的關係。


至於其他的帳號,存取的權限皆使用三階段的比對敘述如下:

首先會比對存取的使用者是不是檔案或目錄的擁有者(使用者),如果是就採用第一階段的權限
第一階段的權限就是九個 rwx 的前面三個,也就是使用者的權限;
再來會比對存取的使用者是不是檔案或目錄的預設群組或是附屬群組,如果是就採用第二階段的權限
第二階段的權限就是九個 rwx 的中間三個,也就是群組的權限;
最後只要是存取的使用者有這台電腦的系統帳號,那就採用第三階段的權限
第三階段的權限就是九個 rwx 的最後三個,也就是其他人的權限。


溫馨提示:權限如果沒有對應到這台主機的任何帳號,則沒有存取這台主機的任何權限。
設定權限改成某個使用者的資料



設定權限改成某個使用者的資料


如果想要把某個檔案或目錄,授予某個使用者完整控制的權限的話,就使用 chown 指令,改成是那個帳號的即可。
舉例來說:家目錄(例如:/home/foo2)都是那個使用者(例如:foo2)擁有完整的控制權限。

設定權限改成某個群組用的資料


不只是一個帳號要使用,而是一群使用者要共用時,則要將這群使用者,納為同一個群組,再建立群組共享的資料。
本文介紹的重點就是建立群組共享的資料夾。

設定權限改成大家都可用的資料


如果要讓大家都能夠讀寫,則是開放成 777 的權限。

開放成 777 感覺上不是很安全,所以除非是不得以,或是暫時開放一下,測試一些東西,稍後就應該要關閉。

系統內建開放成大家都可讀寫的資料,最有名的是 /tmp/ 目錄,其實 /tmp/ 目錄的權限不只是 777 而已,應該說是 1777 的權限才對,開頭的 1 是 sticky bit ,這導致存取 /tmp/ 目錄的使用者,『黏住』原來的身份,這樣的結果是造成A使用者產生的檔案或目錄,B使用者不一定可以修改或刪除。

原因就是存取 /tmp/ 期間,使用者都『黏住』用原本的身份來存取資料,避免了互相砍殺資料的情況。

溫馨提示:/tmp/ 目錄的權限 1777 是 drwxrwxrxt 而不是 drwxrwxrwx 喔!


存取各類型服務時,對應帳號權限及其用意


客戶端來訪存取網頁服務時,Server 上對應的使用者身份是定義在 httpd.conf 裡面 User 與 Group 參數,使用指令「grep -E '^User|^Group' /etc/httpd/conf/httpd.conf」可以找出來訪問網頁的身份是對應成 apache 使用者、apache 群組。

使用「id apache」來確認系統真的是有這個帳號,至於網頁的文件根目錄(DocumentRoot)/var/www/html/ 一定要讓 apache 帳號可以讀取才行。


客戶端存取匿名 ftp 服務時,Server 上對應的使用者身份是 ftp,使用指令「grep ftp /etc/passwd」、「id ftp」確認有 ftp 這個帳號以及家目錄是 /var/ftp/,同樣的 /var/ftp/ 目錄要讓 ftp 這個帳號可以讀取才行。


至於其他的服務:
像是存取 samba 服務的訪客身份(Windows 稱作 guest),對應到 Linux 的 nobody 帳號。

指令「testparm -v | grep 'guest account'」來觀察。


存取 nfs 服務時,客戶端的 root 身份預設被轉換成 Server 上的 nfsnobody、存取 DNS 服務的身份 named、存取 proxy 服務的身份 squid 等等,都是類似的機制,主要的用意都是在壓低服務存取的權限,避免客戶端存取服務時對應到 root 身份來存取資料,這樣就算是服務程式發生漏洞,災害的範圍也可控制的比較小一些。



作者 徐秉義
出處 NetAdmin 網管人雜誌