> For the complete documentation index, see [llms.txt](https://handbook.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://handbook.bsdcn.org/di-33-zhang-wang-luo-fu-wu-qi/33.2.-inetd-chao-ji-fu-wu-qi.md).

# 33.2.inetd 超级服务器

[inetd(8)](https://man.freebsd.org/cgi/man.cgi?query=inetd\&sektion=8\&format=html) 守护进程有时被称为超级服务器（Super-Server），因为它管理许多服务的连接。与启动多个应用程序不同，只需启动 inetd 服务。收到由 inetd 管理的服务连接时，inetd 会确定该连接的目标程序，启动该程序的进程，并为其分配套接字。与单独以独立模式运行每个守护进程相比，使用 inetd 处理不常用的服务可以减少系统负载。

inetd 主要用于启动其他守护进程，但也会内部处理一些简单的协议，如 chargen、auth、time、echo、discard 和 daytime。

本节介绍配置 inetd 的基础知识。

## 33.2.1. 配置文件

inetd 的配置通过编辑 **/etc/inetd.conf** 文件完成。该配置文件中的每一行表示一个可以由 inetd 启动的应用程序。默认情况下，每一行都以注释符号（`#`）开始，这意味着 inetd 不会监听任何应用程序。要配置 inetd 监听某个应用程序的连接，只需删除该应用行开头的 `#`。

编辑完成后，通过编辑 **/etc/rc.conf** 配置 inetd 在系统引导时启动：

```sh
inetd_enable="YES"
```

要立即启动 inetd 使其开始监听已配置的服务，输入以下命令：

```sh
# service inetd start
```

inetd 启动后，对 **/etc/inetd.conf** 文件的任何修改都需要通知 inetd：

示例 1. 重新加载 inetd 配置文件

```sh
# service inetd reload
```

通常情况下，应用程序的默认条目不需要修改，除了删除 `#`。在某些情况下，修改默认条目是适当的。

例如，以下是 [ftpd(8)](https://man.freebsd.org/cgi/man.cgi?query=ftpd\&sektion=8\&format=html) 的默认条目，使用 IPv4：

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

条目中的七个字段如下：

```ini
服务名
套接字类型
协议
{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]]
用户[:组][/登录分级]
服务器程序
服务器程序参数
```

其中：

**服务名** 要启动的守护进程的服务名称。它必须与 **/etc/services** 中列出的服务相对应。此项决定了 inetd 用于监听该服务的端口。如果使用自定义服务，必须首先将其添加到 **/etc/services** 中。

**套接字类型** 可以是 `stream`、`dgram`、`raw` 或 `seqpacket`。对于 TCP 连接使用 `stream`，对于 UDP 服务使用 `dgram`。

**协议** 使用以下协议名称之一：

| 协议名称       | 说明                   |
| ---------- | -------------------- |
| tcp 或 tcp4 | TCP IPv4             |
| udp 或 udp4 | UDP IPv4             |
| tcp6       | TCP IPv6             |
| udp6       | UDP IPv6             |
| tcp46      | 同时支持 TCP IPv4 和 IPv6 |
| udp46      | 同时支持 UDP IPv4 和 IPv6 |

`{wait|nowait}[/max-child[/max-connections-per-ip-per-minute[/max-child-per-ip]]]` 此字段必须指定 `wait` 或 `nowait`。`max-child`、`max-connections-per-ip-per-minute` 和 `max-child-per-ip` 是可选项。

`wait|nowait` 指示服务是否能处理自己的套接字。`dgram` 套接字类型必须使用 `wait`，而 `stream` 守护进程通常是多线程的，应该使用 `nowait`。`wait` 通常将多个套接字交给单个守护进程，而 `nowait` 为每个新套接字生成一个子守护进程。

`max-child` 设置 inetd 可以启动的子守护进程的最大数量。例如，要限制守护进程的实例数为十个，可以在 `nowait` 后面加上 `/10`。指定 `/0` 则允许无限数量的子进程。

`max-connections-per-ip-per-minute` 限制每个特定 IP 地址每分钟的连接次数。达到限制后，该 IP 地址的进一步连接将被丢弃，直到分钟结束。例如，值为 `/10` 表示每个 IP 地址每分钟最多允许十次连接尝试。`max-child-per-ip` 限制每个 IP 地址在同一时刻可以启动的子进程数。这些选项可以限制资源的过度消耗，并帮助防止拒绝服务攻击。

可以在 [fingerd(8)](https://man.freebsd.org/cgi/man.cgi?query=fingerd\&sektion=8\&format=html) 的默认设置中看到示例：

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

**用户** 守护进程将以哪个用户名运行。守护进程通常以 `root`、`daemon` 或 `nobody` 运行。

**服务器程序** 守护进程的完整路径。如果守护进程是由 inetd 提供的内部服务，使用 `internal`。

**服务器程序参数** 用于指定传递给守护进程的命令参数。如果守护进程是内部服务，使用 `internal`。

## 33.2.2. 命令行选项

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

要更改传递给 inetd 的默认选项，可以在 **/etc/rc.conf** 中添加 `inetd_flags` 条目。如果 inetd 已在运行，使用 `service inetd restart` 重启它。

可用的速率限制选项如下：

-c maximum 指定每个服务的默认最大同时调用次数，默认值为无限制。可以在 **/etc/inetd.conf** 中使用 `max-child` 为每个服务覆盖此值。

-C rate 指定每分钟从单个 IP 地址可以调用服务的最大次数。可以在 **/etc/inetd.conf** 中使用 `max-connections-per-ip-per-minute` 为每个服务覆盖此值。

-R rate 指定每分钟可调用服务的最大次数，默认值为 `256`。如果设置为 `0`，则允许无限次调用。

-s maximum 指定每个时刻单个 IP 地址可以调用服务的最大次数，默认值为无限制。可以在 **/etc/inetd.conf** 中使用 `max-child-per-ip` 为每个服务覆盖此值。

还有其他选项可用。有关完整的选项列表，请参见 [inetd(8)](https://man.freebsd.org/cgi/man.cgi?query=inetd\&sektion=8\&format=html)。

## 33.2.3. 安全注意事项

许多可以由 inetd 管理的守护进程缺乏安全意识。例如，一些守护进程（如 fingerd）可能会提供对攻击者有用的信息。只启用必要的服务，并监控系统是否有过多的连接尝试。可以使用 `max-connections-per-ip-per-minute`、`max-child` 和 `max-child-per-ip` 限制此类攻击。

默认情况下，启用了 TCP Wrapper。有关如何对各种 inetd 调用的守护进程设置 TCP 限制的更多信息，请参见 [hosts\_access(5)](https://man.freebsd.org/cgi/man.cgi?query=hosts_access\&sektion=5\&format=html)。
