29.2. inetd超级服务器

inetd(8) 有时也被称作 Internet 超级服务器, 因为它可以为多种服务管理连接。 当 inetd 收到连接时, 它能够确定连接所需的程序, 启动相应的进程, 并把 socket 交给它 (服务 socket 会作为程序的标准输入、 输出和错误输出描述符)。 使用 inetd 来运行那些负载不重的服务有助于降低系统负载, 因为它不需要为每个服务都启动独立的服务程序。

一般说来, inetd 主要用于启动其它服务程序, 但它也有能力直接处理某些简单的服务, 例如 chargenauth, 以及 daytime

本章将介绍如inetd的基础设置。

29.2.1. 配置文件

inetd的配置是通过编辑/etc/inetd.conf来完成的。此配置文件的每一行表示一个应用程序,该应用程序可以通过inetd启动。默认情况下,每行以注释 (#) 开头,这意味着inetd不侦听任何应用程序。要将inetd配置为侦听应用程序的连接,请删除该应用程序行开头的#

保存编辑后,通过编辑/etc/rc.confinetd配置为在系统启动时启动:

inetd_enable="YES"

若需立即启动inetd,请输入:

# service inetd start

inetd启动后,若修改了/etc/inetd.conf,需要重启inetd让配置生效:

例 29.1. 重新库入inetd配置文件
# service inetd reload

配置文件中的每一行都是一个独立的服务程序。 在这个文件中, 前面有 # 的内容被认为是注释。

下面是针对 IPv4 的 ftpd(8) 服务的例子:

ftp     stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -l

这七个参数的含义如下所述:

service-name
socket-type
protocol
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]]
user[:group][/login-class]
server-program
server-program-arguments

其中:

service-name

指明各个服务的服务名。其服务名必须与/etc/services中列出的一致。 这将决定inetd会监听哪个port。 一旦有新的服务需要添加,必须先在/etc/services里面添加。

socket-type

可以是streamdgramraw或者 seqpacketstream 用于基于连接的 TCP 服务;而 dgram 则用于使用 UDP 协议的服务。

protocol

使用以下协议名称之一:

协议名称说明
tcp 或 tcp4TCP IPv4
udp 或 udp4UDP IPv4
tcp6TCP IPv6
udp6UDP IPv6
tcp46TCP IPv4 和 IPv6
udp46UDP IPv4 和 IPv6
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]]

这个字段中, 必须指定 waitnowait 两者之一。 而 max-childmax-connections-per-ip-per-minutemax-child-per-ip 则是可选项。

wait|nowait 指明从inetd 里头调用的服务是否可以自己处理socket. dgramsocket类型必须使用wait, 而stream socket daemons, 由于通常使用多线程方式,应当使用 nowait. wait 通常把多个 socket 丢给单个服务进程, 而 nowait 则 会为每个新的 socket 生成一个子进程。

max-child 选项能够配置 inetd 能为本服务派生出的最大子进程数量。 如果某特定服务需要限定最高10个实例, 把/10 放到nowait后头就可以了。 指定 /0 表示不限制子进程的数量。

max-connections-per-ip-minute限制来自特定的IP地址每分钟的连接数。一旦达到限制值,来自该IP地址的后续连接将被中断,一分钟后恢复正常。例如,/10的值将限制特定的IP地址每分钟的连接尝试次数为10次。max-child-per-ip限制了在任何时刻代表任何单个IP地址启动的子进程数量。这些选项可以限制过多的资源消耗,并有助于防止拒绝服务攻击。

下面是 fingerd(8) 服务的默认配置:

finger stream  tcp     nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
user

该开关指定服务将以什么用户身份运行。一般而言,服务运行身份是 root。基于安全目的,可以看到有些服务以 daemon身份,或者是最小特权的 nobody身份运行。

server-program

当连接到来时,执行服务程序的全路径。如果服务是由 inetd内置提供的,以internal代替。

server-program-arguments

用于指定调用时要传递给守护进程的任何命令参数。如果守护进程是内部服务,请使用internal

29.2.2. 命令行选项

与大多数服务器守护进程一样,inetd有许多可用于修改其行为的选项。默认情况下,inetd-wW -C 60启动。这些选项为所有服务(包括内部服务)启用 TCP 包装,并防止任何IP地址每分钟请求任何服务超过 60 次。

这些参数都可以通过 /etc/rc.confinetd_flags 选项来传给 inetd。如果inetd已在运行,使用service inetd restart重启inetd

可用的速率限制选项包括:

-c maximum

指定单个服务的最大并发访问数量,默认为不限。 也可以在此服务的具体配置里面通过max-child改掉。

-C rate

指定单个服务一分钟内能被单个IP地址调用的最大次数, 默认不限。也可以在此服务的具体配置里面通过max-connections-per-ip-per-minute 改掉。

-R rate

指定单个服务一分钟内能被调用的最大次数,默认为256。 设为0 则允许不限次数调用。

-s maximum

指定同一 IP 同时请求同一服务时允许的最大值; 默认值为不限制。 您可以通过 max-child-per-ip 参数来以服务为单位进行限制。

更多参数的含义请参阅inetd(8)

29.2.3. 安全注意事项

某些服务在设计时是缺少安全意识的, 或者有过长或压根没有连接请求的超时机制。 这使得攻击者能够通过缓慢地对这些服务发起连接, 并耗尽可用的资源。 对于这种情况, 设置 max-connections-per-ip-per-minutemax-childmax-child-per-ip 限制, 来制约服务的行为是个好办法。

默认情况下,TCP wrapping 是打开的。参考 hosts_access(5) 手册,以获得更多关于在各种 inetd 调用的服务上设置TCP限制的信息。

本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题,请先阅读 文档,如不能解决再联系 <questions@FreeBSD.org>.

关于本文档的问题请发信联系 <doc@FreeBSD.org>.