23.2. inetd “超级服务器”

Contributed by Chern Lee.

23.2.1. 总览

inetd(8) 被称为“Internet Super-Server”, 因为它管理几个守护程序的链接。提供网络 服务的程序被称为守护进程。inetd 作为一个为其他服务的管理服务器,当一个被inetd 收到后,它将决定连接将前往哪个程序,然后拉起对应的守护进程, 并将socket转交过去。 比起来将所有守护进程以stand-alone模式 运行,运行单个inetd实例可以降低 系统开销。

一般说来,inetd 被用来拉起 其他守护进程,不过有些细碎的协议被直接接管,比如chargenauth,和 daytime

这一部分将通过命令行选项和/etc/inetd.conf 文件来介绍配置inetd 的基础知识。

23.2.2. 设置

inetd 通过 /etc/rc.conf 系统进行初始化。inetd_enable 选项默认被设定为 NO,不过可以通过sysinstall打开, 如果选用中等安全的模板。在/etc/rc.conf中设定:

inetd_enable="YES"
inetd_enable="NO"
可以激活或者禁止inetd在启动时加载。

此外,可以通过inetd_flags把不同的 命令行参数传给inetd

23.2.3. 命令行选项

inetd 语法:

inetd [-d] [-l] [-w] [-W] [-c maximum] [-C rate] [-a address | hostname] [-p filename] [-R rate] [configuration file]

-d

打开调试选项。

-l

记录成功的连接

-w

为外部服务打开TCP Wrapping(默认)。

-W

inetd的内置服务打开TCP Wrapping (默认)。

-c maximum

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

-C rate

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

-R rate

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

-a

指定绑定的IP地址。此外,可以使用主机名,这样系统就 可以根据主机名对应的IPV4或者IPV6来选择绑定地址。通常当 inetdjail(8) 中运行 的时候指定主机名,这种情况下主机名来自 jail(8) 环 境变量

当使用主机名方式时,如果IPV4和IPV6都会被绑定到服务, 那么,需要在/etc/inetd.conf.中为该服务 的每个对应协议添加一条记录。比如,一个TCP服务需要两条记录, 一条使用tcp4,另一条使用tcp6

-p

指定用来存放进程ID的文件。

以上选项在/etc/rc.conf中将可以 被inetd_flags开关传递给inetd。 默认情况下,inetd_flags 被置为 -wW,也既是对inetd的内置或外部服务打开TCP wrapping. 对于新手,通常不用去动这些参数,就算它们出现在/etc/rc.conf里头。

Note:inetd而言,所谓外部服务是当 连接请求到来时,被调用并接受连接,启动于inetd之外的守护进程。 反之,内置服务则是那些inetd自己可 以完全处理的了。

23.2.4. inetd.conf

inetd的配置通过 /etc/inetd.conf文件进行控制。

/etc/inetd.conf内容发生改变,可以 对inetd进程发送一个HangUP信号,以强制 inetd重新读取配置文件,如下所示:

Example 23-1. 对 inetd发送HangUP信号

# kill -HUP `cat /var/run/inetd.pid`

配置文件中的每一行都是一个独立服务。如果要注释掉该服务,可以在行首加上 “#”。/etc/inetd.conf的格式如下:

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

ftpd使用IPv4的例子:

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

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

socket-type

可以是streamdgramraw或者 seqpacketstream 用在基于连接的,TCP 服务;而dgram被用于服务用于UDP传输协议。

protocol

下列之一:

协议 说明
tcp, tcp4 TCP IPv4
udp, udp4 UDP IPv4
tcp6 TCP IPv6
udp6 UDP IPv6
tcp46 Both TCP IPv4 and v6
udp46 Both UDP IPv4 and v6
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute]]

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

使用max-child选项可以设定针对服务, inetd可以派生出来的最大子进程数量。 如果某特定服务需要限定最高10个实例,把/10 放到nowait后头就可以了。

max-child之外,还有一个开关可以限制 来自同一个地方,针对某个服务的最大连接数。这个开关就是: max-connections-per-ip-per-minute。 比如,设定该值为10就可以限定单个IP地址去向某服务的连接最大 为每分钟十个。这个对于防止有意或者无意的资源耗尽或者拒绝服 务(DoS)颇有用处。

在这部分,必须选择waitnowaitmax-childmax-connections-per-ip-per-minute 则为可有可无。

一个stream-type多线程的服务,如果没有 max-child或者 max-connections-per-ip-per-minute需要, 一般使用: nowait

同样的服务,如果需要限制最大连接数,则如下: nowait/10

此外,如果要限制每分钟单个IP来访连接为20个,同时最多 派生10个进程,可以如下: nowait/10/20

以上开关都默认被使用在fingerd服务上面, 如下所示:

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

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

server-program

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

server-program-arguments

server-program调用到时,该开关 的值通过argv[0]通过传递给服务而工作。 如果命令行为:mydaemon -d,则 mydaemon -dserver-program-arguments 开关的值。同样的,如果服务是由inetd 内置提供的,这里还是 internal

23.2.5. Security

随安装时候选择的安全模式不同,部分inetd的服务 会被设为默认打开。如果没有确实的需要,禁止它们!只要在/etc/inetd.conf里头 需要禁止的服务前头加上“#”,然后 对inetd发送hangup信号。某些服务,比如fingerd, 由于对攻击者提供太多信息,可能对任何人都应该禁止。

某些服务在安全上没有考虑,并且有一些连接超时检测设得很长或没有检测机制。 这回允许攻击者慢慢地发送连接,这样可以导致可用资源的消耗。在某些服务上面加上 max-connections-per-ip-per-minutemax-child 的限制似乎不错。

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

23.2.6. 杂项

daytimetimeechodiscardchargen, 和 auth 都是inetd内置的服务。

auth服务提供 identity (identidentd)网络服务,并且某种程度上可配置。

参考 inetd(8) 手册获得更多信息。