Internet Server专栏
自 己 动 手 架 PPP Server

动 辄 数 十 万 元 的 PPP Server 硬 体 不 再 是 遥 不 可 及 了 , 现 在 我 们 只 要 用 Linux, 外 加 PPP 应 用 程 式 就 可 把 PPP Server 给 架 起 来 !

马 得 翔

  笔 者 在 六 月 份 曾 说 明 如 何 架 设 一 个 SLIP Server, 受 到 读 者 不 错 的 回 响 , 现 在 让 我 们 把 焦 距 对 准 目 前 最 流 行 的 PPP, 来 看 看 如 何 架 好 一 个 PPP Server 来 让 别 人 上 线 。 PPP 协 定 - 使 得 点 对 点 间 的 协 定 走 向 标 准 化 。

  在 开 始 架 设 之 前 , 让 我 们 先 来 看 看 PPP 协 定 的 一 些 概 念 。

PPP 的 基 本 概 念

  1. 就 第 一 层 实 体 层 而 言 , PPP 必 须 建 於 全 双 工 ( full-duplex ) 的 连 结 之 上 , 但 拨 接 线 ( dial-up line ) 或 专 线 ( dedicated line ) 均 可 适 用 ; 此 外 , 8 bits 没 有 同 位 检 查 的 非 同 步 或 同 步 模 式 均 可 。 PPP 对 於 一 般 的 DTE 与 DCE 介 面 均 有 支 援 , 如 EIA RS-232-C, EIA RS-422, EIA RS-423 以 及 CCITT V.35; 而 对 於 DCE 而 言 , PPP 协 定 并 不 需 要 来 自 於 DCE ( 如 m odem ) 的 一 些 控 制 讯 号 , 如 RTS、 CTS、 DCD、 DTR。 但 该 协 定 也 建 议 , 如 果 用 那 些 控 制 信 号 的 话 , 可 增 强 PPP 双 方 的 效 能 ; 换 句 话 说 , PPP 协 定 是 建 议 使 用 那 些 信 号 。

  2. 就 PPP 的 layer 2 而 言 , 它 使 用 HDLC 框 架 ( 一 种 源 自 於 IBM 的 SNA 网 路 架 构 中 data link layer 的 SDLC 框 架 ) , 而 HDLC 中 的 FCS ( Frame Check Sequence ) 可 以 把 传 输 过 程 中 的 错 误 侦 测 出 来 。 此 外 , 流 量 控 制 的 XON/XOFF 信 号 在 PPP 协 定 中 也 可 以 穿 透 过 连 结 , 而 使 双 方 管 制 流 量 。 为 了 去 适 应 不 同 的 第 叁 层 网 路 层 的 环 境 与 第 一 层 实 体 层 , 第 二 层 的 PPP 有 如 下 的 功 能 :

  3. 就 PPP 在 第 叁 层 的 功 能 而 言 , 它 可 封 装 ( encapsulation ) 不 同 型 态 的 网 路 层 的 封 包 , 它 具 有 多 重 协 定 分 封 的 功 能 , 所 以 可 适 用 於 主 机 、 桥 接 器 、 路 由 器 之 间 的 连 结 。 NCP ( Network Control Protocol ) 就 是 负 责 PPP layer 3 的 协 定 , 比 方 说 , 动 态 分 配 IP Address 就 是 由 NCP 达 成 的 。

PPP 框 架 格 式

  它 是 用 软 体 的 方 式 去 模 拟 HDLC 框 架 , 当 然 也 是 用 软 体 的 方 式 去 计 算 出 FCS ( CRC-CCITT , 即 x^0+x^5+x^12+x^16 ) , 图 一 为 其 框 架 格 式 :

旗 标 Flag
它 必 须 为 二 进 码 的 01111110, 代 表 框 架 起 始 或 结 束 , 如 连 续 两 个 框 架 的 话 , 中 间 只 需 插 入 一 个 Flag 即 可 ; 而 Inter-frame Fill 为 框 架 两 不 连 续 框 架 间 所 要 保 持 之 信 号 , 以 非 同 步 模 式 而 言 , 它 须 全 为 *1*, 而 同 步 模 式 须 为 Flag, 即 不 断 送 出 01111110 信 号 。
位 址 Address
它 必 须 为 二 进 码 的 11111111, 即 All-Stations address 才 能 被 对 方 所 接 受 。
控 制 Control
它 必 须 为 二 进 码 的 11111111, 即 Unnumber Information ( UI ) 才 能 被 对 方 所 接 受 。
协 定 Protocol
它 为 2 个 bytes, 它 表 示 之 後 Information 的 型 态 , 如 表 一 : PPP 规 定 所 有 的 协 定 须 为 奇 数 , 且 第 一 个 byte 须 为 偶 数 ; 而 PPP 协 定 范 围 也 有 不 同 的 意 义 , 如 表 二
资 讯 Information
即 上 述 协 定 ( protocol ) 所 指 定 的 资 料 , 内 定 最 大 长 度 为 1,500 bytes。
框 架 检 查 序 FCS
为 16 个 bits, 方 式 为 CRC-CCITT, CRC 的 计 算 包 括 Address、 Control、 Protoc ol、 Information 等 栏 位 。

LCP 封 包 格 式

  LCP 与 NCP 的 封 包 是 架 在 Information 栏 内 , 比 方 说 当 PPP 的 协 定 ( Protocol ) 栏 为 c021 时 , 那 麽 在 Information 栏 内 的 资 料 就 属 於 LCP 封 包 , 而 它 的 格 式 如 图 二

码 ( Code )
1 个 位 元 组 , 它 是 用 来 分 辨 LCP 封 包 的 型 态 , 可 分 为 叁 类 :
识 别 字 ( Identifier)
1 个 位 元 组 , 它 是 用 来 识 别 我 们 的 请 求 或 回 应 。
长 度 ( Length)
2 个 位 元 组 , 它 表 示 Code、 Identifier、 Length 与 Data 的 总 长 度 。
资 料 ( Data)
0 个 或 以 上 个 位 元 组 , 它 为 封 包 所 携 的 资 料 。
  以 上 是 PPP 原 理 的 简 介 , 我 们 原 则 上 可 把 LCP 当 做 是 建 立 、 维 护 、 终 止 连 线 的 协 定 , 同 时 它 利 用 码 ( Code ) 来 让 做 为 封 包 的 识 别 型 态 。 有 了 PPP 协 定 的 基 本 观 念 後 , 且 让 我 们 亲 自 动 手 一 下 , 看 看 要 准 备 怎 样 的 实 验 环 境 。

架 好 实 验 环 境

  首 先 您 的 Linux 核 心 版 本 须 大 於 1.1.14; 同 时 您 的 核 心 也 必 须 包 含 有 原 始 程 式 , 因 为 接 下 来 的 PPP 应 用 程 式 会 更 新 核 心 , 核 心 得 重 新 编 译 。 最 好 您 也 有 一 台 PC ( 笔 记 型 电 脑 由 佳 ) 与 简 易 交 换 机 ( COS ) , 最 後 再 接 上 两 台 数 据 机 , 如 图 叁 , 就 完 成 基 本 的 PPP Server 硬 体 实 验 环 境 。

开 始 编 译 与 装 设 程 式

  首 先 用 gzip -d 把 ppp22b2.tgz 给 解 开 , 它 会 产 生 ppp22b2.tar, 然 後 再 用 tar xvf ppp 22b2.tar 就 可 建 立 ppp-2.2b2 的 子 目 录 , 接 着 进 入 该 子 目 录 就 可 开 始 编 译 以 及 装 设 程 式 , 读 者 可 依 照 如 下 的 步 骤 :

步 骤 一 ./configure
在 ppp-2.2b2 的 目 录 下 执 行 , 此 步 骤 先 去 辨 视 您 所 使 用 的 作 业 系 统 , 再 去 建 立 该 作 业 系 统 所 需 的 makefile, 这 些 makefile 之 後 的 步 骤 会 使 用 到 。
步 骤 二 make kernel
在 ppp-2.2b2 的 目 录 下 执 行 , 它 会 去 更 新 核 心 中 有 关 PPP 部 份 的 原 始 码 , 这 部 份 的 核 心 原 始 码 必 须 与 步 骤 四 的 PPP 应 用 程 式 相 互 配 合 才 行 。
步 骤 叁 make zlilo
转 换 至 Linux 原 始 程 式 的 目 录 之 下 , 并 且 执 行 make zlilo 来 去 编 译 步 骤 二 所 更 新 的 原 始 码 ; 同 时 若 编 译 成 功 它 就 会 去 更 新 Linux 核 心 的 Image, 这 个 动 作 也 会 使 得 LILO ( Linux L oader ) 在 开 机 时 自 动 从 硬 碟 来 载 入 新 的 核 心 。
步 骤 四 make
在 ppp-2.2b2 的 目 录 下 执 行 , 它 会 去 编 译 PPP Server 所 需 的 PPP 应 用 程 式 , 如 chat、 pppd 、 pppstats 等 , 这 部 份 的 程 式 是 与 步 骤 二 的 PPP 核 心 程 式 配 合 。
步 骤 五 make install
把 步 骤 四 所 编 译 好 的 PPP应 用 程 式 装 设 至 /usr/lib/ppp目 录 下 , 同 时 也 会 安 装 说 明 档 。
步 骤 六 重 新 开 机
步 骤 一 至 步 骤 五 若 能 成 功 的 执 行 , 那 麽 PPP Server 所 需 的 核 心 与 PPP 应 用 程 式 都 已 备 妥 , 也 就 是 说 您 的 PPP Server 已 经 成 功 了 一 半 。

接 着 让 我 们 一 步 步 来 检 视 PPP Server 的 启 动 , 好 让 我 们 在 问 题 发 生 时 能 够 逐 步 除 错 , 以 免 自 乱 阵 脚 !

类 别         意 义
建 立 与 架 构 连 结 1 Configure-Request
2 Configure-Ack
3 Configure-Nak
4 Configure-Reject
停 止 连 结 5 Terminate-Request
6 Terminate-Ack
线 路 维 护 与 测 试 7 Code-Reject
8 Protocol-Reject
9 Echo-Request
10 Echo-Reply
11 Discard-Request
12 RESERVED

PPP 启 动

  首 先 用 gzip -d ppplogin.tgz 把 ppplogin 这 支 程 式 给 解 压 缩 , 然 後 再 用 tar xvf ppplogin.tar 就 可 把 ppplogin 这 个 script file 给 取 出 来 , ppplogin 是 个 很 重 要 的 档 案 , 我 们 之 後 会 用 到 。

/etc/inittab
这 是 开 启 拨 接 线 给 PPP 使 用 者 , 例 如 : 以 下 是 把 COM1 设 定 为 拨 接 专 用 的 介 面 , 它 的 服 务 程 式 为 /sbin/agetty。
d1:45:respawn:/sbin/agetty -mt60 19200,9600,2400
  基 本 上 Linux 的 /etc/inittab 档 都 有 如 上 的 定 义 , 您 只 要 把 # ( comment ) 拿 掉 即 可 。 另 外 您 也 须 留 意 modem 的 内 建 设 定 , 务 必 使 得 它 能 与 agetty 相 容 ; 例 如 : modem 内 定 与 DTE ( 如 PC ) 的 速 率 要 能 与 agetty 的 设 定 相 容 , 同 时 PPP Server 所 接 modem 的 设 定 ( 如 铃 响 几 声 後 开 始 进 入 回 应 模 式 ) 也 都 必 须 留 意 , 这 些 设 定 是 不 随 modem 关 机 而 消 失 的 。

/etc/passwd
这 是 用 来 设 定 使 用 者 登 录 时 所 须 敲 入 的 帐 号 与 密 码 , 例 如 以 下 的 指 令 :
ppp::501:101:ppp:/tmp:/sbin/ppplogin
  就 是 开 启 一 个 使 用 者 为 ppp 的 帐 号 , 不 用 密 码 , 使 用 者 ppp 的 识 别 码 为 501, 群 组 识 别 码 为 101, 使 用 者 的 根 目 录 为 /tmp, login 正 确 後 所 执 行 的 程 式 为 /sbin/ppplogin。

  请 注 意 , 这 个 ppplogin 就 是 先 前 从 ppplogin.tgz 给 解 压 缩 出 来 , 并 且 我 们 把 它 拷 备 至 /sb in 目 录 之 下 , 别 忘 了 它 必 须 设 定 为 可 执 行 模 式 。

/sbin/ppplogin
它 是 一 个 由 perl 所 写 成 的 script 档 , 当 使 用 者 成 功 的 login 之 後 , 这 个 script 会 被 叫 用 来 做 为 使 用 者 签 入 与 PPP 应 用 程 式 ( 如 PPPD, 由 编 译 先 前 的 ppp22b2.tgz 所 产 生 ) 间 的 桥 梁 , 它 的 功 用 详 述 如 下 :

  首 先 ppplogin 会 去 了 解 该 位 使 用 者 是 谁 ( 用 /usr/bin/whoami ) 与 他 的 终 端 机 名 称 为 何 ( 用 / usr/bin/tty ) , 然 後 用 此 资 讯 去 查 阅 /etc/slip.hosts 确 认 使 用 者 是 否 合 法 , 以 及 /e tc/slip.tty 确 认 终 端 机 名 称 是 在 许 可 的 范 围 之 内 , 如 果 设 定 都 正 确 的 话 , ppplogin 就 会 取 得 IP Address, 然 後 再 去 呼 叫 /usr/lib/ppp/pppd。

  以 下 为 笔 者 自 己 PPP Server 中 的 slip.hosts 与 slip.tty 的 设 定 :

/etc/slip.hosts:
格 式 : login local_addr remote_addr netmask opt1 opt2
例 子 : ppp 148.5.3.211 DYNAMIC 0xffff0000 compressed
  这 个 设 定 是 把 ppp 这 位 使 用 者 的 设 定 为 DYNAMIC IP Address 模 式 , 也 就 是 他 的 IP Address 是 根 据 他 所 登 录 的 终 端 机 名 称 以 及 /etc/slip.tty 的 设 定 所 决 定 的 , 换 句 话 说 , 每 次 登 录 至 PPP Server 的 IP Address 都 是 不 固 定 的 。

  如 果 读 者 不 想 把 PPP Server 设 定 在 DYNAMIC IP Address 模 式 而 想 把 它 设 为 固 定 IP Address 的 话 , 那 麽 直 接 把 DYNAMIC 改 为 您 想 设 定 的 IP Address 即 可 , 同 时 ppplogin 也 不 会 再 去 查 阅 slip.tty 了 。

/etc/slip.tty: 格 式 : /dev/tty?? xxx.xxx.xxx.xxx
例 子 : /dev/ttys0 148.5.3.213
例 子 : /dev/ttys1 148.5.3.214
  它 是 用 来 设 定 终 端 机 名 称 与 所 对 应 的 IP Address; 例 如 使 用 者 从 com1所 连 接 的 modem登 录 进 来 , 那 麽 他 的 终 端 机 名 称 为 /dev/ttys0, 同 时 他 所 分 配 到 的 IP Address为 148.5.3.213 ; 同 理 , 从 com2进 来 则 为 /dev/ttys1, IP Address为 148.5.3.214。

/usr/lib/ppp/pppd
这 个 程 式 是 由 先 前 编 译 ppp22b2.tgz, 然 後 install 产 生 的 , ppplogin 在 取 得 IP Address ( 不 管 是 固 定 IP 或 DYNAMIC IP ) 後 , 就 把 执 行 权 交 给 pppd, 至 此 , 连 结 的 两 端 完 全 进 入 PPP 模 式 , 而 pppd 就 是 上 述 PPP 原 理 的 实 作 程 式 。

上 线 看 看

  以 下 是 笔 者 用 WIN95 连 上 自 己 所 架 的 PPP Server 的 过 程 , 首 先 是 架 好 如 图 叁 的 硬 体 , 然 後 拨 号 上 线 之 後 , 出 现 khhp83 login: , 接 着 笔 者 回 应 ppp 来 登 录 , 如 图 四 , 等 一 会 而 我 们 就 成 功 的 上 线 啦 ! 如 图 五 所 示 。

PPP 分 析

  读 者 可 用 ifconfig、 netstat 与 先 前 编 译 好 的 PPP 应 用 程 式 pppstates 来 去 分 析 PPP; 另 外 README.linux 是 个 很 不 错 的 PPP Server 说 明 , 读 者 解 开 ppplogin.tgz 後 就 可 看 到 , 同 时 该 说 明 也 提 及 一 些 不 错 的 PPP Server 的 安 全 手 则 , 蛮 有 意 思 的 。 PPP 的 基 本 的 原 理 请 参 阅 RFC 1661 与 RFC 1662, 同 时 由 於 PPP 协 定 较 为 烦 琐 , 它 还 包 含 有 很 多 的 细 目 , 如 RFC 1332 的 IPCP、 RFC 1333 PPP Link Quality Monitory、 RFC 1334 PPP Authentication Protocols, 有 兴 趣 的 读 者 可 参 阅 上 述 的 RFC; 同 时 笔 者 认 为 , 若 各 位 对 PPP 协 定 有 兴 趣 , 不 要 光 读 那 些 RFC, 最 好 自 己 也 能 装 一 次 PPP Server 与 研 读 原 始 程 式 , 这 样 才 能 真 正 了 解 PPP 协 定 与 PPP Server。

( 作 者 任 职 於 台 湾 金 讯 电 子 股 份 有 限 公 司 E-Mail: derek_m1@verifone.com