# 30.2.配置 PPP

FreeBSD 提供对拨号 PPP 连接的内建支持，可以通过 [ppp(8)](https://man.freebsd.org/cgi/man.cgi?query=ppp\&sektion=8\&format=html) 管理。默认的 FreeBSD 内核已支持 **tun**，用于与调制解调器硬件交互。配置工作主要通过编辑至少一个配置文件完成，并已提供包含示例的配置文件。最后，使用 `ppp` 命令来启动和管理连接。

要使用 PPP 连接，必须具备以下内容：

* 与互联网服务提供商（ISP）签订的拨号账号；
* 一台拨号调制解调器；
* ISP 的拨号号码；
* ISP 分配的登录用户名与密码；
* 一个或多个 DNS 服务器的 IP 地址。通常，ISP 会提供这些地址；如果未提供，FreeBSD 可配置为使用 DNS 协商。

如果缺少上述信息，请联系 ISP。

以下信息可能由 ISP 提供，但并非必需：

* 默认网关的 IP 地址。如果未知，ISP 会在连接过程中自动提供正确的值。在配置 FreeBSD 的 PPP 时，这个地址称为 `HISADDR`；
* 子网掩码。如果 ISP 未提供，将在 [ppp(8)](https://man.freebsd.org/cgi/man.cgi?query=ppp\&sektion=8\&format=html) 配置文件中使用 `255.255.255.255`。\*\
  如果 ISP 分配了静态 IP 地址和主机名，应在配置文件中填写；否则，这些信息将在连接过程中自动提供。

本节接下来将演示如何为常见的 PPP 连接场景配置 FreeBSD。所需的配置文件是 **/etc/ppp/ppp.conf**，此外 **/usr/share/examples/ppp/** 中还提供了附加的文件与示例。

> **注意**
>
> 在本节中，许多文件示例显示了行号。这些行号用于方便讨论而添加，不应出现在实际文件中。
>
> 当编辑配置文件时，缩进非常重要。以 `:` 结尾的行必须置于第一列开头，其他行则需如示例中所示，使用空格或 Tab 进行缩进。

## 30.2.1. 基本配置

为了配置 PPP 连接，首先使用 ISP 的拨入信息编辑 **/etc/ppp/ppp.conf**。该文件说明如下：

```ini
1     default:
2       set log Phase Chat LCP IPCP CCP tun command
3       ident user-ppp VERSION
4       set device /dev/cuau0
5       set speed 115200
6       set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \
7                 \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT"
8       set timeout 180
9       enable dns
10
11    provider:
12      set phone "(123) 456 7890"
13      set authname foo
14      set authkey bar
15      set timeout 300
16      set ifaddr x.x.x.x/0 y.y.y.y/0 255.255.255.255 0.0.0.0
17      add default HISADDR
```

**第 1 行**：标识 `default` 条目。执行 `ppp` 时，会自动运行本条目中的命令（第 2 至 9 行）。

**第 2 行**：启用详细日志参数，用于测试连接。待配置正常工作，可简化为：

```sh
set log phase tun
```

**第 3 行**：向连接另一端的 PPP 软件显示 \[ppp(8)] 的版本号。

**第 4 行**：指定连接调制解调器的设备，**COM1** 为 **/dev/cuau0**，**COM2** 为 **/dev/cuau1**。

**第 5 行**：设置连接速率。如果旧调制解调器无法使用 `115200`，可尝试 `38400`。

**第 6 与 7 行**：拨号字符串，使用 expect-send 语法书写。详情请参阅 [chat(8)](https://man.freebsd.org/cgi/man.cgi?query=chat\&sektion=8\&format=html)。

注意此命令因可读性原因换行。**ppp.conf** 中的任何命令都可以在行末加 `\` 来换行。

**第 8 行**：设置链路空闲超时（秒）。

**第 9 行**：指示对端确认 DNS 设置。如果本地网络已有 DNS 服务器，应将本行注释掉（加 `#`），或直接删除。

**第 10 行**：空行，仅用于可读性，\[ppp(8)] 会忽略空行。

**第 11 行**：标识名为 `provider` 的条目。可将其改为 ISP 名称，以便用 `load <ISP>` 启动连接。

**第 12 行**：填写 ISP 的电话号码。可使用冒号（`:`）或竖线（`|`）分隔多个号码。冒号用于轮换拨号，竖线用于总是优先拨打第一个号码，仅当失败才尝试其他号码。所有号码必须用引号包裹，以避免拨号失败。

**第 13 与 14 行**：填写 ISP 的用户名与密码。

**第 15 行**：设置连接的默认空闲超时（秒）。此例中，连接在 300 秒无活动后自动断开。若希望连接永不超时，可将其设为 0。

**第 16 行**：设置接口地址。具体值取决于 ISP 是否提供静态 IP 地址，或是通过连接动态协商。

如果 ISP 分配了静态 IP 和默认网关地址，则用该静态 IP 替换 *x.x.x.x*，用网关地址替换 *y.y.y.y*；若 ISP 仅提供静态 IP 而无网关地址，则将 *y.y.y.y* 改为 `10.0.0.2/0`。

如果每次连接时 IP 地址会变化，则改为以下内容，使用 IP 配置协议（IPCP）动态协商：

```sh
set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.255 0.0.0.0
```

**第 17 行**：保持不变，用于将默认路由添加到网关地址。`HISADDR` 将自动替换为第 16 行指定的网关地址。必须放在第 16 行之后。

如果以手动或自动方式运行 \[ppp(8)]，可能还需要创建 **/etc/ppp/ppp.linkup** 文件，内容如下。若以 `-auto` 模式运行 `ppp`，该文件是必需的。它在连接建立之后使用，此时 IP 地址已分配，可以添加路由表项。创建此文件时，*provider* 必须与 **ppp.conf** 第 11 行中所用值一致。

```ini
provider:
      add default HISADDR
```

如果在静态 IP 配置中默认网关地址是“猜测”出来的，也需要此文件。在这种情况下，应从 **ppp.conf** 中删除第 17 行，并创建包含上述两行的 **/etc/ppp/ppp.linkup**。该文件的更多示例可见于 **/usr/share/examples/ppp/**。

默认情况下，`ppp` 必须以 `root` 身份运行。若要更改此行为，应将希望运行 `ppp` 的用户账户添加到 **/etc/group** 中的 `network` 组。

然后使用 `allow` 语句授予该用户访问 **/etc/ppp/ppp.conf** 某些条目的权限。例如，要让 `fred` 和 `mary` 仅能使用 `provider:` 条目，在该部分添加：

```ini
allow users fred mary
```

若希望允许这些用户访问所有条目，则应将该语句放入 `default` 部分。

## 30.2.2. 高级配置

PPP 可以配置为按需提供 DNS 和 NetBIOS 名称服务器地址。

要在 PPP 1.x 版本中启用这些扩展功能，可以在 **/etc/ppp/ppp.conf** 的相关段落中添加以下几行：

```ini
enable msext
set ns 203.14.100.1 203.14.100.2
set nbns 203.14.100.5
```

对于 PPP 2 及更高版本：

```ini
accept dns
set dns 203.14.100.1 203.14.100.2
set nbns 203.14.100.5
```

这会告知客户端主、备名称服务器地址和一个 NetBIOS 名称服务器主机。

在 2 及以上版本中，如果省略 `set dns` 行，则 PPP 会使用 **/etc/resolv.conf** 中的值。

### 30.2.2.1. PAP 与 CHAP 认证

有些 ISP 设置其系统以使用 PAP 或 CHAP 认证机制完成连接的认证部分。如果是这种情况，ISP 在连接时不会提供 `login:` 提示符，而是会直接开始 PPP 会话。

PAP 的安全性低于 CHAP，但安全性通常不是关键问题，因为尽管 PAP 使用明文传输密码，但是在串行线路上传输。攻击者“窃听”的可能性非常小。

需要进行如下更改：

```ini
13      set authname MyUserName
14      set authkey MyPassword
15      set login
```

**第 13 行** ：此行指定 PAP/CHAP 用户名。请将 *MyUserName* 替换为正确的用户名。

**第 14 行**：此行指定 PAP/CHAP 密码。请将 *MyPassword* 替换为正确的密码。你可能还希望添加一行，例如：

```ini
16      accept PAP
```

或

```ini
16      accept CHAP
```

以明确表达使用的认证类型，但默认情况下 PAP 与 CHAP 都是被接受的。

**第 15 行**：当使用 PAP 或 CHAP 时，ISP 通常不需要登录服务器，因此请禁用 "set login" 字符串。

### 30.2.2.2. 使用 PPP 的网络地址转换功能

PPP 具有使用内部 NAT 的能力，而无需依赖内核的 divert 支持。可以通过在 **/etc/ppp/ppp.conf** 中加入以下行启用此功能：

```ini
nat enable yes
```

或者，也可以通过命令行选项 `-nat` 启用 NAT。此外，**/etc/rc.conf** 中有一个名为 `ppp_nat` 的选项，默认是启用的。

在使用此功能时，可以加入如下选项以启用对外连接的端口转发（位于 **/etc/ppp/ppp.conf**）：

```ini
nat port tcp 10.0.0.2:ftp ftp
nat port tcp 10.0.0.2:http http
```

或完全禁止外部连接：

```ini
nat deny_incoming yes
```

## 30.2.3. 最终系统配置

虽然 `ppp` 已经完成配置，但仍需对 **/etc/rc.conf** 进行一些编辑。

从该文件的顶部开始，确保设置了 `hostname=` 行：

```ini
hostname="foo.example.com"
```

如果 ISP 提供了静态 IP 地址和主机名，请使用此主机名作为系统名称。

查找 `network_interfaces` 变量。若要将系统配置为按需拨号连接 ISP，请确保将 **tun0** 设备添加到列表中；否则请将其移除。

```ini
network_interfaces="lo0 tun0"
ifconfig_tun0=
```

> **注意**
>
> `ifconfig_tun0` 变量应为空，并应创建一个名为 **/etc/start\_if.tun0** 的文件。该文件应包含以下一行：
>
> ```sh
> ppp -auto mysystem
> ```
>
> 该脚本将在网络配置时执行，以自动模式启动 ppp 守护进程。如果此主机作为网关使用，建议加入 `-alias`。详情请参考手册页。

确保在 **/etc/rc.conf** 中使用以下行将路由器程序设置为 `NO`：

```ini
router_enable="NO"
```

这一点很重要，因为不能启动 `routed` 守护进程，否则 `routed` 会删除由 `ppp` 创建的默认路由表项。

建议确保 `sendmail_flags` 行中不包含 `-q` 选项，否则 `sendmail` 会定期进行网络查询，可能会触发系统拨号。你可以尝试：

```sh
sendmail_flags="-bd"
```

这样做的缺点是，每当 PPP 链路建立时，`sendmail` 会被迫重新检查邮件队列。要实现自动化，可以在 **ppp.linkup** 中包含 `!bg`：

```ini
1     provider:
2       delete ALL
3       add 0 0 HISADDR
4       !bg sendmail -bd -q30m
```

另一种方法是设置 “dfilter” 来阻止 SMTP 流量。详见示例文件。

## 30.2.4. 使用 `ppp`

剩下的就是重启系统。重启后，可以键入：

```sh
# ppp
```

然后输入 `dial provider` 来启动 PPP 会话，或者，如果想让 `ppp` 在有出站流量时自动建立连接，并且 **start\_if.tun0** 不存在，可输入：

```sh
# ppp -auto provider
```

可以在 `ppp` 在后台运行时与其通信，但前提是设置了合适的诊断端口。要做到这一点，在配置中添加以下行：

```sh
set server /var/run/ppp-tun%d DiagnosticPassword 0177
```

这会让 PPP 监听指定的 UNIX® 域套接字，在允许访问之前，要求客户端提供指定的密码。名称中的 `%d` 会被使用中的 **tun** 设备号所替代。

待套接字建立完成，[pppctl(8)](https://man.freebsd.org/cgi/man.cgi?query=pppctl\&sektion=8\&format=html) 程序就可以在需要操作正在运行的程序的脚本中使用。

## 30.2.5. 配置拨入服务

[“拨入服务”](https://docs.freebsd.org/en/books/handbook/serialcomms/#dialup) 提供了启用拨号服务的良好说明，使用的是 [getty(8)](https://man.freebsd.org/cgi/man.cgi?query=getty\&sektion=8\&format=html)。

除了 `getty`，还有一个更智能的替代方案：[comms/mgetty+sendfax](https://cgit.freebsd.org/ports/tree/comms/mgetty+sendfax/) 这个 Ports，它是专为拨号线路设计的 `getty` 改进版本。

使用 `mgetty` 的优点在于它能主动与调制解调器“对话”，意味着如果在 **/etc/ttys** 中关闭了端口，那么调制解调器将不会接听电话。

从 0.99beta 版本起，`mgetty` 还支持自动检测 PPP 流，这样客户端就可以无需脚本地访问服务器。

关于 `mgetty` 的更多信息，请参阅：<http://mgetty.greenie.net/doc/mgetty_toc.html>。

默认情况下，[comms/mgetty+sendfax](https://cgit.freebsd.org/ports/tree/comms/mgetty+sendfax/) Ports 启用了 `AUTO_PPP` 选项，使 `mgetty` 能够检测 PPP 连接的 LCP 阶段，并自动启动一个 ppp shell。然而由于此过程中不会经过常规的登录/密码步骤，因此需要通过 PAP 或 CHAP 方式对用户进行认证。

本节假设用户已经成功编译并安装了 [comms/mgetty+sendfax](https://cgit.freebsd.org/ports/tree/comms/mgetty+sendfax/) Ports。

确保 **/usr/local/etc/mgetty+sendfax/login.config** 中包含以下内容：

```sh
/AutoPPP/ -     - /etc/ppp/ppp-pap-dialup
```

这会告诉 `mgetty`：当检测到 PPP 连接时，运行 **ppp-pap-dialup**。

创建一个名为 **/etc/ppp/ppp-pap-dialup** 的可执行文件，内容如下：

```sh
#!/bin/sh
exec /usr/sbin/ppp -direct pap$IDENT
```

对于每个在 **/etc/ttys** 中启用的拨号线路，应在 **/etc/ppp/ppp.conf** 中创建相应条目。它们可以与我们之前创建的定义共存。

```ini
pap:
  enable pap
  set ifaddr 203.14.100.1 203.14.100.20-203.14.100.40
  enable proxy
```

通过这种方式登录的每个用户都需要在 **/etc/ppp/ppp.secret** 中拥有用户名/密码。或者也可以添加以下选项，以通过 **/etc/passwd** 使用 PAP 认证用户：

```ini
enable passwdauth
```

要为某些用户分配静态 IP 地址，请在 **/etc/ppp/ppp.secret** 中将该地址作为第三个参数指定。示例请参考 **/usr/share/examples/ppp/ppp.secret.sample**。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://handbook.bsdcn.org/di-30-zhang-ppp/30.2.-pei-zhi-ppp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
