30.2. inetd “超级服务器”
上一页 | 第 30 章 网络服务器 | 下一页

## 30.2. inetd “超级服务器”

Contributed by Chern Lee.
更新 The FreeBSD Documentation Project.

### 30.2.1. 总览

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

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

这一节将介绍关于如何通过命令行选项， 以及配置文件 `/etc/inetd.conf` 来对 inetd 进行配置的一些基础知识。

### 30.2.2. 设置

inetd 是通过 rc(8) 系统启动的。 `inetd_enable` 选项默认设为 `NO`， 但可以在安装系统时， 由用户根据需要通过 sysinstall 来打开。 将：

inetd_enable="YES"

或

inetd_enable="NO"

写入 `/etc/rc.conf` 可以启用或禁用系统启动时 inetd 的自动启动。 命令：

`#` `/etc/rc.d/inetd rcvar`

可以显示目前的设置。

此外， 您还可以通过 `inetd_flags` 参数来向 inetd 传递额外的其它参数。

### 30.2.3. 命令行选项

与多数服务程序类似， inetd 也提供了为数众多的用以控制其行为的参数。 完整的参数列表如下：

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

这些参数都可以通过 `/etc/rc.conf` 的 `inetd_flags` 选项来传给 inetd。 默认情况下， `inetd_flags` 设为 `-wW -C 60`， 者表示希望为 inetd 的服务启用 TCP wrapping， 并阻止来自同一 IP 每分钟超过 60 次的请求。

虽然我们会在下面介绍关于限制连接频率的选项， 但初学的用户可能会很高兴地发现这些参数通常并不需要进行修改。 在收到超大量的连接请求时， 这些选项则有可能会发挥作用。 完整的参数列表， 可以在 inetd(8) 联机手册中找到。

-c maximum

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

-C rate

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

-R rate

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

-s maximum

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

### 30.2.4. `inetd.conf`

对于 inetd 的配置， 是通过 `/etc/inetd.conf` 文件来完成的。

在修改了 `/etc/inetd.conf` 之后， 可以使用下面的命令来强制 inetd 重新读取配置文件：

例 30.1. 重新加载 inetd 配置文件
`#` `/etc/rc.d/inetd reload`

配置文件中的每一行都是一个独立的服务程序。 在这个文件中， 前面有 “#” 的内容被认为是注释。 `/etc/inetd.conf` 文件的格式如下：

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

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

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

service-name

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

socket-type

  可以是`stream`、`dgram`、`raw`或者 `seqpacket`。 `stream` 用于基于连接的 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[/max-child-per-ip]]]

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

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

  除了 `max-child` 之外， 还有两个选项可以限制来自同一位置到特定服务的最大连接数。 `max-connections-per-ip-per-minute` 可以限制特定 IP 地址每分钟的总连接数， 例如， 限制任何 IP 地址每分钟最多连接十次。 `max-child-per-ip` 则可以限制为某一 IP 地址在任何时候所启动的子进程数量。 这些选项对于防止针对服务器有意或无意的资源耗竭和拒绝服务 (DoS) 攻击十分有用。

  这个字段中， 必须指定 `wait` 或 `nowait` 两者之一。 而 `max-child`、 `max-connections-per-ip-per-minute` 和 `max-child-per-ip` 则是可选项。

  流式多线程服务， 并且不配置任何 `max-child`、 `max-connections-per-ip-per-minute` 或 `max-child-per-ip` 限制时， 其配置为： `nowait`。

  同一个服务， 但希望将服务启动的数量限制为十个时， 则是： `nowait/10`。

  同样配置， 限制每个 IP 地址每分钟最多连接二十次， 而同时启动的子进程最多十个， 应写作： `nowait/10/20`。

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

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

  最后这个例子中， 将子进程数限制为 100 个， 而任意 IP 最多同时建立 5 个连接： `nowait/100/0/5`。

user

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

server-program

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

server-program-arguments

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

### 30.2.5. Security

随安装时所选的模式不同， 许多 inetd 的服务可能已经默认启用。 如果确实不需要某个特定的服务， 则应考虑禁用它。 在 `/etc/inetd.conf` 中， 将对应服务的那行前面加上 “#”， 然后 重新加载 inetd 配置 就可以了。 某些服务， 例如 fingerd， 可能是完全不需要的， 因为它们提供的信息可能对攻击者有用。

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

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

### 30.2.6. 杂项

daytime、 time、 echo、 discard、 chargen， 以及 auth 都是由 inetd 提供的内建服务。

auth 服务提供了网络身份服务， 它可以配置为提供不同级别的服务， 而其它服务则通常只能简单的打开或关闭。

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

上一页 | 上一级 | 下一页
第 30 章 网络服务器 | 起始页 | 30.3. 网络文件系统（NFS）

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

如果对于FreeBSD有问题，请先阅读 文档，如不能解决再联系 <questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.