第九章 各种网络应用程序
在成功地设置好IP和解析器以后,我们现在转过来讨论你想在网络上提供的服务。这一章讲
解了一些简单网络应用程序的配置,包括inetd服务器、以及rlogin族中的程序。象网络文件
系统(NFS)以及网络信息系统(NIS)所基于的远程过程调用接口也将概要地给予讨论。然
而,NFS和NIS的配置内容太多,将用独立的章节进行描述。电子邮件和网络新闻(netnews)
也将用独立的章节给予讨论。
当然,我们不可能在本书中讨论所有的网络应用程序。如果你要安装一个这里没有讨论过的
程序,比如说,talk、gopher或Xmosaic,请参考它们的手册以获得详细信息。
9.1 inetd超级服务器(super-server)
通常,服务是由所谓的后台程序{或称端口监控程序}daemons执行的。一个端口监控程序是一
个程序,它打开一个端口,并且等待进入的连接。如果来了一个连接,它就创建一个子进程
来接纳这个连接,而父进程继续监听更多的请求。这个概念有个缺点,即对于所提供的每个
服务,就必须运行一个监听某个端口上连接发生的端口监控程序,这通常意味着象交换空间
那样的系统资源的浪费。
因而,几乎所有的UN*X安装程序运行一个“超级服务器”,它为许多服务创建套接字,并且
使用select(2)系统调用同时监听所有这些端口。当远程系统请求一个服务时,超级服务器注
意到这点并且会产生该端口的服务器程序。
常用的超级服务器是inetd,即Internet Daemon(Internet端口监听程序)。它是在系统引
导时启动的,并且从名为/etc/inetd.conf的启动文件中取得它所要管理的服务的列表。除了
上面所述的那些调用的服务器程序以外,还有许多由inetd自己处理的一般服务,称作内部服
务(internal services)。这些包括简单地产生字符串的chargen、返回系统日期时间的da
ytime。
该文件中的一行是由以下几个字段组成的:
service type protocol wait user server cmdline
每个字段的含义如下:
service
给出服务的名称。通过查找/etc/services文件,服务名称可以转换成一个端口号。这个文件
将在services和protocols文件一节(10.3节)中给予描述。
type
指定一个套接字类型,或者是stream(对于基于连接的协议)(for connection-oriented
protocols)或者是dgram(对于基于数据报的协议)(for datagram protocols)。因此对
于基于TCP的服务总是使用stream,而基于UDP的服务总是使用dgram。
protocol
命名服务所使用的传输协议。这必须是protocols文件中能找到的有效协议名称,也将在下面
给出解释。
wait
该选项只用于dgram套接字。它可以是wait或nowait。如果指定了wait,那么对于指定的端口
inetd任何时候只执行一次服务器程序。否则的话,在执行了指定的服务器以后,它将立刻在
这个端口上进行监听。
这对于读取所有进入的数据报,然后退出的“单线程”服务器程序来讲是很有用的。许多RP
C服务器程序是这种类型的,因而对它们需指定为wait。对于相反的类型,“多线程”服务器
程序允许无限数量的例程并发运行;这是很少用到的。这种服务器程序需指定为nowait。st
ream套接字应该总是使用nowait。
user
这是用户的登录id,用户的进程就在其下运行。这通常是root用户,但某些服务可以使用不
同的帐号。这里使用最小特权原则是个很好的主意,这是指你不应该在一个享有特权的帐号
下运行一个命令,如果该程序不需要特权也能正常工作的话。例如,NNTP新闻服务器程序将
作为news运行,而可能引起安全危险问题的服务(比如tftp或finger)经常作为nobody运行
。
server
给出将被执行的服务器程序的全路径。内部服务用关键字internal标记。
cmdline
这是传给服务器程序的命令行(参数)。这包括参数0 ?命令名。通常,这是是服务器程序
名,除非当使用一个不同的名字调用时,该程序有不同的行为。对于内部服务该字段是空的
。
#
# inetd services
ftp stream tcp nowait root /usr/sbin/ftpd in.ftpd -l
telnet stream tcp nowait root /usr/sbin/telnetd in.telnetd -b/etc/issue
#finger stream tcp nowait bin /usr/sbin/fingerd in.fingerd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd /boot/diskless
login stream tcp nowait root /usr/sbin/rlogind in.rlogind
shell stream tcp nowait root /usr/sbin/rshd in.rshd
exec stream tcp nowait root /usr/sbin/rexecd in.rexecd
#
# inetd internal services
#
daytime stream tcp nowait root internal
daytime dgram udp nowait root internal
time stream tcp nowait root internal
time dgram udp nowait root internal
echo stream tcp nowait root internal
echo dgram udp nowait root internal
discard stream tcp nowait root internal
discard dgram udp nowait root internal
chargen stream tcp nowait root internal
chargen dgram udp nowait root internal
图9.1 一个/etc/inetd.conf样本文件。
图9.1给出了inetd.conf的一个样本文件。finger服务被注释掉了,所以这个服务就不存在了
。这样做通常是为了安全方面的原因,因为它可能被入侵者用来获取你系统上的用户名。
tftp同样也被注释掉了。tftp实现原始文件传输协议(Primitive File Transfer Protocol
)它允许无须口令检查直接从你的系统上传输任何可读的文件等等。这对于/etc/passwd文件
尤其有害,当没有使用影子口令文件时就更没的说了。
TFTP通常用于无盘客户以及X终端从一个引导服务器上下载代码。如果由于这个原因你需要运
行tftpd的话,请通过在tftpd的命令行上增加那些目录名来限制它们的范围到客户获取文件
的目录中。见例子中的第二个tftp行所示。
9.2 tcpd访问控制工具
由于对网络访问开放一个计算机包含许多安全方面的风险,所以应用程序被设计成能够防卫
几种类型的攻击。然而,其中的某些防卫可能有缺陷(最为彻底的例子是RTM Internet 蠕虫
),或者并不区分请求能被接受的特定服务的安全主机与请求将被拒绝的不可靠的主机。上
面我们已经概要地讨论过了finger和tftp服务。因此,人们想限制这些服务只有“可信的主
机”才能访问,而使用通常的设置是不可能做到的,对于这些服务inetd要么提供给所有的客
户,要么一个客户都不能使用。
为了达到此目的,一个有用的工具是tcpd,[1] 即所谓的端口监控程序包装器(daemon wra
pper)。对于你想监视和保护的TCP服务,将调用这个tcpd而不是服务器程序。tcpd将请求记
录到syslog后台程序,检查远程主机是否允许使用那个服务,并且只有检查通过时才会执行
真正的服务器程序。注意,这对于基于UDP的服务不起作用。
例如,要包装finger daemon时,你必须改变indetd.conf中的相应行成为
# wrap finger daemon
finger stream tcp nowait root /usr/sbin/tcpd in.fingerd
不增加任何访问控制,这将如通常的finger设置一样展现在客户面前,除了任何请求将被记
录到syslog的auth设施中。
访问控制是通过两个文件/etc/hosts.allow和/etc/hosts.deny来实现的。它们分别含有对特
定服务和主机允许和禁止访问的条目。当tcpd处理来自名为biff.foobar.com的客户主机的服
务请求时,比如说是finger服务请求,它将hosts.allow和hosts.deny(以这个次序)文件中
扫描匹配这个服务和主机的条目。如果在hosts.allow中找到了匹配条目,就准予访问,而不
管hosts.deny中的任何条目了。如果在hosts.deny中发现了匹配的条目,该请求将通过关闭
这个连接而被拒绝。如果都没有找到匹配的条目,也准予访问。
在访问文件中的条目看上去象这样:
servicelist: hostlist [:shellcmd]
servicelist是来自于/etc/services中的服务名称的一个列表,或者是关键字ALL。要匹配除
了finger和tftp的所有服务时,使用“ALL EXCEPT finger, tftp”。
hostlist是一个主机名或IP地址的列表,或者是关键字ALL、LOCAL或UNKNOWN。ALL匹配任何
主机,而LOCAL匹配不含有点的主机名。[2] UNKNOWN匹配于任何名字或地址查询失败的主机
。一个以点开头的名字与域名等于这个名字的主机匹配。例如,.foobar.com与biff.foobar
.com相匹配。也有对IP网络地址和子网号的规定。详细信息请参见hosts_access(5)手册页。
除了本地主机以外,要限制所有主机对finger和tftp服务的访问,就将下面一行加入到/etc
/hosts.deny文件中,并且/etc/hosts.allow文件为空:
in.tftpd, in.fingerd: ALL EXCEPT LOCAL, .your.domain
可选的shellcmd字段可以含有一个shell命令,当条目匹配时将被调用。这对于设置可以使潜
在的入侵者暴露的陷阱是很有用的:
in.ftpd: ALL EXCEPT LOCAL, .vbrew.com : echo "request from %d@%h" /var/log/finger.log; if [ %h != "vlager.vbrew.com" ]; then finger -l @%h