概述
在我们解释如何编译和安装安全和优化的服务器软件之前,有必要先知道一下用什么命令和程序来完成这项任务。首先,必须保证在系统中已经安装了必要的软件包,能够进行编译工作。这些软件包必须安装在服务器上,否则将无法编译程序。
必要的一些软件包
为了能在服务器上编译软件,在重新编译完内核之后,必须安装下面的软件包。这些软件包在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
byacc-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,等)可以执行的二进制文件。现在linux系统中可执行的二进制文件的格式通常是elf。程序员用编译器编译源代码以得到二进制程序。编译通不过,或是通过了,但是程序却并不能正常地运行,这是很常见的事,所以有一大半的编程时间是用来跟踪并查找错误(debugging)。
本书中用到的有关如何编译源代码的名词和术语包括但不限于:
单独编译
只用单个文件编译的程序很少见。通常情况下,有多个文件(例如:*.c)要编译成目标文件(*.o),然后再链接成可执行文件。编译器通过调用链接器(“ld”程序)来完成链接工作。
makefile
makefile是用来保证编译的一致性(每次都用同样的方法编译程序),而且还可以提高编译的速度。大型的程序都要用很长的时间—几十分钟才能完成编译。“make”根据makefile里定义的“相关性”来决定程序的哪些部分需要重新编译。如果五十个源程序文件中有一个发生变化,那么只要重新编译一个文件然后再重新链接就行了,而不要全部重新编译。请注意makefile的格式要求有些行必须用tab字符作为起始字符,而不是空格。
函数库
不仅可以用目标文件(*.o)链接成程序,还可以用函数库(目标文件的集合)链接。有时可能要链接系统的函数库(如:-lm数学函数库,用于数学运算的c程序必须用到这个函数库)。有两种链接库函数的方式:静态(函数的目标代码被编译到可执行文件中)和动态(程序运行的时候才把函数动态载入)。编译器的手册中有很大一部分讨论这两种方式各自的优缺点。
补丁
以前补丁是用来修正可执行文件的,而不必重新编译程序。现在已经不用这种方法了,通常是给源代码打“补丁”,也就是改变一小部分的源代码。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”命令在不同的文件之间建立相关性。“strip”命令从目标文件中清除符号信息。这样最后生成的二进制文件就会比较小,也可以提高程序的性能。“chown”命令给二进制文件设定合适的所有者和组的权限。
注意:在后面服务器软件安装的相关章节会介绍和解释更多的命令。
所有第九章和第十章列出来的软件,可以根据自己的需要、这台服务器要完成什么样的任务以及要求它在intranet/internet上扮演什么样的角色,来选择安装。为了保证远程管理的安全有可能会用ssh替代telnet。另外还有可能安装tripware来帮助系统管理员监控系统中文件的变化。