概述
在我們解釋如何編譯和安裝安全和優化的服務器軟件之前,有必要先知道一下用什么命令和程序來完成這項任務。首先,必須保證在系統中已經安裝了必要的軟件包,能夠進行編譯工作。這些軟件包必須安裝在服務器上,否則將無法編譯程序。
必要的一些軟件包
為了能在服務器上編譯軟件,在重新編譯完內核之后,必須安裝下面的軟件包。這些軟件包在RedHat 6.1第一張光盤的RedHat/RPMS目錄下。
用下面的命令進入軟件包所在的目錄:
[root@deep]# mount /dev/cdrom /mnt/cdrom/
[root@deep]# cd /mnt/cdrom/RedHat/RPMS/
需要安裝的軟件是:
autoconf-2.13-5.noarch.rpm
m4-1.4-12.i386.rpm
automake-1.4-5.noarch.rpm
dev86-0.14.9-1.i386.rpm
bison-1.28-1.i386.rpm
byaclearcase/" target="_blank" >cc-1.9-11.i386.rpm
cdecl-2.5-9.i386.rpm
cpp-1.1.2-24.i386.rpm
cproto-4.6-2.i386.rpm
ctags-3.2-1.i386.rpm
egcs-1.1.2-24.i386.rpm
ElectricFence-2.1-1.i386.rpm
flex-2.5.4a-7.i386.rpm
gdb-4.18-4.i386.rpm
glibc-devel-2.1.2-11.i386.rpm
make-3.77-6.i386.rpm
patch-2.5-9.i386.rpm
把RPM軟件包安裝到系統中的命令是:
[root@deep]# rpm -Uvh foo-1.0-2.i386.rpm
檢驗RPM軟件包是否已經安裝到系統中的命令是:
[root@deep]# rpm -q foo
一旦安裝和編譯完所有應該在服務器上安裝的軟件之后,應該把上面的軟件包都卸掉(編譯器、函數庫,等)。這可以保證沒有經過授權的用戶不能在服務器上編譯程序。
還要把“rpm”程序移到一個安全的地方,如:軟盤,其原因是讓沒有經過授權的用戶不能隨便安裝軟件。假定一個懷有惡意的人想在服務器上編譯程序,而且已經知道服務器上沒裝編譯器。他就會試圖用rpm命令把所有上面列出來的軟件包安裝到服務器中去。當他發現rpm命令也不能用的時候,一定會感到很吃驚而又無可奈何。當然,今后如果你想在服務器上安裝新的軟件也要用到rpm程序,但是所要做的不過是把rpm程序從軟盤上拷回原來的地方。
用下面的命令把rpm程序移動到軟盤上:
[root@deep]# mount /dev/fd0 /mnt/floppy/
[root@deep]# mv /bin/rpm /mnt/floppy
[root@deep]# umount /mnt/floppy/
用下面的命令把rpm程序移回原來的地方:
[root@deep]# mount /dev/fd0 /mnt/floppy/
[root@deep]# cp /mnt/floppy/rpm /bin/
[root@deep]# umount /mnt/floppy/
注意:不要用rpm命令把rpm軟件包完全卸載掉,否則以后就再也沒有辦法安裝它了(安裝rpm軟件包也要用rpm程序)。
為什么選擇“tarballs”
RedHat Linux是以RPM文件的形式發行的。RPM文件,也就是RedHat Linux系統中所謂“軟件包”。用RPM軟件包的形式來發行軟件的優勢是可以很方便的安裝、升級、查詢和卸載。然而,在Unix世界,用“tarballs”(.tar.gz文件)發行軟件包是事實上的標準。tarballs是用“tar”就可以處理的簡單文件格式。但是安裝“tarballs”比安裝RPM軟件包麻煩得多了。那么為什么我們還選擇“tarballs”呢?
1.因為許多開發者都是先用“tarballs”來發行軟件的,所以一般要等幾個星期他們才會把最新的軟件轉成RPM包。
2.當開發者發行新的RPM軟件包的時候,他們并不知道你要什么或不要什么,所以編譯的時候用通用的選項來滿足多數人的需要。
3.RPM包通常沒有為特殊的處理器優化。象RedHat Linux這樣的公司發行的RPM軟件包是基于標準PC,也就是以i386的標準來編譯軟件,這樣程序就可以在各種計算機上運行。
4.有時你會下載并安裝別人已經做好的現成的RPM軟件包。但是這有可能導致沖突,因為每個人的軟硬件環境都是不一樣的,而且還有可能產生安全隱患或其它問題。
在系統中編譯軟件
簡單地說,程序就是計算機可以執行的東西。一個人用自己可以理解的語言寫出程序的“源代碼”,這種語言有可能是C或其它語言。編譯器把“源代碼”轉換成處理器(386、486,等)可以執行的二進制文件?,F在Linux系統中可執行的二進制文件的格式通常是Elf。程序員用編譯器編譯源代碼以得到二進制程序。編譯通不過,或是通過了,但是程序卻并不能正常地運行,這是很常見的事,所以有一大半的編程時間是用來跟蹤并查找錯誤(debugging)。
本書中用到的有關如何編譯源代碼的名詞和術語包括但不限于:
單獨編譯
只用單個文件編譯的程序很少見。通常情況下,有多個文件(例如:*.c)要編譯成目標文件(*.o),然后再鏈接成可執行文件。編譯器通過調用鏈接器(“ld”程序)來完成鏈接工作。
Makefile
Makefile是用來保證編譯的一致性(每次都用同樣的方法編譯程序),而且還可以提高編譯的速度。大型的程序都要用很長的時間—幾十分鐘才能完成編譯?!癿ake”根據Makefile里定義的“相關性”來決定程序的哪些部分需要重新編譯。如果五十個源程序文件中有一個發生變化,那么只要重新編譯一個文件然后再重新鏈接就行了,而不要全部重新編譯。請注意Makefile的格式要求有些行必須用TAB字符作為起始字符,而不是空格。
函數庫
不僅可以用目標文件(*.o)鏈接成程序,還可以用函數庫(目標文件的集合)鏈接。有時可能要鏈接系統的函數庫(如:-lm數學函數庫,用于數學運算的C程序必須用到這個函數庫)。有兩種鏈接庫函數的方式:靜態(函數的目標代碼被編譯到可執行文件中)和動態(程序運行的時候才把函數動態載入)。編譯器的手冊中有很大一部分討論這兩種方式各自的優缺點。
補丁
以前補丁是用來修正可執行文件的,而不必重新編譯程序?,F在已經不用這種方法了,通常是給源代碼打“補丁”,也就是改變一小部分的源代碼。Larry Warry的“patch”程序就是用于這個目的。程序版本的更新現在可以用打補丁這種方式,而用不著每次都發行不同的軟件包。
編譯和鏈接中出現的錯誤
有很多原因會導致這些錯誤,如:輸入錯誤、不小心漏掉以及語法錯誤等等。請注意檢查源程序中有沒有包含需要調用的函數的頭文件。無法引用的符號錯誤(unreferenced symbols)通常是鏈接時出現的問題,所以要檢查一下系統中有沒有安裝必要的函數庫和一些工具。
調試
調試涉及很多方面的知識。有時候可以在源代碼中加入調試的語句,這樣可以知道程序運行的狀態。為了避免一下子有太多的輸出,也可以在循環語句中每循環三次輸出一下。查看變量在模塊之間能否正確地傳遞也有助于問題的解決。還有就是要熟悉調試工具。
編譯和安裝軟件
在下面的章節中我們可能會用其它一些不同的命令來編譯和安裝服務器軟件。這一節介紹的命令是一些通用的命令,是Unix兼容的而且可以在各種各樣的Unix變種下編譯和安裝軟件。
在服務器上編譯和安裝“tarballs”軟件包的過程如下:
首先必須到可靠的站點下載“tarball”。
下載完之后,轉到“/var/tmp”目錄(其它的目錄也可以),以root身份用帶參數的“tar”命令解壓軟件包。例如:
[root@deep]# tar xzpf foo.tar.gz
上面這個命令解壓“foo.tar.gz”這個軟件包。
“x”選項告訴tar解壓壓縮文件
“z”選項告訴tar壓縮文件是用gzip壓縮的
“p”選項告訴tar保留文件的權限
“f”選項告訴tar下一個參數是文件名
“tarball”解壓之后,就會在相應的目錄中找到“README”和“INSTALL”文件。讀完這些文件之后就知道如何編譯和安裝軟件了。很有可能會運行下面的命令:
./configure
make
make install
“./configure”命令對軟件進行配置以保證系統中有進行編譯所必要的函數庫,“make”把所有的源代碼文件編譯成二進制文件,“make install”把二進制文件和其它必要的文件安裝到相應的目錄。其它有可能見到的命令還有:
make depend
strip
chown
“make depend”命令在不同的文件之間建立相關性?!皊trip”命令從目標文件中清除符號信息。這樣最后生成的二進制文件就會比較小,也可以提高程序的性能?!癱hown”命令給二進制文件設定合適的所有者和組的權限。
注意:在后面服務器軟件安裝的相關章節會介紹和解釋更多的命令。
所有第九章和第十章列出來的軟件,可以根據自己的需要、這臺服務器要完成什么樣的任務以及要求它在Intr.net/Internet上扮演什么樣的角色,來選擇安裝。為了保證遠程管理的安全有可能會用ssh替代telnet。另外還有可能安裝Tripware來幫助系統管理員監控系統中文件的變化。