13.07.2015 Views

Squid 全套使用手册 - 开源中国社区- 软件镜像下载

Squid 全套使用手册 - 开源中国社区- 软件镜像下载

Squid 全套使用手册 - 开源中国社区- 软件镜像下载

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

tax credits that will encourage more use of new products such as seeds. Producers, private industryand governments should all contribute to supporting research and innovation.‐ 7 ‐


译 器 , 它 顺 从 ANSI 指 令 , 那 么 也 一 样 。GNU C 编 译 器 (gcc) 是 很 好 的 选 择 , 它 被 广 泛 使 用 。大 部 分 操 作 系 统 在 其 标 准 安 装 中 附 带 了 C 编 译 器 , 不 过 Solaris 和 HP-UX 除 外 。 假 如 你 使 用这 样 的 操 作 系 统 , 那 可 能 没 有 安 装 编 译 器 。理 论 上 你 应 该 在 即 将 运 行 squid 的 机 器 上 编 译 squid。 安 装 过 程 侦 察 你 的 操 作 系 统 以 发 现 特 定的 参 数 , 例 如 可 用 文 件 描 述 符 的 数 量 。 然 而 , 假 如 你 的 系 统 没 有 C 编 译 器 存 在 , 你 也 许 会 在 其他 机 器 上 编 译 squid, 然 后 把 二 进 制 代 码 copy 回 来 。 如 果 操 作 系 统 不 同 , 那 么 squid 可 能 会遇 到 问 题 。 假 如 操 作 系 统 有 不 同 的 内 核 配 置 ,squid 会 变 得 混 乱 。除 了 C 编 译 器 , 你 还 需 要 perl 和 awk。awk 是 所 有 unix 系 统 的 标 准 程 序 , 所 以 你 不 必 担 心它 。perl 也 是 相 当 普 及 的 , 但 它 也 许 没 有 默 认 安 装 在 你 的 系 统 上 。 你 需 要 gzip 程 序 来 解 压 源代 码 发 布 文 件 。对 Solaris 用 户 , 请 确 认 /usr/ccs/bin 包 含 在 你 的 PATH 环 境 变 量 里 , 即 使 你 使 用 gcc 编 译器 。 为 了 编 译 squid,make 和 ar 程 序 需 要 在 这 个 目 录 找 到 。3.2 解 开 源 代 码 包在 下 载 完 源 代 码 后 , 你 需 要 在 某 个 目 录 解 开 它 。 具 体 哪 个 目 录 无 关 紧 要 。 你 能 解 开 squid 在 你的 家 目 录 或 任 何 其 他 地 方 , 大 概 需 要 20M 的 自 由 磁 盘 空 间 。 我 个 人 喜 欢 用 /tmp。 使 用 tar 命令 来 展 开 源 代 码 目 录 :% cd /tmp% tar xzvf /some/where/squid-2.5.STABLE4-src.tar.gz一 些 tar 程 序 不 支 持 z 选 项 , 该 选 项 自 动 解 压 gzip 文 件 。 如 果 这 样 , 你 需 要 运 行 如 下 命 令 :% gzip -dc /some/where/squid-2.5.STABLE4-src.tar.gz | tar xvf -一 旦 源 代 码 被 展 开 , 下 一 步 通 常 是 配 置 源 代 码 树 。 然 而 , 假 如 这 是 你 第 一 次 编 译 squid, 你 应 确认 特 定 的 内 核 资 源 限 制 足 够 高 。 怎 样 发 现 , 请 继 续 。3.3 调 整 内 核<strong>Squid</strong> 在 高 负 载 下 , 需 要 大 量 的 内 核 资 源 。 特 别 的 , 你 需 要 给 你 的 系 统 配 置 比 正 常 情 况 更 高 的文 件 描 述 符 和 缓 存 。 文 件 描 述 符 的 限 制 通 常 很 恼 人 。 你 最 好 在 开 始 编 译 squid 之 前 来 增 加 这 些限 制 的 大 小 。因 为 这 点 , 你 可 能 为 了 避 免 重 建 内 核 的 麻 烦 , 而 倾 向 于 使 用 预 编 译 的 二 进 制 版 本 。 不 幸 的 是 , 不管 如 何 你 必 须 重 建 一 个 新 内 核 。squid 和 内 核 通 过 数 据 结 构 来 交 换 信 息 , 数 据 结 构 的 大 小 不 能超 过 设 置 的 文 件 描 述 符 的 限 制 。squid 在 运 行 时 检 查 这 些 设 置 , 并 且 使 用 最 安 全 的 ( 最 小 的 )值 。 这 样 , 即 使 预 编 译 的 二 进 制 版 本 有 比 你 的 内 核 更 高 的 文 件 描 述 符 , 但 还 是 以 你 系 统 内 核 的 实际 数 值 为 主 。为 了 改 编 一 些 参 数 , 你 需 要 重 建 新 内 核 。 这 个 过 程 在 不 同 的 操 作 系 统 之 间 不 同 。 假 如 需 要 , 请 参阅 Unix 系 统 管 理 员 手 册 (Prentice Hall 出 版 ) 或 者 你 的 操 作 系 统 文 档 。 假 如 你 正 使 用 Linux,


可 能 不 必 重 建 内 核 。3.3.1 文 件 描 述 符文 件 描 述 符 是 一 个 简 单 的 整 数 , 用 以 标 明 每 一 个 被 进 程 所 打 开 的 文 件 和 socket。 第 一 个 打 开 的文 件 是 0, 第 二 个 是 1, 依 此 类 推 。Unix 操 作 系 统 通 常 给 每 个 进 程 能 打 开 的 文 件 数 量 强 加 一 个限 制 。 更 甚 的 是 ,unix 通 常 有 一 个 系 统 级 的 限 制 。因 为 squid 的 工 作 方 式 , 文 件 描 述 符 的 限 制 可 能 会 极 大 的 影 响 性 能 。 当 squid 用 完 所 有 的 文 件描 述 符 后 , 它 不 能 接 收 用 户 新 的 连 接 。 也 就 是 说 , 用 完 文 件 描 述 符 导 致 拒 绝 服 务 。 直 到 一 部 分 当前 请 求 完 成 , 相 应 的 文 件 和 socket 被 关 闭 ,squid 不 能 接 收 新 请 求 。 当 squid 发 现 文 件 描 述符 短 缺 时 , 它 会 发 布 警 告 。在 运 行 ./configure 之 前 , 检 查 你 的 系 统 的 文 件 描 述 符 限 制 是 否 合 适 , 能 给 你 避 免 一 些 麻 烦 。 大多 数 情 况 下 ,1024 个 文 件 描 述 符 足 够 了 。 非 常 忙 的 cache 可 能 需 要 4096 或 更 多 。 在 配 置 文件 描 述 符 限 制 时 , 我 推 荐 设 置 系 统 级 限 制 的 数 量 为 每 个 进 程 限 制 的 2 倍 。通 常 在 你 的 Unix shell 中 能 找 到 系 统 的 文 件 描 述 符 限 制 。 所 有 的 C shell 及 其 类 似 的 shell 有内 建 的 limit 命 令 。 更 新 的 Bourne shell 及 其 类 似 的 shell 有 一 条 叫 做 ulimit 的 命 令 。 为 了发 现 你 的 系 统 的 文 件 描 述 符 限 制 , 试 运 行 如 下 命 令 :csh% limit descriptors unlimitedcsh% limit descriptorsdescriptors 4096或 者sh$ ulimit -n unlimitedsh$ ulimit -n4096在 Freebsd 上 , 你 能 使 用 sysctl 命 令 :% sysctl -a | grep maxfileskern.maxfiles: 8192kern.maxfilesperproc: 4096如 果 你 不 能 确 认 文 件 描 述 符 限 制 , squid 的 ./configure 脚 本 能 替 你 做 到 。 当 你 运行 ./configure 时 , 请 见 3.4 章 节 , 观 察 末 尾 这 样 的 输 出 :checking Maximum number of file descriptors we can open... 4096假 如 其 他 的 limit,ulimit, 或 者 ./configure 报 告 这 个 值 少 于 1024, 你 不 得 不 在 编 译 squid 之前 , 花 费 时 间 来 增 加 这 个 限 制 值 的 大 小 。 否 则 ,squid 在 高 负 载 时 执 行 性 能 将 很 低 。增 加 文 件 描 述 符 限 制 的 方 法 因 系 统 不 同 而 不 同 。 下 面 的 章 节 提 供 一 些 方 法 帮 助 你 开 始 。


3.3.1.1 Freebsd,NetBSD,OpenBSD编 辑 你 的 内 核 配 置 文 件 , 增 加 如 下 一 行 :options MAXFILES=8192在 OpenBSD 上 , 使 用 option 代 替 options。 然 后 ,configure, 编 译 , 和 安 装 新 内 核 。 最 后重 启 系 统 以 使 内 核 生 效 。3.3.1.2 Linux在 Linux 上 配 置 文 件 描 述 符 有 点 复 杂 。 在 编 译 squid 之 前 , 你 必 须 编 辑 系 统 include 文 件 中的 一 个 , 然 后 执 行 一 些 shell 命 令 。 请 首 先 编 辑 /usr/include/bits/types.h 文 件 , 改 变__FD_SETSIZE 的 值 :#define _ _FD_SETSIZE 8192下 一 步 , 使 用 这 个 命 令 增 加 内 核 文 件 描 述 符 的 限 制 :# echo 8192 >; /proc/sys/fs/file-max最 后 , 增 加 进 程 文 件 描 述 符 的 限 制 , 在 你 即 将 编 译 squid 的 同 一 个 shell 里 执 行 :sh# ulimit -Hn 8192该 命 令 必 须 以 root 运 行 , 仅 仅 运 行 在 bash shell。 不 必 重 启 机 器 。使 用 这 个 技 术 , 你 必 须 在 每 一 次 系 统 启 动 后 执 行 上 述 echo 和 ulimit 命 令 , 或 者 至 少 在 squid启 动 之 前 。 假 如 你 使 用 某 个 rc.d 脚 本 来 启 动 squid, 那 是 一 个 放 置 这 些 命 令 的 好 地 方 。3.3.1.3 Solaris增 加 该 行 到 你 的 /etc/system 文 件 :set rlim_fd_max = 4096然 后 , 重 启 机 器 以 使 改 动 生 效 。3.3.2 Mbuf ClustersBSD 基 础 的 网 络 代 码 使 用 一 个 叫 做 mbuf( 参 阅 W.R.Stevens 的 TCP/IP 描 述 卷 2) 的 数 据结 构 。Mbuf 典 型 的 是 小 块 内 存 ( 例 如 128 字 节 )。 较 大 的 网 络 包 的 数 据 存 储 在 mbuf clusters里 。 内 核 可 能 给 系 统 可 用 的 mbuf clusters 的 总 数 量 强 加 一 个 最 高 限 制 。 你 能 使 用 netstat 命令 来 发 现 这 个 限 制 :% netstat -m196/6368/32768 mbufs in use (current/peak/max):146 mbufs allocated to data50 mbufs allocated to packet headers103/6182/8192 mbuf clusters in use (current/peak/max)


13956 Kbytes allocated to network (56% of mb_map in use)0 requests for memory denied0 requests for memory delayed0 calls to protocol drain routines在 这 个 例 子 里 , 有 8192 个 mbuf clusters 可 用 , 但 是 永 远 不 会 同 时 用 到 6182 个 。 当 系 统用 尽 mbuf clusters 时 ,I/O 机 制 例 如 read() 和 write() 返 回 “ 无 缓 存 空 间 可 用 ” 的 错 误 信 息 。NetBSD 和 OpenBSD 使 用 netstat -m 不 会 显 示 mbuf 的 输 出 。 代 替 的 , 它 们 在 syslog 里报 告 :"WARNING: mclpool limit reached" 。为 了 增 加 mbuf clusters 的 数 量 , 你 必 须 在 内 核 配 置 文 件 里 增 加 一 个 选 项 :options NMBCLUSTERS=16384<strong>Squid</strong> 中 文 权 威 指 南 33.3.3 临 时 端 口 范 围临 时 端 口 是 TCP/IP 栈 分 配 给 出 去 连 接 的 本 地 端 口 。 换 句 话 说 , 当 squid 发 起 一 条 连 接 到 另 一台 服 务 器 , 内 核 给 本 地 socket 分 配 一 个 端 口 号 。 这 些 本 地 端 口 号 有 特 定 的 范 围 限 制 。例 如 , 在 FreeBSD 上 , 默 认 的 临 时 端 口 范 围 是 1024-5000。临 时 端 口 号 的 短 缺 对 非 常 忙 的 代 理 服 务 器 ( 例 如 每 秒 数 百 个 连 接 ) 来 说 , 会 较 大 的 影 响 性 能 。 这是 因 为 一 些 TCP 连 接 在 它 们 被 关 闭 时 进 入 TIME_WAIT 状 态 。 当 连 接 进 入 TIME_WATI 状 态时 , 临 时 端 口 号 不 能 被 重 用 。你 能 使 用 netstat 命 令 来 显 示 有 多 少 个 连 接 进 入 这 个 状 态 :% netstat -n | grep TIME_WAITProto Recv-Q Send-Q Local Address Foreign Address (state)tcp4 0 0 192.43.244.42.19583 212.67.202.80.80 TIME_WAITtcp4 0 0 192.43.244.42.19597 202.158.66.190.80 TIME_WAITtcp4 0 0 192.43.244.42.19600 207.99.19.230.80 TIME_WAITtcp4 0 0 192.43.244.42.19601 216.131.72.121.80 TIME_WAITtcp4 0 0 192.43.244.42.19602 209.61.183.115.80 TIME_WAITtcp4 0 0 192.43.244.42.3128 128.109.131.47.25666 TIME_WAITtcp4 0 0 192.43.244.42.3128 128.109.131.47.25795 TIME_WAITtcp4 0 0 192.43.244.42.3128 128.182.72.190.1488 TIME_WAITtcp4 0 0 192.43.244.42.3128 128.182.72.190.2194 TIME_WAIT注 意 这 个 例 子 中 既 有 客 户 端 连 接 又 有 服 务 器 端 的 连 接 。 客 户 端 连 接 有 3128 作 为 临 时 端 口 号 ,服 务 器 端 连 接 有 80 作 为 远 程 主 机 的 端 口 号 。 临 时 端 口 号 出 现 在 本 地 地 址 栏 里 。 在 该 例 子 里 , 它们 是 19000 秒 。


如 果 你 没 有 看 到 数 千 个 临 时 端 口 在 TIME_WAIT 状 态 , 那 也 许 不 必 增 加 这 个 端 口 范 围 。在 Freebsd 上 , 用 如 下 命 令 增 加 临 时 端 口 范 围 :# sysctl -w net.inet.ip.portrange.last=30000在 OpenBSD 上 , 命 令 类 似 , 但 sysctl 变 量 有 不 同 的 名 字 :# sysctl -w net.inet.ip.portlast=49151在 NetBSD 上 , 事 情 稍 有 不 同 。 默 认 的 值 是 49152-65535. 为 了 增 加 这 个 范 围 , 需 改 变 最 低限 制 :# sysctl -w net.inet.ip.anonportmin=10000在 Linux 上 , 简 单 的 写 一 对 数 字 到 下 列 指 定 文 件 :# echo "1024 40000" >; /proc/sys/net/ipv4/ip_local_port_range不 要 忘 记 将 这 些 命 令 加 到 你 的 系 统 启 动 脚 本 中 , 以 使 机 器 每 一 次 重 启 后 都 生 效 。3.4 Configure 脚 本象 许 多 其 他 Unix 软 件 一 样 ,squid 在 开 始 编 译 之 前 使 用 ./configure 脚 本 来 了 解 操 作 系 统 信息 。./configure 脚 本 由 流 行 的 GNU autoconf 程 序 产 生 。 当 script 运 行 时 , 它 用 不 同 的 方 法来 侦 察 系 统 , 以 发 现 关 于 库 , 函 数 , 类 型 , 参 数 , 和 有 没 有 功 能 被 提 供 等 。./configure 所 做 的第 一 件 事 情 是 去 找 一 个 C 编 译 器 。 假 如 C 编 译 器 没 有 找 到 , 或 者 编 译 一 个 简 单 的 测 试 程 序 失败 ,./configure 脚 本 不 能 继 续 。./configure 脚 本 有 大 量 的 选 项 。 最 重 要 的 是 安 装 prefix。 在 运 行 ./configure 之 前 , 你 需 要决 定 squid 被 安 装 在 哪 里 。prefix 选 项 指 定 squid 日 志 , 二 进 制 文 件 , 和 配 置 文 件 的 默 认 位 置 。你 可 以 在 安 装 之 后 改 变 这 些 文 件 的 位 置 , 但 假 如 你 现 在 决 定 , 事 情 更 容 易 。默 认 的 安 装 位 置 是 /usr/local/squid.squid 将 文 件 放 在 prefix 指 定 目 录 下 面 的 7 个 子 目 录 :% ls -l /usr/local/squidtotal 5drwxr-x--- 2 wessels wheel 512 Apr 28 20:42 bindrwxr-x--- 2 wessels wheel 512 Apr 28 20:42 etcdrwxr-x--- 2 wessels wheel 512 Apr 28 20:42 libexecdrwxr-x--- 3 wessels wheel 512 Apr 28 20:43 mandrwxr-x--- 2 wessels wheel 512 Apr 28 20:42 sbindrwxr-x--- 4 wessels wheel 512 Apr 28 20:42 sharedrwxr-x--- 4 wessels wheel 512 Apr 28 20:43 var<strong>Squid</strong> 使 用 bin,etc,libexec,man,sbin, 和 share 目 录 存 放 一 些 相 对 较 小 的 文 件 ( 或 其 他 目录 ), 这 些 文 件 不 经 常 改 变 。 但 var 目 录 的 文 件 别 有 洞 天 。 这 里 你 可 以 发 现 squid 的 日 志 文 件 ,它 增 长 得 非 常 大 ( 数 十 或 数 百 兆 )。var 也 是 实 际 磁 盘 cache 的 默 认 位 置 。 你 也 许 想 将 var 目


录 放 在 磁 盘 空 间 足 够 的 位 置 , 这 样 做 较 容 易 的 方 法 是 使 用 --localstatedir 选 项 :% ./configure --localstatedir=/bigdisk/var当 配 置 squid 时 , 你 不 必 对 这 些 路 径 名 称 担 心 太 多 。 你 以 后 可 以 在 squid.conf 文 件 里 改 变 这些 路 径 名 。3.4.1 configure 选 项./configure 脚 本 有 大 量 的 不 同 选 项 , 它 们 以 - 开 始 。 当 你 敲 入 ./configure --help 时 , 能 看 到选 项 的 完 整 列 表 。 一 些 选 项 对 所 有 configure 脚 本 是 通 用 的 , 还 有 一 些 是 squid 专 有 的 。 下 面是 你 可 能 用 得 到 的 标 准 选 项 :--perfix =PREFIX如 前 面 描 述 的 一 样 , 这 里 设 置 安 装 目 录 。 安 装 目 录 是 所 有 可 执 行 文 件 , 日 志 , 和 配 置 文 件 的 默 认目 录 。 在 整 本 书 中 ,$prefix 指 你 选 择 的 安 装 目 录 。--localstatedir =DIR该 选 项 允 许 你 改 变 var 目 录 的 安 装 位 置 。 默 认 是 $prefix/var, 但 也 许 你 想 改 变 它 , 以 使 squid的 磁 盘 缓 存 和 日 志 文 件 被 存 储 在 别 的 地 方 。--sysconfdir =DIR该 选 项 允 许 你 改 变 etc 目 录 的 位 置 。 默 认 的 是 $prefix/etc。 假 如 你 想 使 用 /usr 作 为 安 装 位 置 ,你 也 许 该 配 置 --sysconfdir 为 /etc.以 下 是 squid 的 专 有 ./configure 选 项 :--enable-dlmalloc[=LIB]在 一 些 系 统 上 , 内 建 的 内 存 分 配 机 制 (malloc) 在 使 用 squid 时 表 现 不 尽 人 意 。 使 用 --enabledlmalloc选 项 将 squid 源 代 码 包 中 的 dlmalloc 包 编 译 和 链 接 进 来 。 假 如 你 的 系 统 中 已 安 装dlmalloc , 你 能 使 用 =LIB 参 数 指 定 库 的 路 径 。 请 见http://g.oswego.edu/dl/html/malloc.html 更 多 关 于 dlmalloc 的 信 息 。--enable-gnuregex在 访 问 控 制 列 表 和 其 他 配 置 指 令 里 ,squid 使 用 正 则 表 达 式 作 为 匹 配 机 制 。GNU 的 正 则 表 达 式库 包 含 在 squid 的 源 代 码 包 里 ; 它 可 以 在 没 有 内 建 正 则 表 达 式 的 操 作 系 统 中 使 用 。./configure脚 本 侦 察 你 系 统 中 的 正 则 表 达 式 库 , 假 如 必 要 , 它 可 以 激 活 使 用 GNU 正 则 表 达 式 。 如 果 因 为 某些 理 由 , 你 想 强 制 使 用 GNU 正 则 表 达 式 , 你 可 以 将 这 个 选 项 加 到 ./configure 命 令 后 。--enable-carpCache 数 组 路 由 协 议 (CARP) 用 来 转 发 丢 失 的 cache 到 父 cache 的 数 组 或 cluster。 在 10.9章 有 更 多 关 于 CARP 的 细 节 。--enable-async-io[=N_THREADS]同 步 I/O 是 squid 技 术 之 一 , 用 以 提 升 存 储 性 能 。aufs 模 块 使 用 大 量 的 线 程 来 执 行 磁 盘 I/O 操


作 。 该 代 码 仅 仅 工 作 在 linux 和 solaris 系 统 中 。=N_THREADS 参 数 改 变 squid 使 用 的 线程 数 量 。aufs 和 同 步 I/O 在 8.4 章 中 被 讨 论 。请 注 意 --enable-async-io 是 打 开 其 他 三 个 ./configure 选 项 的 快 捷 方 式 , 它 等 同 于 :--with-aufs-threads=N_THREADS--with-pthreads--enable-storeio=ufs,aufs--with-pthreads该 选 项 导 致 编 译 过 程 链 接 到 你 系 统 中 的 P 线 程 库 。aufs 存 储 模 块 是 squid 中 唯 一 需 要 使 用 线程 的 部 分 。 通 常 来 说 , 如 果 你 使 用 --enable-saync-io 选 项 , 那 么 不 必 再 单 独 指 定 该 选 项 , 因为 它 被 自 动 激 活 了 。--enable-storeio=LIST<strong>Squid</strong> 支 持 大 量 的 不 同 存 储 模 块 。 通 过 使 用 该 选 项 , 你 告 诉 squid 编 译 时 使 用 哪 个 模 块 。 在squid-2.5 中 , 支 持 ufs,aufs,diskd, 和 null 模 块 。 通 过 查 询 src/fs 中 的 目 录 , 你 能 得 到 一 个模块 列 表 。LIST 是 一 个 以 逗 号 分 隔 的 模 块 列 表 , 例 如 :% ./configure --enable-storeio=afus,diskd,ufsufs 模 块 是 默 认 的 , 看 起 来 问 题 最 少 。 不 幸 的 是 , 它 性 能 有 限 。 其 他 模 块 可 能 在 某 些 操 作 系 统 中不 必 编 译 。 关 于 squid 存 储 模 块 的 完 整 描 述 , 请 见 第 8 章 。--with-aufs-threads=N_THREADS指 定 aufs 存 储 机 制 使 用 的 线 程 数 量 ( 见 8.4 章 )。 squid 默 认 根 据 缓 存 目 录 的 数 量 , 自 动 计 算需 要 使 用 多 少 线 程 。--enable-heap-replacement该 选 项 不 再 使 用 , 但 被 保 留 用 于 向 后 兼 容 性 。 你 该 使 用 --enable-removal-policies 来 代 替 。--enable-removal-policies=LIST排 除 策 略 是 squid 需 要 腾 出 空 间 给 新 的 cache 目 标 时 , 用 以 排 除 旧 目 标 的 机 制 。squid-2.5 支持 3 个 排 除 策 略 : 最 少 近 期 使 用 (LRU), 贪 婪 对 偶 大 小 (GDS), 最 少 经 常 使 用 (LFU)。然 而 , 因 为 一 些 理 由 ,./configure 选 项 使 指 定 的 替 代 策 略 和 需 要 执 行 它 们 的 基 本 数 据 结 构 之 间的 差 别 模 糊 化 。LRU 是 默 认 的 , 它 以 双 链 表 数 据 结 构 执 行 。GDS 和 LFU 使 用 堆 栈 的 数 据 结 构 。为 了 使 用 GDS 或 LFU 策 略 , 你 指 定 :% ./configure --enable-removal-policies=heap然 后 你 在 squid 的 配 置 文 件 里 选 择 使 用 GDS 或 LFU。 假 如 你 想 重 新 使 用 LRU, 那 么 指 定 :% ./configure --enable-removal-policies=heap,lru更 多 的 关 于 替 换 策 略 的 细 节 请 见 7.5 章 。


--enable-icmp如 在 10.5 章 中 描 述 的 一 样 ,squid 能 利 用 ICMP 消 息 来 确 定 回 环 时 间 尺 寸 , 非 常 象 ping 程 序 。你 能 使 用 该 选 项 来 激 活 这 些 功 能 。--enable-delay-pools延 时 池 是 squid 用 于 传 输 形 状 或 带 宽 限 制 的 技 术 。 该 池 由 大 量 的 客 户 端 IP 地 址 组 成 。 当 来 自这 些 客 户 端 的 请 求 处 于 cache 丢 失 状 态 , 他 们 的 响 应 可 能 被 人 工 延 迟 。 关 于 延 时 池 的 更 多 细 节请 见 附 录 C。--enable-useragent-log该 选 项 激 活 来 自 客 户 请 求 的 HTTP 用 户 代 理 头 的 日 志 。 更 多 细 节 请 见 13.5 章 。--enable-referer-log该 选 项 激 活 来 自 客 户 请 求 的 HTTP referer 日 志 。 更 多 细 节 请 见 13.4 章 。--disable-wccpWeb cache 协 调 协 议 (WCCP) 是 CISCO 的 专 有 协 议 , 用 于 阻 止 或 分 发 HTTP 请 求 到 一 个 或多 个 caches。WCCP 默 认 被 激 活 , 假 如 你 愿 意 , 可 以 使 用 该 选 项 来 禁 止 该 功 能 。--enable-snmp简 单 网 络 管 理 协 议 (SNMP) 是 监 视 网 络 设 备 和 服 务 器 的 流 行 方 法 。 该 选 项 导 致 编 译 过 程 去 编 译 所有 的 SNMP 相 关 的 代 码 , 包 括 一 个 裁 切 版 本 的 CMU SNMP 库 。--enable-cachemgr -hostname[=hostname]cachemgr 是 一 个 CGI 程 序 , 你 能 使 用 它 来 管 理 查 询 squid。 默 认 cachemgr 的 hostname值 是 空 的 , 但 你 能 使 用 该 选 项 来 指 定 一 个 默 认 值 。 例 如 :% ./configure --enable-cachemgr-hostname=mycache.myorg.net--enable-arp-aclsquid 在 一 些 操 作 系 统 中 支 持 ARP, 或 者 以 太 地 址 访 问 控 制 列 表 。 该 代 码 使 用 非 标 准 的 函 数 接 口 ,来 执 行 ARP 访 问 控 制 列 表 , 所 以 它 默 认 被 禁 止 。 假 如 你 在 linux 或 solaris 上 使 用 squid, 你可 能 用 的 上 这 个 功 能 。--enable-htcpHTCP 是 超 文 本 缓 存 协 议 -- 类 似 于 ICP 的 内 部 缓 存 协 议 。 更 多 细 节 请 见 10.8 章 。--enable-ssl使 用 该 选 项 赋 予 squid 终 止 SSL/TLS 连 接 的 能 力 。 注 意 这 仅 仅 工 作 在 web 加 速 器 中 用 以 加 速请 求 。 更 多 细 节 请 见 15.2.2 章 节 。--with-openssl[=DIR]假 如 必 要 , 你 使 用 该 选 项 来 告 诉 squid 到 哪 里 找 到 OpenSSL 库 或 头 文 件 。 假 如 它 们 不 在 默 认位 置 , 在 该 选 项 后 指 定 它 们 的 父 路 径 。 例 如 :% ./configure --enable-ssl --with-ssl=/opt/foo/openssl


在 这 个 例 子 中 , 你 的 编 译 器 将 在 /opt/foo/openssl/include 目 录 中 找 头 文 件 ,/opt/foo/openssl/lib 中 找 库 文 件 。在--enable-cache-digestsCache 消 化 是 ICP 的 另 一 个 替 代 , 但 有 着 截 然 不 同 的 特 性 。 请 见 10.7 章 。--enable-err-languages="lang1 lang2 ..."squid 支 持 定 制 错 误 消 息 , 错 误 消 息 可 以 用 多 种 语 言 报 告 。 该 选 项 指 定 复 制 到 安 装 目 录($prefix/share/errors) 的 语 言 。 假 如 你 不 使 用 该 选 项 , 所 有 可 用 语 言 被 安 装 。 想 知 道 何 种 语言 可 用 , 请 见 源 代 码 包 里 errors 目 录 下 的 目 录 列 表 。 如 下 显 示 如 何 激 活 多 种 语 言 :% ./configure --enable-err-languages="Dutch German French" ...--enable-default-err-language=lang该 选 项 设 置 error_directory 指 令 的 默 认 值 。 例 如 , 假 如 你 想 使 用 荷 兰 语 , 你 能 这 样 指 定 :% ./configure --enable-default-err-language=Dutch你 也 能 在 squid.conf 里 指 定 error_directory 指 令 , 在 附 录 A 中 有 描 述 。 假 如 你 忽 略 该 选 项 ,英 语 是 默 认 错 误 语 言 。--with-coss-membuf-size=N循 环 目 录 存 储 系 统 (coss) 是 squid 的 试 验 性 存 储 机 制 。 该 选 项 设 置 coss 缓 存 目 录 的 内 存 缓冲 大 小 。 注 意 为 了 使 用 coss, 你 必 须 在 --enable-storeio 选 项 里 指 定 存 储 类 型 。该 参 数 以 字 节 形 式 赋 值 , 默 认 是 1048576 字 节 或 1M。 你 能 指 定 2M 缓 冲 如 下 :% ./configure --with-coss-membuf-size=2097152--enable-pollunix 提 供 两 个 相 似 的 函 数 用 以 在 I/O 事 件 里 扫 描 开 放 文 件 描 述 符 : select() 和poll()。./configure 脚 本 通 常 能 非 常 好 的 计 算 出 何 时 使 用 poll() 来 代 替 select(). 假 如 你 想 强 制使 用 poll(), 那 么 指 定 该 选 项 。--desable-poll类 似 的 , 如 果 不 使 用 poll(), 那 么 指 定 该 选 项 。--disable-http-violationssquid 默 认 可 以 被 配 置 成 违 背 HTTP 协 议 规 范 。 你 能 使 用 该 选 项 来 删 除 违 背 HTTP 协 议 的 代 码 。--enable-ipf-transparent在 第 9 章 中 , 我 将 描 述 如 何 配 置 squid 来 拦 截 缓 存 。 一 些 操 作 系 统 使 用 IP Filter 包 来 协 助 拦 截缓 存 。 在 这 些 环 境 下 你 应 该 使 用 该 ./configure 选 项 。 如 果 你 使 用 了 该 选 项 , 但 是 编 译 器 提 示src/client_side.c 文 件 出 错 , 那 是 因 为 IP Filter 包 没 有 或 没 有 正 确 的 安 装 在 你 的 系 统 中 。--enable-pf-transparent你 可 能 需 要 指 定 该 选 项 , 使 用 PF 包 过 滤 器 在 操 作 系 统 中 拦 截 HTTP。PF 是 OpenBSD 的 标 准包 过 滤 器 , 也 可 能 被 发 布 到 其 他 系 统 中 。 假 如 你 使 用 该 选 项 , 但 是 编 译 器 提 示 src/client_side.c文 件 出 错 , 那 是 因 为 PF 没 有 实 际 安 装 到 你 的 系 统 中 。


--enable-linux-netfilterNetfilter 是 linux 2.4 系 列 内 核 的 包 过 滤 器 名 字 。 假 如 你 想 在 linux2.4 或 以 后 的 版 本 中 使 用HTTP 拦 截 功 能 , 那 么 激 活 该 选 项 。--disable-ident-lookupsident 是 一 个 简 单 的 协 议 , 允 许 服 务 器 利 用 客 户 端 的 特 殊 TCP 连 接 来 发 现 用 户 名 。 假 如 你 使 用该 选 项 , 编 译 器 将 把 执 行 这 些 查 询 的 代 码 排 除 出 去 。 即 使 你 在 编 译 时 保 留 了 这 些 代 码 , 除 非 你 在squid.conf 文 件 里 指 定 ,squid 不 会 执 行 ident 查 询 。--disable-internal-dnssquid 源 代 码 包 含 两 个 不 同 的 DNS 解 决 方 案 , 叫 做 “ 内 部 的 ” 和 “ 外 部 的 ”。 内 部 查 询 是 默 认 的 ,但 某 些 人 可 能 要 使 用 外 部 技 术 。 该 选 项 禁 止 内 部 功 能 , 转 向 使 用 旧 的 方 式 。内 部 查 询 使 用 squid 自 己 的 DNS 协 议 执 行 工 具 。 也 就 是 说 ,squid 产 生 未 完 成 的 DNS 查 询 并且 将 它 们 发 送 到 一 个 解 析 器 。 假 如 超 时 , 它 重 新 发 送 请 求 , 你 能 指 定 任 意 数 量 的 解 析 器 。 该 工 具的 有 利 处 之 一 是 ,squid 获 得 准 确 无 误 的 DNS 响 应 的 TTLs。外 部 查 询 利 用 C 库 的 gethostbyname() 和 gethostbyaddr() 函 数 。squid 使 用 一 个 外 部 进 程池 来 制 造 并 行 查 询 。 使 用 外 部 DNS 解 析 的 主 要 弊 端 是 你 需 要 更 多 的 辅 助 进 程 , 增 加 squid 的负 载 。 另 一 个 麻 烦 是 C 库 函 数 不 在 响 应 里 传 输 TTLs, 这 样 squid 使 用 postive_dns_ttl 指 令提 供 的 一 个 常 量 值 。--enable-truncatetruncate() 系 统 调 用 是 unlink() 的 替 代 品 。unlink() 完 全 删 除 cache 文 件 ,truncate() 将 文 件大 小 设 为 零 。 这 样 做 释 放 了 分 配 给 该 文 件 的 磁 盘 空 间 , 但 留 下 适 当 的 目 录 接 口 。 该 选 项 存 在 的 理由 是 , 某 些 人 相 信 ( 或 希 望 )truncate() 比 unlink() 性 能 表 现 更 好 。 然 而 , 压 力 测 试 显 示 两 者有 很 少 的 或 根 本 没 有 区 别 。--disable-hostname-checks默 认 的 ,squid 要 求 URL 主 机 名 在 一 定 程 度 上 遵 守 古 老 的 RFC 1034 规 范 :标 签 必 须 遵 循 下 列 ARPANET 主 机 名 规 则 。 它 们 必 须 以 字 母 开 始 , 以 字 母 或 数 字 结 尾 , 仅 仅 包含 字 母 , 数 字 和 下 划 线 。这 里 字 母 意 味 着 ASCII 字 符 , 从 A 到 Z。 既 然 国 际 域 名 日 益 流 行 , 你 可 能 希 望 使 用 该 选 项 来 移除 限 制 。--enable-underscores该 选 项 控 制 squid 针 对 主 机 名 里 下 划 线 的 行 为 。 通 用 的 标 准 是 主 机 名 里 不 包 含 下 划 线 字 符 , 尽管 有 些 人 不 赞 成 这 点 。squid 默 认 会 对 URL 主 机 名 里 带 下 划 线 的 请 求 产 生 一 条 错 误 消 息 。 你 能使 用 该 选 项 , 让 squid 信 任 它 们 , 把 它 们 当 作 合 法 的 。 然 而 , 你 的 DNS 解 析 器 也 许 强 迫 使 用 非下 划 线 请 求 , 并 且 对 带 下 划 线 的 主 机 名 解 析 失 败 。--enable-auth[=LIST]该 选 项 控 制 在 squid 的 二 进 制 文 件 里 支 持 哪 种 验 证 机 制 。 你 能 选 择 下 列 机 制 的 任 意 组 合 :basic,digest,ntlm。 假 如 你 忽 略 该 选 项 ,squid 仅 仅 支 持 basic 验 证 。 假 如 你 使 用 不 带 参 数的 --enable-auth 选 项 , 编 译 进 程 将 增 加 对 所 有 验 证 机 制 的 支 持 。 你 可 以 使 用 以 逗 号 分 隔 的 验证 机 制 列 表 :


% ./configure --enable-auth=digest,ntlm我 在 第 六 章 和 第 十 二 章 里 会 谈 得 更 多 。--enable-auth-helpers=LIST这 个 旧 选 项 现 在 已 舍 弃 了 , 但 为 了 保 持 向 后 兼 容 性 仍 保 留 着 。 你 可 以 使 用 --enable-basicauth-helperes=LIST来 代 替 。--enable-basic-auth-helpers=LIST使 用 该 选 项 , 你 能 将 helpers/basic_auth 目 录 的 一 个 或 多 个 HTTP Basic 验 证 辅 助 程 序 编 译进 来 。 请 见 12.2 章 找 到 它 们 的 名 字 和 描 述 。--enable-ntlm-auth-helpers=LIST使 用 该 选 项 , 你 能 将 helpers/ntlm_auth 目 录 的 一 个 或 多 个 HTTP NTLM 验 证 辅 助 程 序 编 译进 来 。 请 见 12.4 章 找 到 它 们 的 名 字 和 描 述 。--enable-digest-auth-modules=LIST使 用 该 选 项 , 你 能 将 helpers/digest_auth 目 录 的 一 个 或 多 个 HTTP Digest 验 证 辅 助 程 序 编译 进 来 。 请 见 12.3 章 找 到 它 们 的 名 字 和 描 述 。--enable-external-acl-helpers=LIST使 用 该 选 项 , 你 能 编 译 一 个 或 多 个 扩 展 ACL 辅 助 程 序 , 这 些 在 12.5 章 中 讨 论 。 例 如 :% ./configure --enable-external-acl-helpers=ip_user,ldap_group--disable-unlinkdunlinkd 是 另 一 个 squid 的 外 部 辅 助 进 程 。 它 的 基 本 工 作 是 对 cache 文 件 执 行 unlink() 或truncate() 系 统 调 用 。 通 过 在 外 部 进 程 里 执 行 文 件 删 除 工 作 , 能 给 squid 带 来 明 显 的 性 能 提 升 。使 用 该 选 项 来 禁 止 外 部 unlink 进 程 功 能 。--enable-stacktrace某 些 系 统 支 持 在 程 序 崩 溃 时 , 自 动 产 生 数 据 追 踪 。 当 你 激 活 该 功 能 后 , 如 果 squid 崩 溃 , 数 据追 踪 信 息 被 写 到 cache.log 文 件 。 这 些 信 息 对 开 发 和 程 序 bug 调 试 有 用 。--enable-x-accelerator-vary该 高 级 功 能 可 能 在 squid 被 配 置 成 加 速 器 时 使 用 。 它 建 议 squid 在 响 应 请 求 时 , 从 后 台 原 始 服务 器 中 寻 找 X-Accelerator-Vary 头 。 请 见 15.5 章 。3.4.2 运 行 configure现 在 我 们 准 备 运 行 ./configure 脚 本 。 进 入 源 代 码 的 顶 级 目 录 敲 入 ./configure, 后 面 跟 上 前 面提 到 过 的 任 意 选 项 , 例 如 :% cd squid-2.5.STABLE4% ./configure --enable-icmp --enable-htcp./configure 的 工 作 就 是 侦 察 你 的 操 作 系 统 , 以 发 现 什 么 东 西 可 用 , 什 么 不 可 用 。 它 首 先 做 的 事


情 之 一 就 是 确 认 你 的 C 编 译 器 可 用 。 假 如 ./configure 检 测 到 你 的 C 编 译 器 有 问 题 , 脚 本 会 退出 , 返 回 如 下 错 误 :configure: error: installation or configuration problem: C compilercannot create executables.很 可 能 你 从 不 会 看 到 这 个 消 息 。 假 如 看 到 了 , 那 意 味 着 你 的 系 统 中 没 有 C 编 译 器 存 在 , 或 者 编译 器 没 有 正 确 安 装 。 请 见 config.log 文 件 找 到 解 决 问 题 的 建 议 。 假 如 你 的 系 统 中 有 多 个 C 编 译器 , 你 可 以 在 运 行 ./configure 之 前 设 置 CC 环 境 变 量 , 来 告 诉 ./configure 使 用 哪 个 :% setenv CC /usr/local/bin/gcc% ./configure ...在 ./configure 检 查 完 该 编 译 器 后 , 它 查 找 头 文 件 , 库 文 件 和 函 数 的 长 列 表 。 通 常 你 不 必 担 心 该部 分 。 在 某 些 实 际 情 况 中 ,./configure 会 终 止 以 引 起 你 的 注 意 , 某 些 事 情 可 能 有 问 题 , 例 如 没有 足 够 的 文 件 描 述 符 。 假 如 你 指 定 不 完 整 的 或 不 合 理 的 命 令 行 选 项 , 它 也 会 终 止 。 假 如 有 错 误 发生 , 请 检 查 config.log 输 出 。./configure 的 最 终 任 务 是 创 造 Makefiles 和 其 他 文 件 , 这 些 文件 基 于 squid 从 你 系 统 中 了 解 到 的 知 识 。 到 此 为 止 , 你 准 备 做 编 译 工 作 。3.5 编 译一 旦 ./configure 完 成 了 它 的 工 作 , 你 简 单 的 敲 入 make 开 始 编 译 源 代 码 :%make正 常 来 说 , 该 过 程 很 顺 利 , 你 可 以 见 到 大 量 的 滚 动 行 。你 也 许 见 到 一 些 编 译 器 警 告 。 大 多 数 情 况 下 , 可 以 安 全 的 忽 略 这 些 。 假 如 这 些 警 告 非 常 多 , 并 且一 些 看 起 来 非 常 严 重 , 请 将 它 们 报 告 给 开 发 者 , 在 第 16.5 章 中 有 描 述 。假 如 编 译 过 程 没 有 错 误 , 你 可 以 转 移 到 下 一 节 , 描 述 如 何 安 装 你 刚 才 编 译 的 程 序 。为 了 验 证 编 译 是 否 成 功 , 你 可 以 再 次 运 行 make。 你 将 看 到 如 下 输 出 :% makeMaking all in lib...Making all in scripts...Making all in src...Making all in fs...Making all in repl...'squid' is up to date.'client' is up to date.'unlinkd' is up to date.'cachemgr.cgi' is up to date.Making all in icons...Making all in errors...Making all in auth_modules...因 为 许 多 理 由 , 编 译 步 骤 也 许 会 失 败 , 包 括 :源 代 码 bugs


通 常 squid 源 代 码 是 完 整 的 调 试 过 的 。 然 而 , 你 也 许 会 遇 到 某 些 bugs 或 问 题 从 而 阻 止 你 编 译 。这 种 问 题 在 新 的 开 发 版 本 中 更 容 易 出 现 , 请 将 它 们 报 告 给 开 发 者 。编 译 器 安 装 问 题不 正 确 安 装 的 C 编 译 器 不 能 够 编 译 squid 或 其 他 软 件 包 。 通 常 编 译 器 随 着 操 作 系 统 预 安 装 , 所以 你 不 必 担 心 它 。 然 而 , 假 如 你 在 操 作 系 统 安 装 完 后 , 试 图 升 级 编 译 器 , 那 么 可 能 会 犯 错 误 。 绝对 不 要 把 已 经 安 装 好 的 编 译 器 从 一 台 机 器 拷 贝 到 另 一 台 , 除 非 你 绝 对 清 楚 你 在 做 什 么 。 我 觉 得 在每 台 机 上 独 立 的 安 装 编 译 器 总 是 最 好 的 。请 确 认 你 的 编 译 器 的 头 文 件 总 是 与 库 文 件 同 步 。 头 文 件 通 常 在 /usr/include 目 录 , 而 库 文 件 在/usr/lib 目 录 。Linux 的 流 行 RPM 系 统 允 许 它 去 升 级 其 中 之 一 , 但 并 非 另 一 个 。 假 如 库 文 件 基于 不 同 的 头 文 件 ,squid 不 能 编 译 。假 如 你 想 在 开 源 BSD 变 种 之 一 中 升 级 编 译 器 , 请 确 认 在 /usr/src 目 录 中 运 行 make world,这 好 过 从 /usr/src/lib 或 /usr/src/include 中 运 行 。如 下 是 一 些 通 用 的 编 译 器 问 题 和 错 误 消 息 :Solaris: make[1]: *** [libmiscutil.a] Error 255这 意 味 着 ./configure 不 能 发 现 ar 程 序 。 请 确 认 /usr/ccs/bin 位 于 你 的 PATH 环 境 变 量 里 。 假如 你 没 有 安 装 Sun 的 编 译 器 , 那 么 需 要 GNU 的 工 具 。(http://www.gnu.org/directory/binutils.html).Linux: storage size of 'rl' isn't known这 是 因 为 头 文 件 和 库 文 件 不 匹 配 所 致 , 象 前 面 描 述 的 一 样 。 请 确 认 同 时 升 级 两 者 。Digital Unix: Don't know how to make EXTRA_libmiscutil_a_SOURCES. Stop.Digital Unix 的 make 程 序 不 能 兼 容 automake 包 产 生 的 Makefile 文 件 。 例 如 ,lib/Makefile.in 包 含 如 下 行 :noinst_LIBRARIES = \@LIBDLMALLOC@ \libmiscutil.a \libntlmauth.a \@LIBREGEX@在 替 换 后 , 当 lib/Makefile 被 创 建 时 , 它 看 起 来 如 下 :noinst_LIBRARIES = \\libmiscutil.a \libntlmauth.a \;


象 上 面 显 示 的 一 样 , 最 后 一 行 包 括 一 个 不 可 见 的 TAB 字 符 , 它 阻 止 了 make。 通 过 安 装 和 使 用GNU make, 或 者 手 工 编 辑 lib/Makefile 如 下 , 来 解 决 这 个 问 题 :noinst_LIBRARIES = \\libmiscutil.a \libntlmauth.a假 如 你 在 编 译 squid 时 遇 到 问 题 , 请 先 检 查 FAQ。 你 也 许 该 在 <strong>Squid</strong> 的 web 站 点 上 搜 索 ( 使用 主 页 里 的 搜 索 栏 )。 最 后 , 假 如 你 仍 有 问 题 , 请 发 邮 件 到 squid-users@squid-cache.org 列表 。3.6 安 装在 编 译 完 后 , 你 需 要 把 程 序 安 装 到 指 定 的 目 录 。 可 能 需 要 超 级 用 户 权 限 来 把 它 们 放 置 到 安 装 目 录 。所 以 , 请 先 切 换 到 root:%supassword:#make install假 如 你 通 过 使 用 --enable-icmp 选 项 , 激 活 了 squid 的 ICMP 衡 量 功 能 , 那 么 必 须 安 装 pinger程 序 。pinger 程 序 必 须 以 超 级 用 户 权 限 安 装 , 因 为 仅 仅 允 许 root 来 发 送 和 接 受 ICMP 消 息 。下 列 命 令 以 相 应 的 许 可 来 安 装 pinger 程 序 :#make install-pinger在 安 装 完 后 , 你 将 在 squid 的 安 装 目 录 里 ( 默 认 是 /usr/local/squid) 见 到 下 列 目 录 和 文 件 :sbinsbin 目 录 的 程 序 正 常 只 能 被 root 启 动sbin/squid<strong>Squid</strong> 的 主 程 序binbin 目 录 包 含 对 所 有 用 户 可 用 的 程 序bin/RunCacheRunCache 是 一 个 shell 脚 本 , 你 能 用 它 来 启 动 squid。 假 如 squid 死 掉 , 该 脚 本 自 动 重 启 它 ,除 非 它 检 测 到 经 常 的 重 启 。RunCache 是 一 个 时 间 遗 留 的 产 物 , 那 时 <strong>Squid</strong> 还 不 是 后 台 服 务 进程 。 在 最 近 的 版 本 里 ,RunCache 很 少 用 到 , 因 为 <strong>Squid</strong> 自 动 重 启 它 自 身 , 当 你 不 使 用 -N 选项 时 。bin/RunAccel


RunAccel 与 RunCache 几 乎 一 致 , 唯 一 的 不 同 是 它 增 加 了 一 个 命 令 行 参 数 , 告 诉 squid 在 哪里 侦 听 HTTP 请 求 。bin/squidclientsquidclient 是 个 简 单 的 HTTP 客 户 端 程 序 , 你 能 用 它 来 测 试 squid。 它 也 有 一 些 特 殊 功 能 ,用 以 对 运 行 的 squid 进 程 发 起 管 理 请 求 。libexeclibexec 目 录 传 统 的 包 含 了 辅 助 程 序 。 有 一 些 命 令 你 不 能 正 常 的 启 动 。 然 而 , 这 些 程 序 通 常 被 其他 程 序 启 动 。libexec/unlinkdunlinkd 是 一 个 辅 助 程 序 , 它 从 cache 目 录 里 删 除 文 件 。 如 你 后 面 看 到 的 一 样 , 文 件 删 除 是 个性 能 瓶 颈 。 通 过 在 外 部 进 程 里 执 行 删 除 操 作 ,<strong>Squid</strong> 提 升 了 一 些 执 行 性 能 。libexec/cachemgr.cgicachemgr.cgi 是 <strong>Squid</strong> 管 理 功 能 的 CGI 接 口 。 为 了 使 用 它 , 你 需 要 拷 贝 该 程 序 到 你 的 WEB服 务 器 的 cgi-bin 目 录 。 在 14.2 章 中 有 更 多 描 述 。libexec/diskd(optional)假 如 你 指 定 了 --enable-storeio=diskd, 你 才 能 看 到 它 。libexec/pinger(optional)假 如 你 指 定 了 --enable-icmp, 你 才 能 看 到 它 。etcetc 目 录 包 含 squid 的 配 置 文 件 。etc/squid.conf这 是 squid 的 主 要 配 置 文 件 。 初 始 的 该 文 件 包 含 了 大 量 的 注 释 , 用 以 解 释 每 一 个 选 项 做 什 么 。在 你 理 解 了 这 些 配 置 指 令 后 , 建 议 你 删 除 这 些 注 释 , 让 配 置 文 件 更 小 和 更 容 易 阅 读 。 注 意 假 如 该文 件 存 在 , 安 装 过 程 不 会 覆 盖 该 文 件 。etc/squid.conf.default这 是 从 源 代 码 目 录 中 拷 贝 过 来 的 默 认 配 置 文 件 。 在 升 级 了 squid 安 装 后 , 你 也 许 发 现 有 一 份 当前 默 认 配 置 文 件 的 拷 贝 是 有 用 的 。 可 能 会 增 加 新 的 配 置 指 令 , 一 些 存 在 的 旧 指 令 可 能 有 所 改 变 。etc/mime.confmime.conf 文 件 告 诉 squid 对 从 FTP 和 Gopher 服 务 器 获 取 的 数 据 使 用 何 种 MIME 类 型 。 该文 件 是 一 个 关 联 文 件 名 扩 展 到 MIME 类 型 的 表 。 正 常 而 言 , 你 不 必 编 辑 该 文 件 。 然 而 , 你 可 能需 要 增 加 特 殊 文 件 类 型 的 接 口 , 它 们 在 你 的 组 织 内 使 用 。etc/mime.conf.default这 是 从 源 代 码 目 录 里 拷 贝 过 来 的 默 认 mime.conf 文 件 。


shareshare 目 录 通 常 包 括 squid 的 只 读 数 据 文 件 。share/mib.txt这 是 squid 的 SNMP 管 理 信 息 基 础 (MIB) 文 件 。squid 自 身 不 使 用 该 文 件 , 然 而 , 你 的 SNMP客 户 端 软 件 ( 例 如 snmpget 和 多 路 由 走 向 图 (MRTG)) 需 要 该 文 件 , 用 以 理 解 来 自 squid 的SNMP 对 象 可 用 。share/iconsshare/icons 目 录 包 含 大 量 的 小 图 标 文 件 ,squid 用 在 FTP 和 Gopher 目 录 列 举 里 。 正 常 而 言 ,你 不 必 担 心 这 些 文 件 , 但 如 果 需 要 , 你 可 以 改 变 它 们 。share/errorsshare/errors 目 录 包 含 了 squid 显 示 给 用 户 看 的 错 误 消 息 模 板 。 这 些 文 件 在 你 安 装 squid 时 ,从 源 代 码 目 录 拷 贝 而 来 。 如 果 需 要 你 可 以 编 辑 它 们 。 然 而 , 在 每 次 运 行 make install 时 , 安 装过 程 总 会 覆 盖 它 们 。 所 以 假 如 你 想 定 制 错 误 消 息 , 建 议 你 把 它 们 放 在 不 同 的 目 录 。varvar 目 录 包 含 了 不 是 很 重 要 的 和 经 常 变 化 的 文 件 。 这 些 文 件 你 不 必 正 常 的 备 份 它 们 。var/logsvar/logs 目 录 是 squid 不 同 日 志 文 件 的 默 认 位 置 。 当 你 第 一 次 安 装 squid 时 , 它 是 空 的 。 一旦 squid 开 始 运 行 , 你 能 在 这 里 看 到 名 字 为 access.log,cache.log 和 store.log 这 样 的 文 件 。var/cache假 如 你 不 在 squid.conf 文 件 里 指 定 , 这 是 默 认 的 缓 存 目 录 (cache_dir)。 第 七 章 有 关 于 缓 存 目录 的 所 有 细 节 。3.7 打 补 丁在 你 运 行 squid 一 段 时 间 后 , 你 可 能 发 现 需 要 打 源 代 码 补 丁 , 用 以 修 正 bug 或 者 增 加 试 验 性 的功 能 。 在 squid-cache.org 站 点 上 , 对 重 要 的 bug 修 正 会 发 布 补 丁 。 假 如 你 不 想 等 到 下 一 个 官方 发 布 版 本 , 你 能 下 载 补 丁 , 并 且 打 到 你 的 源 代 码 中 。 然 后 你 需 要 重 新 编 译 squid。为 了 打 补 丁 - 或 者 有 时 候 叫 差 别 文 件 - 你 需 要 一 个 叫 做 "patch" 的 程 序 。 你 的 操 作 系 统 必 须 有 该 程序 。 如 果 没 有 , 你 可 以 从 GNU 工 具 集 里 下 载 (http://www.gnu.org/directory/patch.html).注 意 假 如 你 在 使 用 匿 名 CVS( 见 2.4 节 ), 你 不 必 担 心 补 丁 文 件 。 当 你 升 级 源 代 码 树 时 ,CVS系 统 自 动 升 级 了 补 丁 。为 了 打 补 丁 , 你 必 须 把 补 丁 文 件 存 放 在 系 统 中 某 处 。 然 后 进 入 到 squid 的 源 代 码 目 录 , 运 行 如下 命 令 :


% cd squid-2.5.STABLE4% patch < /tmp/patch_file默 认 的 , 在 patch 程 序 运 行 时 , 它 告 诉 你 它 正 在 做 什 么 。 通 常 输 出 滚 动 非 常 快 , 除 非 有 问 题 。你 能 安 全 的 忽 略 它 输 出 的 offset NNN lines 警 告 。 假 如 你 不 想 见 到 所 有 这 些 输 出 , 使 用 -s 选 项选 择 安 静 模 式 。当 补 丁 更 新 了 源 代 码 后 , 它 创 造 了 原 始 文 件 的 拷 贝 。 例 如 , 假 如 你 对 src/http.c 打 一 个 补 丁 ,备 份 文 件 名 就 是 src/http.c.orig。 这 样 , 假 如 你 在 打 了 补 丁 后 想 撤 销 这 个 操 作 , 简 单 的 重 命 名所 有 的 .orig 文 件 到 它 们 以 前 的 格 式 。 为 了 成 功 的 使 用 该 技 术 , 建 议 你 在 打 补 丁 之 前 删 除 所 有的 .orig 文 件 。假 如 patch 程 序 遇 到 问 题 , 它 停 止 运 行 并 且 给 出 建 议 。 通 常 问 题 如 下 :在 错 误 的 目 录 运 行 patch 程 序 —— 解 决 的 方 法 是 , 进 入 到 正 确 的 目 录 , 或 者 使 用 patch 的 -p 选项 。补 丁 已 打 过 ——patch 会 告 诉 你 是 否 已 打 过 补 丁 文 件 。 在 这 样 的 情 况 下 , 它 会 问 你 是 否 撤 销 这 个文 件 的 补 丁 。patch 程 序 不 能 理 解 你 赋 给 它 的 文 件 —— 补 丁 文 件 通 常 有 三 个 风 格 : 正 常 的 ,context 的 和unified 的 。 旧 版 本 的 patch 程 序 可 能 不 理 解 后 两 者 的 差 异 输 出 。 从 GNU 的 FTP 站 点 获 取 最近 的 版 本 能 解 决 该 问 题 。损 坏 的 补 丁 文 件 —— 假 如 你 在 下 载 和 存 储 补 丁 文 件 时 不 小 心 , 它 有 可 能 被 损 坏 。 有 时 候 人 们 以email 消 息 发 送 补 丁 文 件 , 在 新 的 窗 口 里 , 它 们 被 简 单 的 剪 切 和 粘 贴 。在 这 样 的 系 统 中 , 剪 切 和 粘 贴 能 将 Tab 字 符 改 变 为 空 格 , 或 者 不 正 确 的 捆 绑 长 行 。 这 些 改 变 混乱 了 patch。-l 选 项 也 许 有 用 , 但 最 好 是 正 确 的 拷 贝 和 存 储 补 丁 文 件 。某 些 时 候 patch 不 能 应 用 部 分 或 所 有 的 差 别 文 件 —— 在 这 样 的 情 况 下 , 你 能 见 到 类 似 于 Hunk 3of 4 failed 的 消 息 。 失 败 的 部 分 被 存 储 在 命 名 为 .rej 的 文 件 里 。 例 如 , 假 如 在 处 理 src/http.c时 失 败 ,patch 程 序 将 该 差 别 文 件 片 断 存 为 src/http.c.rej。 在 这 样 的 情 况 下 , 你 也 许 能 手 工修 正 这 些 问 题 , 但 它 通 常 不 值 得 这 么 做 。 假 如 你 有 大 量 的 "failed hunks" 或 者 .rej 文 件 , 建 议 你去 下 载 最 近 源 代 码 版 本 的 完 整 新 拷 贝 。在 你 打 完 补 丁 后 , 你 必 须 重 新 编 译 squid。make 的 先 进 功 能 之 一 就 是 它 仅 仅 编 译 改 变 了 的 文 件 。但 有 时 候 make 不 能 理 解 错 综 复 杂 的 依 赖 关 系 , 它 没 有 完 整 的 重 编 译 所 需 文 件 。 为 了 安 全 起 见 ,通 常 建 议 你 去 重 编 译 所 有 文 件 。 最 好 的 方 法 是 在 开 始 编 译 之 前 清 除 源 代 码 树 :%make clean%make3.8 重 运 行 configure


有 时 候 你 可 能 发 现 有 必 要 重 新 运 行 ./configure。 例 如 , 假 如 你 调 整 了 内 核 参 数 , 你 必 须 再 次 运行 ./configure 以 使 它 能 发 现 新 设 置 。 当 你 阅 读 本 书 时 , 你 也 发 现 你 必 须 使 用 ./configure 选 项来 激 活 所 需 的 功 能 。以 相 同 的 选 项 重 运 行 ./configure, 使 用 如 下 命 令 :%config.status --recheck另 一 个 技 术 是 `touch config.status` 文 件 , 它 更 新 了 该 文 件 的 时 间 戳 。 这 导 致 make 在 编 译源 代 码 之 前 , 重 新 运 行 ./configure 脚 本 :% touch config.status% make如 果 增 加 或 删 除 ./configure 选 项 , 你 必 须 重 新 敲 入 完 整 的 命 令 行 。 假 如 你 记 不 住 以 前 的 选 项 ,请 查 看 config.status 文 件 的 顶 部 。 例 如 :% head config.status#! /bin/sh# Generated automatically by configure.# Run this file to recreate the current configuration.<strong>Squid</strong> 中 文 权 威 指 南 16# This directory was configured as follows,# on host foo.life-gone-hazy.com:## ./configure --enable-storeio=ufs,diskd --enable-carp \# --enable-auth-modules=NCSA# Compiler output produced by configure, useful for debugging# configure, is in ./config.log if it exists.在 运 行 ./configure 之 后 , 你 必 须 再 次 编 译 和 安 装 squid。 安 全 起 见 , 建 议 先 运 行 make clean:%make clean%make请 回 想 一 下 ,./configure 会 缓 存 它 在 你 系 统 中 发 现 的 东 西 。 在 这 样 的 形 式 下 , 你 可 能 想 清 除 这些 缓 存 , 从 头 开 始 编 译 过 程 。 假 如 喜 欢 , 你 可 以 简 单 的 删 除 config.cache 文 件 。 然 后 , 下 一次 ./configure 运 行 时 , 它 不 会 使 用 以 前 的 数 值 。 你 也 能 恢 复 squid 源 代 码 树 到 它 的 configure之 前 的 状 态 , 使 用 如 下 命 令 :%make distclean这 将 删 除 所 有 的 目 标 文 件 和 其 他 被 ./configure 和 make 程 序 产 生 的 文 件 。第 4 章 快 速 配 置 向 导4.1 squid.conf 语 法


<strong>Squid</strong> 的 配 置 文 件 相 对 规 范 。 它 与 其 他 许 多 unix 程 序 相 似 。 每 行 以 配 置 指 令 开 始 , 后 面 跟 着数 字 值 或 关 键 字 。 在 读 取 配 置 文 件 时 ,squid 忽 略 空 行 和 注 释 掉 的 行 ( 以 # 开 始 )。 如 下 是 一 些配 置 行 示 例 :cache_log /squid/var/cache.log# define the localhost ACLacl Localhost src 127.0.0.1/32connect_timeout 2 minuteslog_fqdn on某 些 指 令 取 唯 一 值 。 在 这 些 情 形 下 , 重 复 赋 予 该 指 令 不 同 的 值 , 将 覆 盖 前 面 的 值 。 例 如 ,下 面 是 一 个 连 接 超 时 值 。 第 一 行 无 效 , 因 为 第 二 行 覆 盖 了 它 :connect_timeout 2 minutesconnect_timeout 1 hour另 外 , 某 些 指 令 取 列 表 值 。 在 这 些 情 形 下 , 每 一 个 新 增 的 值 都 有 效 。" 扩 展 方 式 " 指 令 以 这 种 方 法工 作 :extension_methods UNGETextension_methods UNPUTextension_methods UNPOST对 这 些 基 于 列 表 的 指 令 , 你 通 常 能 在 同 一 行 中 赋 予 多 个 值 :extension_methods UNGET UNPUT UNPOST许 多 指 令 有 通 用 类 型 。 例 如 , 连 接 超 时 值 是 一 个 时 间 规 范 , 在 数 字 后 面 跟 着 时 间 单 元 。 例 如 :connect_timeout 3 hoursclient_lifetime 4 daysnegative_ttl 27 minutes类 似 的 , 大 量 的 指 令 指 向 文 件 大 小 或 者 内 存 额 度 。 例 如 , 你 可 以 这 样 编 写 大 小 规 范 : 十 进 制 数 字后 面 跟 bytes,KB,MB 或 GB. 例 如 :minimum_object_size 12 bytesrequest_header_max_size 10 KBmaximum_object_size 187 MB另 一 种 值 得 提 起 的 类 型 是 触 发 器 , 它 的 值 是 on 或 者 off。 许 多 指 令 使 用 该 类 型 。 例 如 :server_persistent_connections onstrip_query_terms offprefer_direct on通 常 , 配 置 文 件 指 令 能 以 任 何 顺 序 出 现 。 然 而 , 如 果 某 个 指 令 指 向 的 值 被 其 他 指 令 所 定 义 , 那 么顺 序 就 很 重 要 。 访 问 控 制 列 表 是 个 好 的 例 子 。acl 被 用 在 http_access 规 则 之 前 必 须 被 定 义 :acl Foo src 1.2.3.4http_access deny Foo


squid.conf 文 件 里 的 许 多 东 西 是 大 小 写 敏 感 的 , 例 如 指 令 名 。 你 不 能 将 http_port 写 成HTTP_port。默 认 的 squid.conf 文 件 包 含 了 对 每 个 指 令 的 大 量 注 释 , 以 及 指 令 的 默 认 值 。 例 如 :# TAG: persistent_request_timeout# How long to wait for the next HTTP request on a persistent# connection after the previous request completes.##Default:# persistent_request_timeout 1 minute每 次 安 装 squid 后 , 当 前 默 认 配 置 文 件 存 放 在 $prefix/etc 目 录 下 的 squid.conf.default。 既然 指 令 每 次 都 有 所 改 变 , 你 能 参 考 该 文 档 , 以 获 取 最 近 的 更 新 。该 章 剩 下 的 部 分 是 关 于 在 开 始 运 行 squid 之 前 , 你 必 须 知 道 的 少 数 指 令 。4.2 User IDs你 可 能 知 道 ,unix 进 程 和 文 件 拥 有 文 件 和 组 属 主 的 属 性 。 你 必 须 选 择 某 个 用 户 和 组 给 squid。该 用 户 和 组 的 组 合 , 必 须 对 大 部 分 squid 相 关 的 文 件 和 目 录 有 读 和 写 的 权 限 。我 高 度 推 荐 创 建 名 为 "squid" 的 用 户 和 组 。 这 避 免 了 某 人 利 用 squid 来 读 取 系 统 中 的 其 他 文 件 。假 如 不 止 一 个 人 拥 有 对 squid 的 管 理 权 限 , 你 可 以 将 他 们 加 到 squid 组 里 。unix 进 程 继 承 了 它 们 父 进 程 的 属 主 属 性 。 那 就 是 说 , 假 如 你 以 joe 用 户 来 启 动 squid,squid 也以 joe 来 运 行 。 假 如 你 不 想 以 joe 来 运 行 squid, 你 需 要 预 先 改 变 你 的 用 户 ID。 这 是 su 命 令的 典 型 功 能 。 例 如 :joe% su - squidsquid% /usr/local/squid/sbin/squid不 幸 的 是 , 运 行 squid 并 非 总 是 如 此 简 单 。 在 某 些 情 况 下 , 你 必 须 以 root 来 启 动 squid, 这依 赖 于 你 的 配 置 。 例 如 , 仅 仅 root 能 绑 定 TCP 套 接 字 到 特 权 端 口 上 , 如 80。 假 如 你 必 须 以 root来 启 动 squid, 你 必 须 设 置 cache_effective_user 指 令 。 它 告 诉 squid, 在 执 行 完 需 要 特 别权 限 的 任 务 后 , 变 成 哪 个 用 户 。 例 如 :cache_effective_user squid你 提 供 的 该 名 字 必 须 是 有 效 用 户 ( 在 /etc/passwd 文 件 里 )。 请 注 意 仅 仅 当 你 以 root 来 启 动squid 时 , 你 才 需 要 用 到 该 指 令 。 仅 仅 root 有 能 力 来 随 意 改 变 用 户 身 份 。 假 如 你 以 joe 来 启动 squid, 它 不 能 改 变 到 squid 用 户 。你 可 能 尝 试 不 设 置 cache_effective_user, 直 接 以 root 来 运 行 squid。 假 如 你 试 过 , 你 会 发现 squid 拒 绝 运 行 。 这 违 背 了 安 全 规 则 。 假 如 外 部 攻 击 者 有 能 力 危 及 或 利 用 squid, 他 能 获 取


对 系 统 的 全 部 访 问 权 。 尽 管 我 们 努 力 使 squid 安 全 和 少 bug, 但 还 是 稳 重 点 好 。假 如 你 没 有 设 置 cache_effective_user, 以 root 来 启 动 squid,squid 使 用 nobody 作 为 默认 值 。 不 管 你 选 择 什 么 用 户 ID , 请 确 认 它 有 对 下 面 目 录 的 读 访 问 权 :$prefix/etc,$prefix/libexec,$prefix/share。 该 用 户 ID 也 必 须 有 对 日 志 文 件 和 缓 存 目 录 的写 访 问权 。squid 也 有 一 个 cache_effective_group 指 令 , 但 你 也 许 不 必 设 置 它 。 默 认 的 ,squid 使 用cache_effective_user 的 默 认 组 ( 从 /etc/passwd 文 件 读 取 )。4.3 端 口 号http_port 指 令 告 诉 squid 在 哪 个 端 口 侦 听 HTTP 请 求 。 默 认 端 口 是 3128:http_port 3128假 如 你 将 squid 作 为 加 速 器 运 行 ( 见 15 章 ), 你 也 许 该 将 它 设 为 80。你 能 使 用 附 加 的 http_port 行 , 来 指 示 squid 侦 听 在 多 个 端 口 上 。 假 如 你 必 须 支 持 客 户 组 ( 它们 被 配 置 得 不 一 致 ), 这 点 就 经 常 有 用 。 例 如 , 来 自 某 个 部 门 的 浏 览 器 发 送 请 求 到 3128,然 而 另 一 个 部 门 使 用 80 端 口 。 简 单 的 将 两 个 端 口 号 列 举 出 来 :http_port 3128http_port 8080你 也 能 使 用 http_port 指 令 来 使 squid 侦 听 在 指 定 的 接 口 地 址 上 。 当 squid 作 为 防 火 墙 运 行时 , 它 有 两 个 网 络 接 口 : 一 个 内 部 的 和 一 个 外 部 的 。 你 可 能 不 想 接 受 来 自 外 部 的 http 请 求 。 为了 使 squid 仅 仅 侦 听 在 内 部 接 口 上 , 简 单 的 将 IP 地 址 放 在 端 口 号 前 面 :http_port 192.168.1.1:31284.4 日 志 文 件 路 径我 将 在 第 13 章 讨 论 所 有 squid 的 日 志 细 节 。 你 现 在 你 关 注 的 唯 一 事 情 是 ,squid 将 它 的 日 志放 在 何 处 。 默 认 的 日 志 目 录 是 squid 安 装 位 置 下 的 logs 目 录 。 例 如 , 假 如 你 在 ./configure时 没 有 使 用 --prefix= 选 项 , 那 么 默 认 的 日 志 文 件 路 径 是 /usr/local/squid/var/logs。你 必 须 确 认 日 志 文 件 所 存 放 的 磁 盘 位 置 空 间 足 够 。 在 squid 写 日 志 时 如 果 接 受 到 错 误 , 它 会 退出 和 重 启 。 该 行 为 的 主 要 理 由 应 引 起 你 的 注 意 。squid 想 确 认 你 不 会 丢 失 任 何 重 要 的 日 志 信 息 ,特 别 是 你 的 系 统 被 滥 用 或 者 被 攻 击 时 。squid 有 三 个 主 要 的 日 志 文 件 :cache.log,access.log,store.log. 第 一 个 文 件 即 cache.log,包 含 状 态 性 的 和 调 试 性 的 消 息 。 当 你 刚 开 始 运 行 squid 时 , 你 应 密 切 的 关 注 该 文 件 。 假 如 squid拒 绝 运 行 , 理 由 也 许 会 出 现 在 cache.log 文 件 的 结 尾 处 。 在 正 常 条 件 下 , 该 文 件 不 会 变 得 很 大 。


也 请 注 意 , 假 如 你 以 -s 选 项 来 运 行 squid, 重 要 的 cache.log 消 息 也 可 被 送 到 你 的 syslog 进程 。 通 过 使 用 cache_log 指 令 , 你 可 以 改 变 该 日 志 文 件 的 路 径 :cache_log /squid/logs/cache.logaccess.log 文 件 包 含 了 对 squid 发 起 的 每 个 客 户 请 求 的 单 一 行 。 每 行 平 均 约 150 个 字 节 。 也就 是 说 , 在 接 受 一 百 万 条 客 户 请 求 后 , 它 的 体 积 约 是 150M。 请 使 用 cache_access_log 指 令来 改 变 该 日 志 文 件 的 路 径 :cache_access_log /squid/logs/access.log假 如 因 为 某 些 理 由 , 你 不 想 squid 记 录 客 户 端 请 求 日 志 , 你 能 指 定 日 志 文 件 的 路 径 为 /dev/null.store.log 文 件 对 大 多 数 cache 管 理 员 来 说 并 非 很 有 用 。 它 包 含 了 进 入 和 离 开 缓 存 的 每 个 目 标的 记 录 。 平 均 记 录 大 小 典 型 的 是 175-200 字 节 。 然 而 ,squid 不 在 store.log 里 对 cache 点击 创 建 接 口 , 所 以 它 比 access.log 包 含 少 得 多 的 记 录 。 请 使 用 cache_store_log 指 令 来 改 变它 的 位 置 :cache_store_log /squid/logs/store.log通 过 指 定 路 径 为 none, 你 能 轻 易 的 完 全 禁 止 store.log 日 志 :cache_store_log none假 如 你 不 小 心 ,squid 的 日 志 文 件 增 加 没 有 限 制 。 某 些 操 作 系 统 对 单 个 文 件 强 制 执 行 2G 的 大小 限 制 , 即 使 你 有 充 足 的 磁 盘 空 间 。 超 过 该 限 制 会 导 致 写 错 误 , 这 样 squid 就 会 退 出 。 为 了 保证 日 志 文 件 大 小 合 理 , 你 应 创 建 任 务 来 有 规 律 的 重 命 名 和 打 包 日 志 。squid 有 内 建 功 能 来 使 这个 容 易 做 到 。 请 见 13.7 章 关 于 日 志 轮 循 的 解 释 。4.5 访 问 控 制在 第 6 章 里 有 更 多 的 关 于 访 问 控 制 的 描 述 。 现 在 , 我 只 讲 述 少 量 的 访 问 控 制 方 法 , 以 使 热 心 的读 者 能 快 速 开 始 使 用 squid。squid 默 认 的 配 置 文 件 拒 绝 每 一 个 客 户 请 求 。 在 任 何 人 能 使 用 代 理 之 前 , 你 必 须 在 squid.conf文 件 里 加 入 附 加 的 访 问 控 制 规 则 。 最 简 单 的 方 法 就 是 定 义 一 个 针 对 客 户 IP 地 址 的 ACL 和 一 个访 问 规 则 , 告 诉 squid 允 许 来 自 这 些 地 址 的 HTTP 请 求 。squid 有 许 多 不 同 的 ACL 类 型 。src类 型 匹 配 客 户 IP 地 址 ,squid 会 针 对 客 户 HTTP 请 求 检 查 http_access 规 则 。 这 样 , 你 需 要增 加 两 行 :acl MyNetwork src 192.168.0.0/16http_access allow MyNetwork请 将 这 些 行 放 在 正 确 的 位 置 。http_access 的 顺 序 非 常 重 要 , 但 是 acl 行 的 顺 序 你 不 必 介 意 。你 也 该 注 意 默 认 的 配 置 文 件 包 含 了 一 些 重 要 的 访 问 控 制 , 你 不 应 该 改 变 或 删 除 它 们 , 除 非 你 完 全理 解 它 们 的 意 义 。 在 你 第 一 次 编 辑 squid.conf 文 件 时 , 请 看 如 下 注 释 :# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS


在 该 注 释 之 后 , 以 及 "http_access deny all" 之 前 插 入 你 自 己 的 新 规 则 。为 了 彻 底 说 明 , 如 下 是 一 个 合 理 的 初 始 访 问 控 制 配 置 , 包 括 推 荐 的 默 认 控 制 和 早 先 的 例 子 :acl All src 0/0acl Manager proto cache_objectacl Localhost src 127.0.0.1/32acl Safe_ports port 80 21 443 563 70 210 280 488 591 777 1025-65535acl SSL_ports 443 563acl CONNECT method CONNECTacl MyNetwork src 192.168.0.0/16http_access allow Manager Localhosthttp_access deny Managerhttp_access deny !Safe_portshttp_access deny CONNECT !SSL_portshttp_access allow MyNetworkhttp_access deny All4.6 可 见 主 机 名希 望 你 不 必 担 心 visible_hostname 指 令 。 然 而 , 假 如 squid 不 能 发 现 它 所 运 行 的 机 器 的 主 机名 , 你 就 必 须 设 置 它 。 如 果 发 生 这 样 的 事 ,squid 抱 怨 和 拒 绝 运 行 :% squid -Nd1FATAL: Could not determine fully qualified hostname. Please set'visible_hostname'有 大 量 的 理 由 使 squid 需 要 知 道 主 机 名 :+ 主 机 名 出 现 在 squid 的 错 误 消 息 里 , 这 帮 助 用 户 验 证 潜 在 问 题 的 源 头 。+ 主 机 名 出 现 在 squid 转 发 的 cache 单 元 的 HTTP Via 头 里 。 当 请 求 到 达 原 始 主 机 时 ,Via头 包 含 了 在 传 输 过 程 中 涉 及 的 代 理 列 表 。squid 也 使 用 Via 头 来 检 测 转 发 环 路 。 我 将 在 第 10章 里 讨 论 转 发 环 路 。squid 对 特 定 事 务 使 用 内 部 URL, 例 如 FTP 目 录 列 表 的 图 标 。 当 squid 对 FTP 目 录 产 生 HTML页 面 时 , 它 插 入 小 图 标 用 以 指 明 该 目 录 中 的 文 件 类 型 。 图 标 URL 包 含 了 cache 的 主 机 名 , 以便 web 浏 览 器 能 直 接 从 squid 请 求 它 们 。每 个 从 squid 响 应 的 HTTP 回 复 包 含 了 X-Cache 头 。 这 并 非 官 方 HTTP 头 。 它 是 一 个 扩 展 头 ,用 以 指 明 该 响 应 是 cache 点 击 还 是 cache 丢 失 。 既 然 请 求 和 响 应 可 能 经 过 多 个 cache, 每 个 X-Cache 头 包 含 了 cache 报 告 点 击 或 丢 失 的 名 字 。 如 下 是 一 个 通 过 2 个 cache 的 响 应 示 例 :HTTP/1.0 200 OKDate: Mon, 29 Sep 2003 22:57:23 GMTContent-type: text/htmlContent-length: 733X-Cache: HIT from bo2.us.ircache.net


X-Cache: MISS from bo1.us.ircache.netsquid 在 启 动 时 试 图 自 动 获 取 主 机 名 。 首 先 它 调 用 gethostname() 函 数 , 这 通 常 能 返 回 正 确 的主 机 名 。 接 着 ,squid 调 用 gethostbyname() 函 数 尝 试 对 主 机 名 进 行 DNS 查 询 。 该 函 数 典型 的 返 回 IP 地 址 和 系 统 的 规 范 名 。 假 如 gethostbyname() 成 功 ,squid 在 错 误 消 息 里 ,Via 头里 等 地 方 使 用 这 个 规 范 名 。因 为 大 量 的 理 由 ,squid 可 能 不 能 检 测 到 它 的 规 范 主 机 名 , 包 括 :+ 主 机 名 可 能 未 设 置 。+ 主 机 名 可 能 从 DNS 区 域 或 /etc/hosts 文 件 里 丢 失 。squid 系 统 的 DNS 客 户 端 配 置 可 能 不 正 确 或 丢 失 。 在 unix 系 统 上 , 你 该 检 查/etc/resolv.conf 和 /etc/host.conf 文 件 。假 如 你 看 到 上 述 的 致 命 错 误 , 你 必 须 修 正 主 机 名 和 DNS 信 息 , 或 者 显 式 的 给 squid 指 明 主 机名 。 在 大 多 数 情 况 下 , 请 确 认 "hostname" 命 令 返 回 一 个 完 全 规 范 的 主 机 名 , 并 且 在 /etc/hosts文 件 里 增 加 这 个 接 口 。 假 如 这 样 不 成 功 , 请 在 squid.conf 里 设 置 可 见 主 机 名 :visible_hostname squid.packet-pushers.net4.7 管 理 联 系 信 息你 应 该 设 置 cache_mgr 指 令 作 为 对 用 户 的 帮 助 。 它 是 一 个 email 地 址 , 假 如 问 题 发 生 , 用 户能 写 信 给 它 。cache_mgr 地 址 默 认 出 现 在 squid 的 错 误 消 息 里 。 例 如 :cache_mgr squid@web-cache.net4.8 下 一 步在 创 建 了 初 步 的 配 置 文 件 后 , 你 多 少 准 备 首 次 运 行 squid 了 。 请 遵 循 下 面 章 节 的 建 议 。当 你 掌 握 了 启 动 和 停 止 squid 后 , 你 该 花 费 一 些 时 间 来 改 善 配 置 文 件 。 你 可 能 想 增 加 更 高 级 的访 问 控 制 , 这 在 第 6 章 里 有 描 述 。 既 然 我 在 这 里 没 有 讨 论 磁 盘 cache, 你 该 花 些 时 间 阅 读 第 7 和第 8 章 。第 5 章 运 行 <strong>Squid</strong>5.1 squid 命 令 行 选 项在 开 始 其 他 事 情 之 前 , 让 我 们 先 看 一 下 squid 的 命 令 行 选 项 。 这 里 的 许 多 选 项 你 从 不 会 使 用 ,另 外 有 些 仅 仅 在 调 试 问 题 时 有 用 。-a port


指 定 新 的 http_port 值 。 该 选 项 覆 盖 了 来 自 squid.conf 的 值 。 然 而 请 注 意 , 你 能 在 squid.conf里 指 定 多 个 值 。-a 选 项 仅 仅 覆 盖 配 置 文 件 里 的 第 一 个 值 。( 该 选 项 使 用 字 母 a 是 因 为 在 Harvestcache 里 ,HTTP 端 口 被 叫 做 ASCII 端 口 )-d level让 squid 将 它 的 调 试 信 息 写 到 标 准 错 误 ( 假 如 配 置 了 , 就 是 cache.log 和 syslog)。level参 数 指 定 了 显 示 在 标 准 错 误 里 的 消 息 的 最 大 等 级 。 在 多 数 情 况 下 ,d1 工 作 良 好 。 请 见 16.2 章关 于 调 试 等 级 的 描 述 。-f file指 定 另 一 个 配 置 文 件 。-h显 示 用 法 。-k function指 示 squid 执 行 不 同 的 管 理 功 能 。 功 能 参 数 是 下 列 之 一 :reconfigure,rotate,shutdown,interrupt,kill,debug,check,or parse。+ reconfigure 导 致 运 行 中 的 squid 重 新 读 取 配 置 文 件 。+ rotate 导 致 squid 滚 动 它 的 日 志 , 这 包 括 了 关 闭 日 志 , 重 命 名 , 和 再 次 打 开 它 们 。+ shutdown 发 送 关 闭 squid 进 程 的 信 号 。+ interrupt 立 刻 关 闭 squid, 不 必 等 待 活 动 会 话 完 成 。+ kill 发 送 KILL 信 号 给 squid, 这 是 关 闭 squid 的 最 后 保 证 。+ debug 将 squid 设 置 成 完 全 的 调 试 模 式 , 假 如 你 的 cache 很 忙 , 它 能 迅 速 的 用 完 你 的 磁 盘空 间 。+ check 简 单 的 检 查 运 行 中 的 squid 进 程 , 返 回 的 值 显 示 squid 是 否 在 运 行 。+ 最 后 ,parse 简 单 的 解 析 squid.conf 文 件 , 如 果 配 置 文 件 包 含 错 误 , 进 程 返 回 非 零 值 。-s激 活 将 日 志 记 录 到 syslog 进 程 。squid 使 用 LOCAL4 syslog 设 备 。0 级 别 调 试 信 息 以 优 先级 LOG_WARNING 被 记 录 ,1 级 别 消 息 以 LOG_NOTICE 被 记 录 。 更 高 级 的 调 试 信 息 不 会被 发 送 到 syslogd. 你 可 以 在 /etc/syslogd.conf 文 件 里 使 用 如 下 接 口 :local4.warning /var/log/squid.log-u port指 定 另 一 个 ICP 端 口 号 , 覆 盖 掉 squid.conf 文 件 里 的 icp_port。-v打 印 版 本 信 息 。-z初 始 化 cache, 或 者 交 换 , 目 录 。 在 首 次 运 行 squid, 或 者 增 加 新 的 cache 目 录 时 , 你 必 须 使用 该 选 项 。


-C阻 止 安 装 某 些 信 号 句 柄 , 它 们 捕 获 特 定 的 致 命 信 号 例 如 SIGBUS 和 SIGSEGV。 正 常 的 , 这 些信 号 被 squid 捕 获 , 以 便 它 能 干 净 的 关 闭 。 然 而 , 捕 获 这 些 信 号 可 能 让 以 后 调 试 问 题 困 难 。 使用 该 选 项 , 致 命 的 信 号 导 致 它 们 的 默 认 动 作 , 通 常 是 coredump。-D禁 止 初 始 化 DNS 测 试 。 正 常 情 况 下 ,squid 直 到 验 证 它 的 DNS 可 用 才 能 启 动 。 该 选 项 阻 止了 这 样 的 检 测 。 你 也 能 在 squid.conf 文 件 里 改 变 或 删 除 dns_testnames 选 项 。-F让 squid 拒 绝 所 有 的 请 求 , 直 到 它 重 新 建 立 起 存 储 元 数 据 。 假 如 你 的 系 统 很 忙 , 该 选 项 可 以 减短 重 建 存 储 元 数 据 的 时 间 。 然 而 , 如 果 你 的 cache 很 大 , 重 建 过 程 可 能 会 花 费 很 长 的 时 间 。-N阻 止 squid 变 成 后 台 服 务 进 程 。-R阻 止 squid 在 绑 定 HTTP 端 口 之 前 使 用 SO_REUSEADDR 选 项 。-V激 活 虚 拟 主 机 加 速 模 式 。 类 似 于 squid.conf 文 件 里 的 httpd_accel_host virtual 指 令 。-X强 迫 完 整 调 试 模 式 , 如 你 在 squid.conf 文 件 里 指 定 debug_options ALL,9 一 样 。-Y在 重 建 存 储 元 数 据 时 , 返 回 ICP_MISS_NOFETCH 代 替 ICP_MISS. 忙 碌 的 父 cache 在 重 建时 , 该 选 项 可 以 导 致 最 少 的 负 载 。 请 见 10.6.1.2 章 。5.2 对 配 置 文 件 查 错在 开 启 squid 之 前 , 你 应 该 谨 慎 的 验 证 配 置 文 件 。 这 点 容 易 做 到 , 运 行 如 下 命 令 即 可 :%squid -k parse假 如 你 看 不 到 输 出 , 配 置 文 件 有 效 , 你 能 继 续 后 面 的 步 骤 。然 而 , 如 果 配 置 文 件 包 含 错 误 ,squid 会 告 诉 你 :squid.conf line 62: http_access allow okay2aclParseAccessLine: ACL name 'okay2' not found.这 里 你 可 以 看 到 ,62 行 的 http_access 指 令 指 向 的 ACL 不 存 在 。 有 时 候 错 误 信 息 很 少 :FATAL: Bungled squid.conf line 76: memory_pools


在 这 个 情 形 里 , 我 们 忘 记 了 在 76 行 的 memory_pools 指 令 后 放 置 on 或 off。建 议 你 养 成 习 惯 : 在 每 次 修 改 配 置 文 件 后 , 使 用 squid -k parse。 假 如 你 不 愿 麻 烦 , 并 且 你 的配 置 文 件 有 错 误 ,squid 会 告 诉 你 关 于 它 们 而 且 拒 绝 启 动 。 假 如 你 管 理 着 大 量 的 cache, 也 许你 会 编 辑 脚 本 来 自 动 启 动 , 停 止 和 重 配 置 squid。 你 能 在 脚 本 里 使 用 该 功 能 , 来 确 认 配 置 文 件 是有 效 的 。5.3 初 始 化 cache 目 录在 初 次 运 行 squid 之 前 , 或 者 无 论 何 时 你 增 加 了 新 的 cache_dir, 你 必 须 初 始 化 cache 目 录 。命 令 很 简 单 :%squid –z对 UFS 相 关 的 存 储 机 制 (ufs,aufs,and diskd; 见 第 8 章 ), 该 命 令 在 每 个 cache_dir 下 面创 建 了 所 需 的 子 目 录 。 你 不 必 担 心 squid 会 破 坏 你 的 当 前 cache 目 录 ( 如 果 有 的 话 )。在 该 阶 段 属 主 和 许 可 权 是 通 常 遇 到 的 问 题 。squid 在 特 定 的 用 户 ID 下 运 行 , 这 在 squid.conf文 件 里 的 cache_effective_user 里 指 定 。 用 户 ID 必 须 对 每 个 cache_dir 目 录 有 读 和 写 权 限 。否 则 , 你 将 看 到 如 下 信 息 :Creating Swap DirectoriesFATAL: Failed to make swap directory /usr/local/squid/var/cache/00:(13) Permission denied在 这 样 的 情 形 下 , 你 该 确 认 /usr/local/squid/var/cache 目 录 的 所 有 组 成 都 可 被 squid.conf给 定 的 用 户 ID 访 问 。 最 终 的 组 件 --cache 目 录 -- 必 须 对 该 用 户 ID 可 写 。cache 目 录 初 始 化 可 能 花 费 一 些 时 间 , 依 赖 于 cache 目 录 的 大 小 和 数 量 , 以 及 磁 盘 驱 动 器 的 速度 。 假 如 你 想 观 察 这 个 过 程 , 请 使 用 -X 选 项 :%squid –zX5.4 在 终 端 窗 口 里 测 试 squid一 旦 你 已 经 初 始 化 cache 目 录 , 就 可 以 在 终 端 窗 口 里 运 行 squid, 将 日 志 记 录 到 标 准 错 误 。 这样 , 你 能 轻 易 的 定 位 任 何 错 误 或 问 题 , 并 且 确 认 squid 是 否 成 功 启 动 。 使 用 -N 选 项 来 保 持 squid在 前 台 运 行 ,-d1 选 项 在 标 准 错 误 里 显 示 1 级 别 的 调 试 信 息 。%squid -N -d1你 将 看 到 类 似 于 以 下 的 输 出 :2003/09/29 12:57:52| Starting <strong>Squid</strong> Cacheversion 2.5.STABLE4 for i386-unknown-freebsd4.8...2003/09/29 12:57:52| Process ID 2942003/09/29 12:57:52| With 1064 file descriptors available


2003/09/29 12:57:52| DNS Socket created on FD 42003/09/29 12:57:52| Adding nameserver 206.107.176.2 from /etc/resolv.conf2003/09/29 12:57:52| Adding nameserver 205.162.184.2 from /etc/resolv.conf2003/09/29 12:57:52| Unlinkd pipe opened on FD 92003/09/29 12:57:52| Swap maxSize 102400 KB, estimated 7876 objects2003/09/29 12:57:52| Target number of buckets: 3932003/09/29 12:57:52| Using 8192 Store buckets2003/09/29 12:57:52| Max Mem size: 8192 KB2003/09/29 12:57:52| Max Swap size: 102400 KB2003/09/29 12:57:52| Rebuilding storage in /usr/local/squid/var/cache (DIRTY)2003/09/29 12:57:52| Using Least Load store dir selection2003/09/29 12:57:52| Set Current Directory to /usr/local/squid/var/cache2003/09/29 12:57:52| Loaded Icons.2003/09/29 12:57:52| Accepting HTTP connections at 0.0.0.0, port 3128, FD 11.2003/09/29 12:57:52| Accepting ICP messages at 0.0.0.0, port 3130, FD 12.2003/09/29 12:57:52| WCCP Disabled.2003/09/29 12:57:52| Ready to serve reques假 如 你 看 到 错 误 消 息 , 你 该 首 先 修 正 它 。 请 检 查 输 出 信 息 的 开 始 几 行 以 发 现 警 告 信 息 。 最 普 通 的错 误 是 文 件 / 目 录 许 可 问 题 , 和 配 置 文 件 语 法 错 误 。 假 如 你 看 到 一 条 不 引 起 注 意 的 错 误 消 息 , 请见 16 章 中 关 于 squid 故 障 处 理 的 建 议 和 信 息 。 如 果 还 不 行 , 请 检 查 squid FAQ, 或 查 找 邮 件列 表 来 获 得 解 释 。一 旦 你 见 到 "Ready to serve requests" 消 息 , 就 可 用 一 些 HTTP 请 求 来 测 试 squid。 配 置 你的 浏 览 器 使 用 squid 作 为 代 理 , 然 后 打 开 某 个 web 页 面 。 假 如 squid 工 作 正 常 , 页 面 被 迅 速载 入 , 就 象 没 使 用 squid 一 样 。 另 外 , 你 可 以 使 用 squidclient 程 序 , 它 随 squid 发 布 :% squidclient http://www.squid-cache.org/假 如 它 正 常 工 作 ,squid 的 主 页 html 文 件 会 在 你 的 终 端 窗 口 里 滚 动 。 一 旦 确 认 squid 工 作 正常 , 你 能 中 断 squid 进 程 ( 例 如 使 用 ctrl-c) 并 且 在 后 台 运 行 squid。5.5 将 squid 作 为 服 务 进 程 运 行正 常 情 况 下 你 想 将 squid 以 后 台 进 程 运 行 ( 不 出 现 在 终 端 窗 口 里 )。 最 容 易 的 方 法 是 简 单 执 行如 下 命 令 :%squid –s-s 选 项 导 致 squid 将 重 要 的 状 态 和 警 告 信 息 写 到 syslogd。squid 使 用 LOCAL4 设 备 , 和LOG_WARNING 和 LOG_NOTICE 优 先 权 。syslog 进 程 实 际 可 能 会 或 不 会 记 录 squid 的 消息 , 这 依 赖 于 它 被 如 何 配 置 。 同 样 的 消 息 被 写 进 cache.log 文 件 , 所 以 假 如 你 愿 意 , 忽 略 -s 选项 也 是 安 全 的 。当 你 不 使 用 -N 选 项 来 启 动 squid,squid 自 动 在 后 台 运 行 并 且 创 建 父 / 子 进 程 对 。 子 进 程 做 所


有 的 实 际 工 作 。 父 进 程 确 认 子 进 程 总 在 运 行 。 这 样 , 假 如 子 进 程 意 外 终 止 , 父 进 程 启 动 另 外 一 个子 进 程 以 使 squid 正 常 工 作 。 通 过 观 察 syslog 消 息 , 你 能 看 到 父 / 子 进 程 交 互 作 用 。Jul 31 14:58:35 zapp squid[294]: <strong>Squid</strong> Parent: child process 296 started这 里 显 示 的 父 进 程 ID 是 294, 子 进 程 是 296。 当 你 查 看 ps 的 输 出 , 你 可 以 看 到 子 进 程 以(squid) 形 式 出 现 :%ps ax | grep squid294 ?? Is 0:00.01 squid -sD296 ?? S 0:00.27 (squid) -sD (squid)假 如 squid 进 程 意 外 终 止 , 父 进 程 启 动 另 一 个 。 例 如 :Jul 31 15:02:53 zapp squid[294]: <strong>Squid</strong> Parent: child process 296 exited due tosignal 6Jul 31 15:02:56 zapp squid[294]: <strong>Squid</strong> Parent: child process 359 started在 某 些 情 形 下 ,squid 子 进 程 可 能 立 即 终 止 。 为 了 防 止 频 繁 的 启 动 子 进 程 , 假 如 子 进 程 连 续 5 次没 有 运 行 至 少 10 秒 钟 , 父 进 程 会 放 弃 。Jul 31 15:13:48 zapp squid[455]: <strong>Squid</strong> Parent: child process 474 exited withstatus 1Jul 31 15:13:48 zapp squid[455]: Exiting due to repeated, frequent failures如 果 发 生 这 样 的 事 , 请 检 查 syslog 和 squid 的 cache.log 以 发 现 错 误 。5.5.1 squid_start 脚 本当 squid 以 后 台 进 程 运 行 时 , 它 查 找 squid 执 行 程 序 目 录 下 的 名 为 squid_start 的 文 件 。 假如 发 现 , 该 程 序 在 父 进 程 创 建 子 进 程 之 前 被 执 行 。 你 能 使 用 该 脚 本 完 成 特 定 的 管 理 任 务 , 例 如 通知 某 人 squid 在 运 行 , 管 理 日 志 文 件 等 。 除 非 squid_start 程 序 存 在 ,squid 不 会 创 建 子 进 程 。squid_start 脚 本 在 你 使 用 绝 对 或 相 对 路 径 启 动 squid 时 才 开 始 工 作 。 换 句 话 说 ,squid 不 使用 PATH 环 境 变 量 来 定 位 squid_start. 这 样 , 你 应 该 养 成 习 惯 这 样 启 动 squid:% /usr/local/squid/sbin/squid –sD而 不 要 这 样 :%squid –sD5.6 启 动 脚 本通 常 你 希 望 squid 在 每 次 计 算 机 重 启 后 自 动 启 动 。 对 不 同 的 操 作 系 统 , 它 们 的 启 动 脚 本 如 何 工作 也 很 不 同 。 我 在 这 里 描 述 一 些 通 用 的 环 境 , 但 对 你 自 己 的 特 殊 操 作 系 统 , 也 许 该 有 特 殊 的 处 理方 法 。


5.6.1 /etc/rc.local最 容 易 的 机 制 之 一 是 /etc/rc.local 脚 本 。 这 是 个 简 单 的 shell 脚 本 , 在 每 次 系 统 启 动 时 以 root运 行 。 使 用 该 脚 本 来 启 动 squid 非 常 容 易 , 增 加 一 行 如 下 :/usr/local/squid/sbin/squid –s当 然 你 的 安 装 位 置 可 能 不 同 , 还 有 你 可 能 要 使 用 其 他 命 令 行 选 项 。 不 要 在 这 里 使 用 -N 选 项 。假 如 因 为 某 些 理 由 , 你 没 有 使 用 cache_effective_user 指 令 , 你 可 以 尝 试 使 用 su 来 让 squid以 非 root 用 户 运 行 :/usr/bin/su nobody -c '/usr/local/squid/sbin/squid -s'5.6.2 init.d 和 rc.dinit.d 和 rc.d 机 制 使 用 独 立 的 shell 脚 本 来 启 动 不 同 的 服 务 。 这 些 脚 本 通 常 在 下 列 目 录 之 中 :/sbin/init.d, /etc/init.d, /usr/local/etc/rc.d. 脚 本 通 常 获 取 单 一 命 令 行 参 数 , 是 start 或stop。 某 些 系 统 仅 仅 使 用 start 参 数 。 如 下 是 启 动 squid 的 基 本 脚 本 :#!/bin/sh# this script starts and stops <strong>Squid</strong>case "$1" instart)/usr/local/squid/sbin/squid -secho -n ' <strong>Squid</strong>';;stop)/usr/local/squid/sbin/squid -k shutdown;;esacLinux 用 户 可 能 在 启 动 squid 之 前 需 要 设 置 文 件 描 述 符 限 制 。 例 如 :echo 8192 >; /proc/sys/fs/file-maxlimit -HSn 8192为 了 使 用 该 脚 本 , 先 找 到 脚 本 存 放 的 目 录 。 给 它 一 个 有 意 义 的 名 字 , 类 似 于 其 他 的 系 统 启 动 脚 本 。可 以 是 S98squid 或 squid.sh。 通 过 重 启 计 算 机 来 测 试 该 脚 本 , 而 不 要 假 想 它 会 正 常 工 作 。5.6.3 /etc/inittab某 些 操 作 系 统 支 持 另 一 种 机 制 , 是 /etc/inittab 文 件 。 在 这 些 系 统 中 ,init 进 程 启 动 和 停 止 基于 运 行 等 级 的 服 务 。 典 型 的 inittab 接 口 类 似 如 此 :sq:2345 nce:/usr/local/squid/sbin/squid –s


使 用 该 接 口 ,init 进 程 启 动 squid 一 次 并 且 随 后 忘 记 它 。squid 确 认 它 驻 留 在 运 行 状 态 , 象 前面 描 述 的 一 样 。 或 者 , 你 能 这 样 做 :sq:2345:respawn:/usr/local/squid/sbin/squid –Ns这 里 我 们 使 用 了 respawn 选 项 , 假 如 进 程 不 存 在 init 会 重 启 squid。 假 如 使 用 respawn, 请确 认 使 用 -N 选 项 。在 编 辑 完 inittab 文 件 后 , 使 用 下 面 的 命 令 来 使 init 重 新 读 取 它 的 配 置 文 件 和 启 动 squid:# init q5.7 chroot 环 境某 些 人 喜 欢 在 chroot 环 境 运 行 squid。 这 是 unix 的 功 能 , 给 予 进 程 新 的 root 文 件 系 统 目 录 。在 squid 受 安 全 威 胁 时 , 它 提 供 额 外 等 级 的 安 全 保 护 。 假 如 攻 击 者 在 某 种 程 度 上 通 过 squid 获取 了 对 操 作 系 统 的 访 问 权 , 她 仅 仅 能 访 问 在 chroot 文 件 系 统 中 的 文 件 。 在 chroot 树 之 外 的 系统 文 件 , 她 不 可 访 问 。最 容 易 在 chroot 环 境 里 运 行 squid 的 方 法 是 , 在 squid.conf 文 件 里 指 定 新 的 root 目 录 ,如 下 :chroot /new/root/directorychroot() 系 统 调 用 需 要 超 级 用 户 权 限 , 所 以 你 必 须 以 root 来 启 动 squid。chroot 环 境 不 是 为 unix 新 手 准 备 的 。 它 有 点 麻 烦 , 因 为 你 必 须 在 新 的 root 目 录 里 重 复 放 置大 量 的 文 件 。 例 如 , 假 如 默 认 的 配 置 文 件 正 常 在 /usr/local/squid/etc/squid.conf, 并 且 你 使用 chroot 指 令 , 那 么 文 件 必 须 位 于 /new/root/directory/usr/local/squid/etc/squid.conf.你 必 须 将 位 于 $prefix/etc,$prefix/share,$prefix/libexec 下 的 所 有 文 件 拷 贝 到 chroot 目录 。 请 确 认 $prefix/var 和 cache 目 录 在 chroot 目 录 中 存 在 和 可 写 。同 样 的 , 你 的 操 作 系 统 需 要 将 大 量 的 文 件 放 在 chroot 目 录 里 , 例 如 /etc/resolv.conf 和/dev/null. 假 如 你 使 用 外 部 辅 助 程 序 , 例 如 重 定 向 器 ( 见 11 章 ) 或 者 验 证 器 ( 见 12 章 ), 你也 需 要 来 自 /usr/lib 的 某 些 共 享 库 。 你 可 以 使 用 ldd 工 具 来 查 找 给 定 的 程 序 需 要 哪 些 共 享 库 :% ldd /usr/local/squid/libexec/ncsa_auth/usr/local/squid/libexec/ncsa_auth:libcrypt.so.2 =>; /usr/lib/libcrypt.so.2 (0x28067000)libm.so.2 =>; /usr/lib/libm.so.2 (0x28080000)libc.so.4 =>; /usr/lib/libc.so.4 (0x28098000)你 可 以 使 用 chroot 命 令 来 测 试 辅 助 程 序 :# chroot /new/root/directory /usr/local/squid/libexec/ncsa_auth/usr/libexec/ld-elf.so.1: Shared object "libcrypt.so.2" not found


更 多 的 关 于 chroot 的 信 息 , 请 见 你 系 统 中 chroot() 的 manpage。5.8 停 止 squid最 安 全 的 停 止 squid 的 方 法 是 使 用 squid -k shutdown 命 令 :%squid -k shutdown该 命 令 发 送 TERM 信 号 到 运 行 中 的 squid 进 程 。 在 接 受 到 TERM 信 号 后 ,squid 关 闭 进 来 的套 接 字 以 拒 收 新 请 求 。 然 后 它 等 待 一 段 时 间 , 用 以 完 成 外 出 请 求 。 默 认 时 间 是 30 秒 , 你 可 以 在shutdown_lifetime 指 令 里 更 改 它 。假 如 因 为 某 些 理 由 ,squid.pid 文 件 丢 失 或 不 可 读 ,squid -k 命 令 会 失 败 。 在 此 情 形 下 , 你 可以 用 ps 找 到 squid 的 进 程 ID, 然 后 手 工 杀 死 squid。 例 如 :%ps ax |grep squid假 如 你 看 到 不 止 一 个 squid 进 程 , 请 杀 死 以 (squid) 显 示 的 那 个 。 例 如 :% ps ax | grep squid294 ?? Is 0:00.01 squid -sD296 ?? S 0:00.27 (squid) -sD (squid)% kill -TERM 296在 发 送 TERM 信 号 后 , 你 也 许 想 查 看 日 志 , 以 确 认 squid 已 关 闭 :% tail -f logs/cache.log2003/09/29 21:49:30| Preparing for shutdown after 9316 requests2003/09/29 21:49:30| Waiting 10 seconds for active connections to finish2003/09/29 21:49:30| FD 11 Closing HTTP connection2003/09/29 21:49:31| Shutting down...2003/09/29 21:49:31| FD 12 Closing ICP connection2003/09/29 21:49:31| Closing unlinkd pipe on FD 92003/09/29 21:49:31| storeDirWriteCleanLogs: Starting...2003/09/29 21:49:32| Finished. Wrote 253 entries.2003/09/29 21:49:32| Took 0.1 seconds (1957.6 entries/sec).2003/09/29 21:49:32| <strong>Squid</strong> Cache (Version 2.5.STABLE4): Exiting normally.假 如 你 使 用 squid -k interrupt 命 令 ,squid 立 即 关 闭 , 不 用 等 待 完 成 活 动 请 求 。 这 与 在 kill 里发 送 INT 信 号 相 同 。5.9 重 配 置 运 行 中 的 squid 进 程在 你 了 解 了 更 多 关 于 squid 的 知 识 后 , 你 会 发 现 对 squid.conf 文 件 做 了 许 多 改 动 。 为 了 让 新设 置 生 效 , 你 可 以 关 闭 和 重 启 squid, 或 者 在 squid 运 行 时 , 重 配 置 它 。重 配 置 运 行 中 的 squid 最 好 的 方 法 是 使 用 squid -k reconfigure 命 令 :


%squid -k reconfigure当 你 运 行 该 命 令 时 ,HUP 信 号 被 发 送 到 运 行 中 的 squid 进 程 。 然 后 squid 读 取 和 解 析squid.conf 文 件 。 假 如 操 作 成 功 , 你 可 以 在 cache.log 里 看 到 这 些 :2003/09/29 22:02:25| Restarting <strong>Squid</strong> Cache (version 2.5.STABLE4)...2003/09/29 22:02:25| FD 12 Closing HTTP connection2003/09/29 22:02:25| FD 13 Closing ICP connection2003/09/29 22:02:25| Cache dir '/usr/local/squid/var/cache' size remainsunchangedat 102400 KB2003/09/29 22:02:25| DNS Socket created on FD 52003/09/29 22:02:25| Adding nameserver 10.0.0.1 from /etc/resolv.conf2003/09/29 22:02:25| Accepting HTTP connections at 0.0.0.0, port 3128, FD 9.2003/09/29 22:02:25| Accepting ICP messages at 0.0.0.0, port 3130, FD 11.2003/09/29 22:02:25| WCCP Disabled.2003/09/29 22:02:25| Loaded Icons.2003/09/29 22:02:25| Ready to serve requests.在 使 用 reconfigure 选 项 时 你 须 谨 慎 , 因 为 所 做 的 改 变 可 能 会 导 致 致 命 错 误 。 例 如 , 请 注 意squid 关 闭 和 重 新 打 开 进 来 的 HTTP 和 ICP 套 接 字 ; 假 如 你 将 http_port 改 变 为 squid 不 能打 开 的 端 口 , 它 会 发 生 致 命 错 误 并 退 出 。在 squid 运 行 时 , 某 些 指 令 和 和 选 项 不 能 改 变 , 包 括 :+ 删 除 cache 目 录 (cache_dir 指 令 )+ 改 变 store_log 指 令+ 改 变 coss cache_dir 的 块 大 小 数 值 。 事 实 上 , 无 论 何 时 你 改 变 了 该 值 , 你 必 须 重 新 初 始 化coss cache_dir。+ coredump_dir 指 令 在 重 配 置 过 程 中 不 被 检 查 。 所 以 , 在 squid 已 经 启 动 了 后 , 你 不 能 让squid 改 变 它 的 当 前 目 录 。solaris 用 户 在 重 配 置 squid 过 程 中 可 能 遇 到 其 他 问 题 。solaris 的 stdio 执 行 组 件 里 的fopen() 调 用 要 求 使 用 小 于 256 的 未 用 文 件 描 述 符 。FILE 结 构 以 8 位 值 存 储 该 文 件 描 述 符 。正 常 情 况 下 这 不 构 成 问 题 , 因 为 squid 使 用 底 层 I/O( 例 如 open()) 来 打 开 cache 文 件 。 然而 , 在 重 配 置 过 程 中 的 某 些 任 务 使 用 fopen(), 这 就 有 可 能 失 败 , 因 为 前 面 的 256 个 文 件 描 述符 已 被 分 配 出 去 。5.10 滚 动 日 志 文 件除 非 你 在 squid.conf 里 禁 止 ,squid 会 写 大 量 的 日 志 文 件 。 你 必 须 周 期 性 的 滚 动 日 志 文 件 ,以 阻 止 它 们 变 得 太 大 。squid 将 大 量 的 重 要 信 息 写 入 日 志 , 假 如 写 不 进 去 了 ,squid 会 发 生 错误 并 退 出 。 为 了 合 理 控 制 磁 盘 空 间 消 耗 , 在 cron 里 使 用 如 下 命 令 :%squid -k rotate


例 如 , 如 下 任 务 接 口 在 每 天 的 早 上 4 点 滚 动 日 志 :0 4 * * * /usr/local/squid/sbin/squid -k rotate该 命 令 做 两 件 事 。 首 先 , 它 关 闭 当 前 打 开 的 日 志 文 件 。 然 后 , 通 过 在 文 件 名 后 加 数 字 扩 展 名 , 它重 命 名 cache.log,store.log, 和 access.log。 例 如 ,cache.log 变 成 cache.log.0,cache.log.0变 成 cache.log.1, 如 此 继 续 , 滚 动 到 logfile_rotate 选 项 指 定 的 值 。squid 仅 仅 保 存 每 个 日 志 文 件 的 最 后 logfile_rotate 版 本 。 更 老 的 版 本 在 重 命 名 过 程 中 被 删 除 。假 如 你 想 保 存 更 多 的 拷 贝 , 你 需 要 增 加 logfile_rotate 限 制 , 或 者 编 写 脚 本 用 于 将 日 志 文 件 移动 到 其 他 位 置 。请 见 13.7 章 关 于 滚 动 日 志 的 其 他 信 息 。第 6 章 . 访 问 控 制6.1 访 问 控 制 元 素ACL 元 素 是 <strong>Squid</strong> 的 访 问 控 制 的 基 础 。 这 里 告 诉 你 如 何 指 定 包 括 IP 地 址 , 端 口 号 , 主 机 名 ,和 URL 匹 配 等 变 量 。 每 个 ACL 元 素 有 个 名 字 , 在 编 写 访 问 控 制 规 则 时 需 要 引 用 它 们 。 基 本 的ACL 元 素 语 法 如 下 :acl name type value1 value2 ...例 如 :acl Workstations src 10.0.0.0/16在 多 数 情 况 下 , 你 能 对 一 个 ACL 元 素 列 举 多 个 值 。 你 也 可 以 有 多 个 ACL 行 使 用 同 一 个 名 字 。例 如 , 下 列 两 行 配 置 是 等 价 的 :acl http_ports port 80 8000 8080acl Http_ports port 80acl Http_ports port 8000acl Http_ports port 80806.1.1 一 些 基 本 的 ACL 类 型<strong>Squid</strong> 大 约 有 25 个 不 同 的 ACL 类 型 , 其 中 的 一 些 有 通 用 基 本 类 型 。 例 如 ,src 和 dst ACL使 用 IP 地 址 作 为 它 们 的 基 本 类 型 。 为 避 免 冗 长 , 我 首 先 描 述 基 本 类 型 , 然 后 在 接 下 来 章 节 里 描述 每 种 ACL 类 型 。6.1.1.1 IP 地 址使 用 对 象 :src,dst,myipsquid 在 ACL 里 指 定 IP 地 址 时 , 拥 有 强 有 力 的 语 法 。 你 能 以 子 网 , 地 址 范 围 , 域 名 等 形 式 编


写 地 址 。squid 支 持 标 准 IP 地 址 写 法 ( 由 ”.” 连 接 的 4 个 小 于 256 的 数 字 ) 和 无 类 域 间 路 由规 范 。 另 外 , 假 如 你 忽 略 掩 码 ,squid 会 自 动 计 算 相 应 的 掩 码 。 例 如 , 下 例 中 的 每 组 是 相 等 的 :acl Foo src 172.16.44.21/255.255.255.255acl Foo src 172.16.44.21/32acl Foo src 172.16.44.21acl Xyz src 172.16.55.32/255.255.255.248acl Xyz src 172.16.55.32/28acl Bar src 172.16.66.0/255.255.255.0acl Bar src 172.16.66.0/24acl Bar src 172.16.66.0当 你 指 定 掩 码 时 ,squid 会 检 查 你 的 工 作 。 如 果 你 的 掩 码 在 IP 地 址 的 非 零 位 之 外 ,squid 会 告警 。 例 如 , 下 列 行 导 致 告 警 :acl Foo src 127.0.0.1/8aclParseIpData: WARNING: Netmask masks away part of the specified IP in 'Foo'这 里 的 问 题 是 /8 掩 码 (255.0.0.0) 在 最 后 三 个 字 节 里 都 是 零 值 , 但 是 IP 地 址 127.0.0.1 不是 这 样 的 。squid 警 告 你 这 个 问 题 , 以 便 你 消 除 歧 义 。 正 确 的 写 法 是 :acl Foo src 127.0.0.1/32or:acl Foo src 127.0.0.0/8有 时 候 你 可 能 想 列 举 多 个 相 邻 子 网 , 在 这 样 的 情 况 下 , 通 过 指 定 地 址 范 围 很 容 易 做 到 。 例 如 :acl Bar src 172.16.10.0-172.16.19.0/24这 等 价 但 高 效 于 下 面 的 行 :acl Foo src 172.16.10.0/24acl Foo src 172.16.11.0/24acl Foo src 172.16.12.0/24acl Foo src 172.16.13.0/24acl Foo src 172.16.14.0/24acl Foo src 172.16.15.0/24acl Foo src 172.16.16.0/24acl Foo src 172.16.18.0/24acl Foo src 172.16.19.0/24注 意 使 用 IP 地 址 范 围 , 掩 码 只 能 取 一 个 。 你 不 能 为 范 围 里 的 地 址 设 置 多 个 不 同 掩 码 。你 也 能 在 IP ACL 里 指 定 主 机 名 , 例 如 :acl <strong>Squid</strong> dst www.squid-cache.orgsquid 在 启 动 时 , 将 主 机 名 转 换 成 IP 地 址 。 一 旦 启 动 ,squid 不 会 对 主 机 名 的 地 址 发 起 第 二次 DNS 查 询 。 这 样 , 假 如 在 squid 运 行 中 地 址 已 改 变 ,squid 不 会 注 意 到 。


假 如 主 机 名 被 解 析 成 多 个 IP 地 址 ,squid 将 每 一 个 增 加 到 ACL 里 。 注 意 你 也 可 以 对 主 机 名 使用 网 络 掩 码 。在 基 于 地 址 的 ACL 里 使 用 主 机 名 通 常 是 坏 做 法 。squid 在 初 始 化 其 他 组 件 之 前 , 先 解 析 配 置 文件 , 所 以 这 些 DNS 查 询 不 使 用 squid 的 非 阻 塞 IP 缓 存 接 口 。 代 替 的 , 它 们 使 用 阻 塞 机 制 的gethostbyname() 函 数 。 这 样 , 将 ACL 主 机 名 转 换 到 IP 地 址 的 过 程 会 延 缓 squid 的 启 动 。除 非 绝 对 必 要 , 请 在 src,dst, 和 myip ACL 里 避 免 使 用 主 机 名 。squid 以 一 种 叫 做 splay tree 的 数 据 结 构 在 内 存 里 存 储 IP 地 址 ACL ( 请 见http://www.link.cs.cmu.edu/splay/)。 splay tree 有 一 些 有 趣 的 自 我 调 整 的 特 性 , 其 中 之一 是 在 查 询 发 生 时 , 列 表 会 自 动 纠 正 它 自 己 的 位 置 。 当 某 个 匹 配 元 素 在 列 表 里 发 现 时 , 该 元 素 变成 新 的 树 根 。 在 该 方 法 中 , 最 近 参 考 的 条 目 会 移 动 到 树 的 顶 部 , 这 减 少 了 将 来 查 询 的 时 间 。属 于 同 一 ACL 元 素 的 所 有 的 子 网 和 范 围 不 能 重 迭 。 如 果 有 错 误 ,squid 会 警 告 你 。 例 如 , 如 下不 被 允 许 :acl Foo src 1.2.3.0/24acl Foo src 1.2.3.4/32它 导 致 squid 在 cache.log 里 打 印 警 告 :WARNING: '1.2.3.4' is a subnetwork of '1.2.3.0/255.255.255.0'WARNING: because of this '1.2.3.4' is ignored to keep splay tree searchingpredictableWARNING: You should probably remove '1.2.3.4' from the ACL named 'Foo'在 该 情 形 下 , 你 需 要 修 正 这 个 问 题 , 可 以 删 除 其 中 一 个 ACL 值 , 或 者 将 它 们 放 置 在 不 同 的 ACL列 表 中 。6.1.1.2 域 名使 用 对 象 :srcdomain,dstdomain, 和 cache_host_domain 指 令 域 名 简 单 的 就 是 DNS 名 字或 区 域 。 例 如 , 下 面 是 有 效 的 域 名 :www.squid-cache.orgsquid-cache.orgorg域 名 ACL 有 点 深 奥 , 因 为 相 对 于 匹 配 域 名 和 子 域 有 点 微 妙 的 差 别 。 当 ACL 域 名 以 "." 开 头 ,squid 将 它 作 为 通 配 符 , 它 匹 配 在 该 域 的 任 何 主 机 名 , 甚 至 域 名 自 身 。 相 反 的 , 如 果 ACL 域 名不 以 "." 开 头 ,squid 使 用 精 确 的 字 符 串 比 较 , 主 机 名 同 样 必 须 被 严 格 检 查 。表 6-1 显 示 了 squid 的 匹 配 域 和 主 机 名 的 规 则 。 第 一 列 显 示 了 取 自 URL 请 求 的 主 机 名 ( 或 者srcdomain ACL 的 客 户 主 机 名 )。 第 二 列 指 明 是 否 主 机 名 匹 配 lrrr.org。 第 三 列 显 示 是 否 主 机名 匹 配 .lrrr.org ACL。 你 能 看 到 , 唯 一 的 不 同 在 第 二 个 实 例 里 。Table 6-1. Domain name matching


_____________________________________________________________________URL hostname_____Matches ACL lrrr.org? ____Matches ACL .lrrr.org?__lrrr.org_________Yes_______________________Yes__i.am.lrrr.org____No________________________Yes__iamlrrr.org______No________________________No___________________________________________________________________** 说 明 : 为 了 表 现 表 格 形 状 ,“__” 仅 代 表 空 格 分 隔 符 , 没 有 任 何 实 际 意 义 ( 段 誉 注 释 )。域 名 匹 配 可 能 让 人 迷 惑 , 所 以 请 看 第 二 个 例 子 以 便 你 能 真 正 理 解 它 。 如 下 是 两 个 稍 微 不 同 的ACL:acl A dstdomain foo.comacl B dstdomain .foo.com用 户 对 http://www.foo.com/ 的 请 求 匹 配 ACL B, 但 不 匹 配 A。ACL A 要 求 严 格 的 字 符 串匹 配 , 然 而 ACL B 里 领 头 的 点 就 像 通 配 符 。另 外 , 用 户 对 http://foo.com/ 的 请 求 同 时 匹 配 A 和 B。 尽 管 在 URL 主 机 名 里 的 foo.com 前面 没 有 字 符 , 但 ACL B 里 领 头 的 点 仍 然 导 致 一 个 匹 配 。squid 使 用 splay tree 的 数 据 结 构 来 存 储 域 名 ACL, 就 像 它 处 理 IP 地 址 一 样 。 然 而 ,squid的 域 名 匹 配 机 制 给 splay tree 提 供 了 一 个 有 趣 的 问 题 。splay tree 技 术 要 求 唯 一 键 去 匹 配 任意 特 定 搜 索 条 目 。 例 如 , 让 我 们 假 设 搜 索 条 目 是 i.am.lrrr.org 。 该 主 机 名 同 时 匹配 .lrrr.org 和 .am.lrrr.org。 事 实 上 就 是 两 个 ACL 值 匹 配 同 一 个 主 机 名 扰 乱 了 splay 机 制 。 换句 话 说 , 在 配 置 文 件 里 放 置 如 下 语 句 是 错 误 的 :acl Foo dstdomain .lrrr.org .am.lrrr.org假 如 你 这 样 做 ,squid 会 产 生 如 下 警 告 信 息 :WARNING: '.am.lrrr.org' is a subdomain of '.lrrr.org'WARNING: because of this '.am.lrrr.org' is ignored to keep splay tree searchingpredictableWARNING: You should probably remove '.am.lrrr.org' from the ACL named 'Foo'在 该 情 况 下 你 应 遵 循 squid 的 建 议 。 删 除 其 中 一 条 相 关 的 域 名 , 以 便 squid 明 确 知 道 你 的 意 图 。注 意 你 能 在 不 同 的 ACL 里 任 意 使 用 这 样 的 域 名 :acl Foo dstdomain .lrrr.orgacl Bar dstdomain .am.lrrr.org这 是 允 许 的 , 因 为 每 个 命 名 ACL 使 用 它 自 己 的 splay tree.6.1.1.3 用 户 名


使 用 对 象 :ident,proxy_auth该 类 型 的 ACL 被 设 计 成 匹 配 用 户 名 。squid 可 能 通 过 RFC 1413 ident 协 议 或 者 通 过 HTTP验 证 头 来 获 取 用 户 名 。 用 户 名 必 须 被 严 格 匹 配 。 例 如 ,bob 不 匹 配 bobby。squid 也 有 相 关 的ACL 对 用 户 名 使 用 正 则 表 达 式 匹 配 (ident_regex 和 proxy_auth_regex)。你 可 以 使 用 单 词 "REQUIRED" 作 为 特 殊 值 去 匹 配 任 意 用 户 名 。 假 如 squid 不 能 查 明 用 户 名 ,ACL不 匹 配 。 当 使 用 基 于 用 户 名 的 访 问 控 制 时 ,squid 通 常 这 样 配 置 。6.1.1.4 正 则 表 达 式使 用 对 象 :srcdom_regex,dstdom_regex,url_regex,urlpath_regex,browser,referer_regex,ident_regex,proxy_auth_regex,req_mime_type,rep_mime_type大 量 的 ACL 使 用 正 则 表 达 式 来 匹 配 字 符 串 ( 完 整 的 正 则 表 达 式 参 考 , 请 见 O'Reilly 的Mastering Regular Expressions 一 书 )。 对 squid 来 说 , 最 常 使 用 的 正 则 表 达 式 功 能 用 以 匹配 字 符 串 的 开 头 或 结 尾 。 例 如 ,^ 字 符 是 特 殊 元 字 符 , 它 匹 配 行 或 字 符 串 的 开 头 :^http://该 正 则 表 达 式 匹 配 任 意 以 http:// 开 头 的 URL。$ 也 是 特 殊 的 元 字 符 , 因 为 它 匹 配 行 或 字符 串 的 结 尾 :.jpg$实 际 上 , 该 示 例 也 有 些 错 误 , 因 为 . 字 符 也 是 特 殊 元 字 符 。 它 是 匹 配 任 意 单 个 字 符 的 通 配 符 。 我们 实 际 想 要 的 应 该 是 :\.jpg$反 斜 杠 对 这 个 "." 进 行 转 义 。 该 正 则 表 达 式 匹 配 以 .jpg 结 尾 的 任 意 字 符 串 。 假 如 你 不 使 用 ^ 或 $字 符 , 正 则 表 达 式 的 行 为 就 象 标 准 子 串 搜 索 。 它 们 匹 配 在 字 符 串 里 任 何 位 置 出 现 的 单 词 或 词 组 。对 所 有 的 squid 正 则 表 达 式 类 , 你 可 以 使 用 大 小 写 敏 感 的 选 项 。 匹 配 是 默 认 大 小 写 敏 感 的 。 为了 大 小 写 不 敏 感 , 在 ACL 类 型 后 面 使 用 -i 选 项 。 例 如 :acl Foo url_regex -i ^http://www6.1.1.5 TCP 端 口 号使 用 对 象 :port,myport该 类 型 是 相 对 的 。 值 是 个 别 的 端 口 号 或 端 口 范 围 。 回 想 一 下 TCP 端 口 号 是 16 位 值 , 这 样 它 的值 必 须 大 于 0 和 小 于 65536。 如 下 是 一 些 示 例 :acl Foo port 123acl Bar port 1-1024


6.1.1.6 自 主 系 统 号使 用 对 象 :src_as,dst_asInternet 路 由 器 使 用 自 主 系 统 (AS) 号 来 创 建 路 由 表 。 基 本 上 , 某 个 AS 号 指 向 被 同 一 组 织 管 理的 IP 网 络 范 围 。 例 如 , 我 的 ISP 分 配 了 如 下 网 络 块 :134.116.0.0/16, 137.41.0.0/16,206.168.0.0/16, 和 其 他 更 多 。 在 Internet 路 由 表 里 , 这 些 网 络 被 公 布 为 属 于 AS 3404。 当路 由 器 转 发 包 时 , 它 们 典 型 的 选 择 经 过 最 少 AS 的 路 径 。 假 如 这 些 对 你 不 重 要 , 请 不 必 关 注 它们 。AS 基 础 的 ACL 仅 仅 被 网 络 gurus 使 用 。如 下 是 基 于 AS 的 类 型 如 何 工 作 的 : 当 squid 首 先 启 动 时 , 它 发 送 一 条 特 殊 的 查 询 到 某 个 whois服 务 器 。 查 询 语 句 基 本 是 :“ 告 诉 我 哪 个 IP 网 络 属 于 该 AS 号 ”。 这 样 的 信 息 被 RADB 收 集 和管 理 。 一 旦 <strong>Squid</strong> 接 受 到 IP 网 络 列 表 , 它 相 似 的 将 它 们 作 为 IP 基 础 的 ACL 对 待 。基 于 AS 的 类 型 仅 仅 在 ISP 将 他 们 的 RADB 信 息 保 持 与 日 更 新 时 才 工 作 良 好 。 某 些 ISP 更 新RADB 比 其 他 人 做 得 更 好 ; 而 许 多 根 本 不 更 新 它 。 请 注 意 squid 仅 仅 在 启 动 或 者 reconfigure时 才 将 AS 号 转 换 为 网 络 地 址 。 假 如 ISP 更 新 了 它 的 RADB 接 口 , 除 非 你 重 启 或 者 重 配 置squid,squid 不 会 知 道 这 个 改 变 。另 外 的 情 况 是 , 在 你 的 squid 启 动 时 ,RADB 可 能 不 可 到 达 。 假 如 <strong>Squid</strong> 不 能 联 系 上 RADB服 务 器 , 它 从 访 问 控 制 配 置 里 删 除 AS 接 口 。 默 认 的 whois 服 务 器 是 whois.ra.net, 对 许 多用 户 来 说 太 遥 远 了 而 不 可 信 赖 。6.1.2 ACL 类 型现 在 我 们 能 把 焦 点 放 在 ACL 类 型 自 身 上 。 我 在 这 里 按 照 重 要 性 的 降 序 来 列 举 它 们 。6.1.2.1 srcIP 地 址 在 访 问 控 制 元 素 里 是 最 普 遍 使 用 的 。 大 部 分 站 点 使 用 IP 地 址 来 控 制 客 户 允 许 或 不 允 许访 问 <strong>Squid</strong>。src 类 型 指 客 户 源 IP 地 址 。 也 就 是 说 , 当 src ACL 出 现 在 访 问 控 制 列 表 里 时 ,squid 将 它 与 发 布 请 求 的 客 户 IP 地 址 进 行 比 较 。正 常 情 况 下 你 允 许 来 自 内 网 中 主 机 的 请 求 , 并 阻 塞 其 他 的 。 例 如 , 假 如 你 的 单 位 使 用192.168.0.0 子 网 , 你 可 以 这 样 指 定 ACL:acl MyNetwork src 192.168.0.0假 如 你 有 许 多 子 网 , 你 能 在 同 一 个 acl 行 里 面 列 举 它 们 :acl MyNetwork src 192.168.0.0 10.0.1.0/24 10.0.5.0/24 172.16.0.0/12squid 有 许 多 其 他 ACL 类 型 用 以 检 查 客 户 地 址 。srcdomain 类 型 比 较 客 户 的 完 整 可 验 证 域 名 。它 要 求 反 向 DNS 查 询 , 这 可 能 会 延 缓 处 理 该 请 求 。srcdom_regex ACL 是 类 似 的 , 但 它 允 许


你 使 用 正 则 表 达 式 来 匹 配 域 名 。 最 后 ,src_as 类 型 比 较 客 户 的 AS 号 。6.1.2.2 dstdst 类 型 指 向 原 始 服 务 器 ( 目 标 )IP 地 址 。 在 某 些 情 况 下 , 你 能 使 用 该 类 型 来 阻 止 你 的 用 户 访问 特 定 web 站 点 。 然 而 , 在 使 用 dst ACL 时 你 须 谨 慎 。 大 部 分 squid 接 受 到 的 请 求 有 原 始 服务 器 主 机 名 。 例 如 :GET http://www.web-cache.com/ HTTP/1.0这 里 ,www.web-cache.com 是 主 机 名 。 当 访 问 列 表 规 则 包 含 了 dst 元 素 时 ,squid 必 须 找到 该 主 机 名 的 IP 地 址 。 假 如 squid 的 IP 缓 存 包 含 了 该 主 机 名 的 有 效 接 口 , 这 条 ACL 被 立 即检 测 。 否 则 , 在 DNS 查 询 忙 碌 时 ,squid 会 延 缓 处 理 该 请 求 。 这 对 某 些 请 求 来 说 会 造 成 延 时 。为 了 避 免 延 时 , 你 该 尽 可 能 的 使 用 dstdomain ACL 类 型 来 代 替 dst。如 下 是 简 单 的 dst ACL 示 例 :acl AdServers dst 1.2.3.0/24请 注 意 ,dst ACL 存 在 的 问 题 是 , 你 试 图 允 许 或 拒 绝 访 问 的 原 始 服 务 器 可 能 会 改 变 它 的 IP 地址 。 假 如 你 不 关 心 这 样 的 改 变 , 那 就 不 必 麻 烦 去 升 级 squid.conf。 你 可 以 在 acl 行 里 放 上 主 机名 , 但 那 样 会 延 缓 启 动 速 度 。 假 如 你 的 ACL 需 要 许 多 主 机 名 , 你 也 许 该 预 处 理 配 置 文 件 , 将 主机 名 转 换 成 IP 地 址 。6.1.2.3 myipmyip 类 型 指 <strong>Squid</strong> 的 IP 地 址 , 它 被 客 户 连 接 。 当 你 在 squid 机 上 运 行 netstat -n 时 , 你见 到 它 们 位 于 本 地 地 址 列 。 大 部 分 squid 安 装 不 使 用 该 类 型 。 通 常 所 有 的 客 户 连 接 到 同 一 个 IP地 址 , 所 以 该 ACL 元 素 仅 仅 当 系 统 有 多 个 IP 地 址 时 才 有 用 。为 了 理 解 myip 为 何 有 用 , 考 虑 某 个 有 两 个 子 网 的 公 司 网 络 。 在 子 网 1 的 用 户 是 程 序 员 和 工 程师 。 子 网 2 包 括 会 计 , 市 场 和 其 他 管 理 部 门 。 这 样 情 况 下 的 squid 有 三 个 网 络 接 口 : 一 个 连 接子 网 1, 一 个 连 接 子 网 2, 第 三 个 连 接 到 外 部 因 特 网 。当 正 确 的 配 置 时 , 所 有 在 子 网 1 的 用 户 连 接 到 squid 位 于 该 子 网 的 IP 地 址 , 类 似 的 , 子 网 2 的用 户 连 接 到 squid 的 第 二 个 IP 地 址 。 这 样 你 就 可 以 给 予 子 网 1 的 技 术 部 员 工 完 全 的 访 问 权 ,然 而 限 制 管 理 部 门 的 员 工 仅 仅 能 访 问 工 作 相 关 的 站 点 。ACL 可 能 如 下 :acl Eng myip 172.16.1.5acl Admin myip 172.16.2.5然 而 请 注 意 , 使 用 该 机 制 你 必 须 特 别 小 心 , 阻 止 来 自 某 个 子 网 的 用 户 连 接 squid 位 于 另 一 子 网


的 IP 地 址 。 否 则 , 在 会 计 和 市 场 子 网 的 聪 明 的 用 户 , 能 够 通 过 技 术 部 子 网 进 行 连 接 , 从 而 绕 过你 的 限 制 。6.1.2.4 dstdomain在 某 些 情 况 下 , 你 发 现 基 于 名 字 的 访 问 控 制 非 常 有 用 。 你 可 以 使 用 它 们 去 阻 塞 对 某 些 站 点 的 访 问 ,去 控 制 squid 如 何 转 发 请 求 , 以 及 让 某 些 响 应 不 可 缓 存 。dstdomain 之 所 以 非 常 有 用 , 是 因为 它 检 查 请 求 url 里 的 主 机 名 。然 而 首 先 我 想 申 明 如 下 两 行 的 不 同 :acl A dst www.squid-cache.orgacl B dstdomain www.squid-cache.orgA 实 际 上 是 IP 地 址 ACL。 当 <strong>Squid</strong> 解 析 配 置 文 件 时 , 它 查 询 www.squid-cache.org 的 IP地 址 , 并 将 它 们 存 在 内 存 里 。 它 不 保 存 名 字 。 假 如 在 squid 运 行 时 IP 地 址 改 变 了 ,squid 会继 续 使 用 旧 的 地 址 。然 而 dstdomain ACL 以 域 名 形 式 存 储 , 并 非 IP 地 址 。 当 squid 检 查 ACL B 时 , 它 对 URL的 主 机 名 部 分 使 用 字 符 串 比 较 功 能 。 在 该 情 形 下 , 它 并 不 真 正 关 心 是 否 www.squid-cache.org的 IP 地 址 改 变 了 。使 用 dstdomain ACL 的 主 要 问 题 是 某 些 URL 使 用 IP 地 址 代 替 主 机 名 。 假 如 你 的 目 标 是 使 用dstdomain ACL 来 阻 塞 对 某 些 站 点 的 访 问 , 聪 明 的 用 户 能 手 工 查 询 站 点 的 IP 地 址 , 然 后 将 它们 放 在 URL 里 。 例 如 , 下 面 的 2 行 URL 带 来 同 样 的 页 面 :http://www.squid-cache.org/docs/FAQ/http://206.168.0.9/docs/FAQ/第 一 行 能 被 dstdomain ACL 轻 易 匹 配 , 但 第 二 行 不 能 。 这 样 , 假 如 你 依 靠 dstdomain ACL,你 也 该 同 样 阻 塞 所 有 使 用 IP 地 址 代 替 主 机 名 的 请 求 。 请 见 6.3.8 章 节 。6.1.2.5 srcdomainsrcdomain ACL 也 有 点 麻 烦 。 它 要 求 对 每 个 客 户 IP 地 址 进 行 所 谓 的 反 向 DNS 查 询 。 技 术 上 ,squid 请 求 对 该 地 址 的 DNS PTR 记 录 。DNS 的 响 应 -- 完 整 可 验 证 域 名 (FQDN)-- 是 squid 匹配 ACL 值 的 东 西 。( 请 参 考 O'Reilly's DNS and BIND 找 到 更 多 关 于 DNS PTR 记 录 的 信 息 )使 用 dst ACL,FQDN 查 询 会 导 致 延 时 。 请 求 会 被 延 缓 处 理 直 到 FQDN 响 应 返 回 。FQDN 响 应被 缓 存 下 来 , 所 以 srcdomain 查 询 通 常 仅 在 客 户 首 次 请 求 时 延 时 。不 幸 的 是 ,srcdomain 查 询 有 时 不 能 工 作 。 许 多 组 织 并 没 有 保 持 他 们 的 反 向 查 询 数 据 库 与 日 更新 。 假 如 某 地 址 没 有 PTR 记 录 ,ACL 检 查 失 败 。 在 该 情 形 下 , 请 求 可 能 会 延 时 非 常 长 时 间 ( 例如 2 分 钟 ) 直 到 DNS 查 询 超 时 。 假 如 你 使 用 srcdomain ACL, 请 确 认 你 自 己 的 DNS inaddr.arpa区 域 配 置 正 确 并 且 在 工 作 中 。 假 如 这 样 , 你 可 以 使 用 如 下 的 ACL:


acl LocalHosts srcdomain .users.example.com6.1.2.6 port你 很 可 能 想 使 用 port ACL 来 限 制 对 某 些 原 始 服 务 器 端 口 号 的 访 问 。 就 像 我 即 将 讲 到 的 ,squid其 实 不 连 接 到 某 些 服 务 , 例 如 email 和 IRC 服 务 。port ACL 允 许 你 定 义 单 独 的 端 口 或 端 口 范围 。 例 如 :acl HTTPports port 80 8000-8010 8080HTTP 在 设 计 上 与 其 他 协 议 类 似 , 例 如 SMTP。 这 意 味 着 聪 明 的 用 户 通 过 转 发 email 消 息 到SMTP 服 务 器 能 欺 骗 squid。Email 转 发 是 垃 圾 邮 件 的 主 要 原 因 之 一 , 我 们 必 须 处 理 它 们 。 历史 上 , 垃 圾 邮 件 有 真 正 的 邮 件 服 务 器 。 然 而 近 来 , 越 来 越 多 的 垃 圾 邮 件 制 造 者 使 用 开 放 HTTP 代理 来 隐 藏 他 们 的 踪 迹 。 你 肯 定 不 想 <strong>Squid</strong> 被 当 成 垃 圾 邮 件 转 发 器 。 假 如 是 这 样 , 你 的 IP 地 址很 可 能 被 许 多 邮 件 转 发 黑 名 单 冻 结 (MAPS,ORDB,spamhaus 等 )。 除 email 之 外 , 还 有 其 他许 多 TCP/IP 服 务 是 squid 不 与 其 通 信 的 。 这 些 包 括 IRC,Telnet,POP, 和 NNTP。 你 的 针 对 端口 的 策 略 必 须 被 配 置 成 拒 绝 已 知 危 险 端 口 , 并 允 许 剩 下 的 ; 或 者 允 许 已 知 安 全 端 口 , 并 拒 绝 剩 下的 。我 的 态 度 比 较 保 守 , 仅 仅 允 许 安 全 的 端 口 。 默 认 的 squid.conf 包 含 了 下 面 的 安 全 端 口 ACL:acl Safe_ports port 80 # httpacl Safe_ports port 21 # ftpacl Safe_ports port 443 563 # https, snewsacl Safe_ports port 70 # gopheracl Safe_ports port 210 # waisacl Safe_ports port 1025-65535 # unregistered portsacl Safe_ports port 280 # http-mgmtacl Safe_ports port 488 # gss-httpacl Safe_ports port 591 # filemakeracl Safe_ports port 777 # multiling httphttp_access deny !Safe_ports这 是 个 较 明 智 的 配 置 。 它 允 许 用 户 连 接 到 任 何 非 特 权 端 口 (1025-65535), 但 仅 仅 指 定 的 特权 端 口 可 以 被 连 接 。 假 如 你 的 用 户 试 图 访 问 某 个 URL 如 下 :http://www.lrrr.org:123/,squid会 返 回 访 问 拒 绝 错 误 消 息 。 在 某 些 情 形 下 , 为 了 让 你 的 用 户 满 意 , 你 可 能 需 要 增 加 另 外 的 端 口 号 。宽 松 的 做 法 是 , 拒 绝 对 特 别 危 险 的 端 口 的 访 问 。<strong>Squid</strong> FAQ 包 括 了 如 下 示 例 :acl Dangerous_ports 7 9 19 22 23 25 53 109 110 119http_access deny Dangerous_ports使 用 Dangerous_ports 的 弊 端 是 squid 对 几 乎 每 个 请 求 都 要 搜 索 整 个 列 表 。 这 对 CPU 造 成了 额 外 的 负 担 。 大 多 数 情 况 下 ,99% 到 达 squid 的 请 求 是 对 80 端 口 的 , 它 不 出 现 在 危 险 端 口列 表 里 。 所 有 请 求 对 该 表 的 搜 索 不 会 导 致 匹 配 。 当 然 , 整 数 比 较 是 快 速 的 操 作 , 不 会 显 然 影 响 性能 。


( 译 者 注 : 这 里 的 意 思 是 , 两 者 都 要 对 列 表 进 行 搜 索 和 匹 配 。 在 第 一 种 情 况 下 , 它 搜 索 安 全 端 口列 表 并 匹 配 80, 显 然 第 一 个 元 素 就 匹 配 成 功 了 。 而 第 二 种 情 况 中 , 会 搜 索 危 险 端 口 列 表 并 试 图匹 配 80, 当 然 危 险 端 口 不 会 包 括 80, 所 以 每 次 对 80 的 请 求 都 要 搜 索 完 整 个 列 表 , 这 样 就 会影 响 性 能 。)6.1.2.7 myportsquid 也 有 myport ACL。port ACL 指 向 原 始 服 务 器 的 端 口 号 ,myport 指 向 squid 自 己 的端 口 号 , 用 以 接 受 客 户 请 求 。 假 如 你 在 http_port 指 令 里 指 定 不 止 一 个 端 口 号 , 那 么 squid 就可 以 在 不 同 的 端 口 上 侦 听 。假 如 你 将 squid 作 为 站 点 HTTP 加 速 器 和 用 户 代 理 服 务 器 , 那 么 myport ACL 特 别 有 用 。 你可 以 在 80 上 接 受 加 速 请 求 , 在 3128 上 接 受 代 理 请 求 。 你 可 能 想 让 所 有 人 访 问 加 速 器 , 但 仅仅 你 自 己 的 用 户 能 以 代 理 形 式 访 问 squid。 你 的 ACL 可 能 如 下 :acl AccelPort myport 80acl ProxyPort myport 3128acl MyNet src 172.16.0.0/22http_access allow AccelPort # anyonehttp_access allow ProxyPort MyNet # only my usershttp_access deny ProxyPort # deny others6.1.2.8 methodmethod ACL 指 HTTP 请 求 方 法 。GET 是 典 型 的 最 常 用 方 法 , 接 下 来 是 POST,PUT, 和 其 他 。下 例 说 明 如 何 使 用 method ACL:acl Uploads method PUT POST<strong>Squid</strong> 知 道 下 列 标 准 HTTP 方 法 :GET, POST, PUT, HEAD, CONNECT, TRACE,OPTIONS和 DELETE。 另 外 ,squid 了 解 下 列 来 自 WEBDAV 规 范 ,RFC 2518 的 方 法 :PROPFIND,PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK。 某 些 Microsoft 产 品 使 用 非 标 准 的WEBDAV 方 法 , 所 以 squid 也 了 解 它 们 :BMOVE, BDELETE, BPROPFIND。 最 后 , 你 可 以在 extension_methods 指 令 里 配 置 squid 去 理 解 其 他 的 请 求 方 法 。 请 见 附 录 A。注 意 CONNECT 方 法 非 常 特 殊 。 它 是 用 于 通 过 HTTP 代 理 来 封 装 某 种 请 求 的 方 法 ( 请 见 RFC2817:Upgrading to TLS Within HTTP/1.1)。 在 处 理 CONNECT 方 法 和 远 程 服 务 器 的 端 口号 时 应 特 别 谨 慎 。 就 像 前 面 章 节 讲 过 的 一 样 , 你 不 希 望 squid 连 接 到 某 些 远 程 服 务 。 你 该 限 制CONNECT 方 法 仅 仅 能 连 接 到 HTTPS/SSL 或 NNTPS 端 口 ( 443 和 563 )。 默 认 的squid.conf 这 样 做 :acl CONNECT method CONNECTacl SSL_ports 443 563http_access allow CONNECT SSL_ports


http_access deny CONNECT在 该 配 置 里 ,squid 仅 仅 允 许 加 密 请 求 到 端 口 4 4 3(HTTPS/SSL) 和 5 6 3(NNTPS)。CONNECT方 法 对 其 他 端 口 的 请 求 都 被 拒 绝 。PURGE 是 另 一 个 特 殊 的 请 求 方 法 。 它 是 <strong>Squid</strong> 的 专 有 方 法 , 没 有 在 任 何 RFC 里 定 义 。 它 让管 理 员 能 强 制 删 除 缓 存 对 象 。 既 然 该 方 法 有 些 危 险 ,squid 默 认 拒 绝 PURGE 请 求 , 除 非 你 定义 了 ACL 引 用 了 该 方 法 。 否 则 , 任 何 能 访 问 cache 者 也 许 能 够 删 除 任 意 缓 存 对 象 。 我 推 荐 仅仅 允 许 来 自 localhost 的 PURGE:acl Purge method PURGEacl Localhost src 127.0.0.1http_access allow Purge Localhosthttp_access deny Purge关 于 从 squid 的 缓 存 里 删 除 对 象 , 请 见 7.6 章 。6.1.2.9 proto该 类 型 指 URI 访 问 ( 或 传 输 ) 协 议 。 如 下 是 有 效 值 : http, https (same as HTTP/TLS),ftp,gopher, urn, whois, 和 cache_object。 也 就 是 说 , 这 些 是 被 squid 支 持 的 URL 机 制 名字 。 例 如 , 假 如 你 想 拒 绝 所 有 的 FTP 请 求 , 你 可 以 使 用 下 列 指 令 :acl FTP proto FTPhttp_access deny FTPcache_object 机 制 是 squid 的 特 性 。 它 用 于 访 问 squid 的 缓 存 管 理 接 口 , 我 将 在 14.2 章 讨论 它 。 不 幸 的 是 , 它 并 非 好 名 字 , 可 能 会 被 改 变 。默 认 的 squid.conf 文 件 有 许 多 行 限 制 缓 存 管 理 访 问 :acl Manager proto cache_objectacl Localhost src 127.0.0.1http_access allow Manager Localhosthttp_access deny Manager这 些 配 置 行 仅 允 许 来 自 本 机 地 址 的 缓 存 管 理 请 求 , 所 有 其 他 的 缓 存 管 理 请 求 被 拒 绝 。 这 意 味 着 在squid 机 器 上 有 帐 号 的 人 , 能 访 问 到 潜 在 的 敏 感 缓 存 管 理 信 息 。 你 也 许 想 修 改 缓 存 管 理 访 问 控制 , 或 对 某 些 页 面 使 用 密 码 保 护 。 我 将 在 14.2.2 章 里 谈 论 到 。6.1.2.10 timetime ACL 允 许 你 控 制 基 于 时 间 的 访 问 , 时 间 为 每 天 中 的 具 体 时 间 , 和 每 周 中 的 每 天 。 日 期 以 单字 母 来 表 示 , 见 如 下 表 。 时 间 以 24 小 时 制 来 表 示 。 开 始 时 间 必 须 小 于 结 束 时 间 , 这 样 在 编 写 跨越 0 点 的 time ACL 时 可 能 有 点 麻 烦 。


Code____Day-----------------S_______SundayM_______MondayT_______TuesdayW_______WednesdayH_______ThursdayF_______FridayA_______SaturdayD_______All weekdays (M-F)-----------------日 期 和 时 间 由 localtime() 函 数 来 产 生 。 请 确 认 你 的 计 算 机 位 于 正 确 的 时 区 , 你 也 该 让 你 的 时 钟与 标 准 时 间 同 步 。为 了 编 写 time ACL 来 匹 配 你 的 工 作 时 间 , 你 可 以 这 样 写 :acl Working_hours MTWHF 08:00-17:00or:acl Working_hours D 08:00-17:00让 我 们 看 一 个 麻 烦 的 例 子 。 也 许 你 是 某 个 ISP, 在 下 午 8 点 到 早 上 4 点 这 段 不 忙 的 时 间 内 放 松访 问 。 既 然 该 时 间 跨 越 子 夜 , 你 不 能 编 写 “20:00-04:00”。 代 替 的 , 你 需 要 把 它 们 分 成 两 个 ACL来 写 , 或 者 使 用 否 定 机 制 来 定 义 非 忙 时 。 例 如 :acl Offpeak1 20:00-23:59acl Offpeak2 00:00-04:00http_access allow Offpeak1 ...http_access allow Offpeak2 ...另 外 , 你 可 以 这 样 写 :acl Peak 04:00-20:00http_access allow !Peak ...尽 管 squid 允 许 , 你 也 不 应 该 在 同 一 个 time ACL 里 放 置 多 个 日 期 和 时 间 范 围 列 表 。 对 这 些 ACL的 解 析 不 一 定 是 你 想 象 的 那 样 。 例 如 , 假 如 你 输 入 :acl Blah time M 08:00-10:00 W 09:00-11:00实 际 能 做 到 的 是 :acl Blah time MW 09:00-11:00解 析 仅 仅 使 用 最 后 一 个 时 间 范 围 。 正 确 的 写 法 是 , 将 它 们 写 进 两 行 :acl Blah time M 08:00-10:00acl Blah time W 09:00-11:00


6.1.2.11 identident ACL 匹 配 被 ident 协 议 返 回 的 用 户 名 。 这 是 个 简 单 的 协 议 , 文 档 是 RFC 1413。 它 工 作过 程 如 下 :1. 用 户 代 理 ( 客 户 端 ) 对 squid 建 立 TCP 连 接 。2.squid 连 接 到 客 户 系 统 的 ident 端 口 (113)。3.squid 发 送 一 个 包 括 两 个 TCP 端 口 号 的 行 。squid 端 的 端 口 号 可 能 是 3128( 或 者 你 在squid.conf 里 配 置 的 端 口 号 ), 客 户 端 的 端 口 号 是 随 机 的 。4. 客 户 端 的 ident 服 务 器 返 回 打 开 第 一 个 连 接 的 进 程 的 用 户 名 。5.squid 记 录 下 用 户 名 用 于 访 问 控 制 目 的 , 并 且 记 录 到 access.log。当 squid 遇 到 对 特 殊 请 求 的 ident ACL 时 , 该 请 求 被 延 时 , 直 到 ident 查 询 完 成 。 这 样 ,identACL 可 以 对 你 的 用 户 请 求 造 成 延 时 。我 们 推 荐 仅 仅 在 本 地 局 域 网 中 , 并 且 大 部 分 客 户 工 作 站 运 行 ident 服 务 时 , 才 使 用 ident ACL。假 如 squid 和 客 户 工 作 站 连 在 一 个 局 域 网 里 ,ident ACL 工 作 良 好 。 跨 广 域 网 使 用 ident 难 以成 功 。ident 协 议 并 非 很 安 全 。 恶 意 的 用 户 能 替 换 他 们 的 正 常 ident 服 务 为 假 冒 服 务 , 并 返 回 任 意 的他 们 选 择 的 用 户 名 。 例 如 , 假 如 我 知 道 从 administrator 用 户 的 连 接 总 是 被 允 许 , 那 么 我 可 以写 个 简 单 的 程 序 , 在 回 答 每 个 ident 请 求 时 都 返 回 这 个 用 户 名 。你 可 以 使 用 ident ACL 拦 截 cache( 请 见 第 9 章 )。 当 squid 被 配 置 成 拦 截 cache 时 , 操 作系 统 假 设 它 自 己 是 原 始 服 务 器 。 这 意 味 着 用 于 拦 截 TCP 连 接 的 本 地 socket 地 址 有 原 始 服 务 器的 IP 地 址 。 假 如 你 在 squid 上 运 行 netstat -n 时 , 你 可 以 看 到 大 量 的 外 部 IP 地 址 出 现 在 本地 地 址 栏 里 。 当 squid 发 起 一 个 ident 查 询 时 , 它 创 建 一 个 新 的 TCP 套 接 字 , 并 绑 定 本 地 终点 到 同 一 个 IP 地 址 上 , 作 为 客 户 TCP 连 接 的 本 地 终 点 。 既 然 本 地 地 址 并 非 真 正 是 本 地 的 ( 它可 能 与 原 始 服 务 器 IP 地 址 相 距 遥 远 ),bind() 系 统 调 用 失 败 。squid 将 这 个 作 为 失 败 的 ident查 询 来 处 理 。注 意 squid 也 有 个 特 性 , 对 客 户 端 执 行 懒 惰 ident 查 询 。 在 该 情 形 下 , 在 等 待 ident 查 询 时 ,请 求 不 会 延 时 。 在 HTTP 请 求 完 成 时 ,squid 记 录 ident 信 息 , 假 如 它 可 用 。 你 能 使 用ident_lookup_access 指 令 来 激 活 该 特 性 , 我 将 在 本 章 后 面 讨 论 。6.1.2.12 proxy_authsquid 有 一 套 有 力 的 , 在 某 种 程 度 上 有 点 混 乱 的 特 性 , 用 以 支 持 HTTP 代 理 验 证 功 能 。 使 用 代理 验 证 , 客 户 的 包 括 头 部 的 http 请 求 包 含 了 验 证 信 用 选 项 。 通 常 , 这 简 单 的 是 用 户 名 和 密 码 。


squid 解 密 信 用 选 项 , 并 调 用 外 部 验 证 程 序 以 发 现 该 信 用 选 项 是 否 有 效 。squid 当 前 支 持 三 种 技 术 以 接 受 用 户 验 证 :HTTP 基 本 协 议 , 数 字 认 证 协 议 , 和 NTLM。 基 本认 证 已 经 发 展 了 相 当 长 时 间 。 按 今 天 的 标 准 , 它 是 非 常 不 安 全 的 技 术 。 用 户 名 和 密 码 以 明 文 同 时发 送 。 数 字 认 证 更 安 全 , 但 也 更 复 杂 。 基 本 和 数 字 认 证 在 RFC 2617 文 档 里 被 描 述 。NTLM 也比 基 本 认 证 更 安 全 。 然 而 , 它 是 Microsoft 发 展 的 专 有 协 议 。 少 数 squid 开 发 者 已 经 基 本 完 成了 对 它 的 反 向 工 程 。为 了 使 用 代 理 验 证 , 你 必 须 配 置 squid 使 用 大 量 的 外 部 辅 助 程 序 。squid 源 代 码 里 包 含 了 一 些程 序 , 用 于 对 许 多 标 准 数 据 库 包 括 LDAP,NTLM,NCSA 类 型 的 密 码 文 件 , 和 标 准 Unix 密 码 数据 库 进 行 认 证 。auth_param 指 令 控 制 对 所 有 辅 助 程 序 的 配 置 。 我 将 在 12 章 里 讨 论 这 些 细 节 。auth_param 指 令 和 proxy_auth ACL 是 少 数 在 配 置 文 件 里 顺 序 重 要 的 实 例 。 你 必 须 在proxy_auth ACL 之 前 定 义 至 少 一 个 验 证 辅 助 程 序 ( 使 用 auth_param)。 假 如 你 没 有 这 样 做 ,squid 打 印 出 错 误 消 息 , 并 且 忽 略 proxy_auth ACL。 这 并 非 致 命 错 误 , 所 以 squid 可 以 启 动 ,但 所 有 你 的 用 户 的 请 求 可 能 被 拒 绝 。proxy_auth ACL 取 用 户 名 作 为 值 。 然 而 , 大 部 分 安 装 里 简 单 的 使 用 特 殊 值 REQUIRED:auth_param ...acl Auth1 proxy_auth REQUIRED在 该 情 况 中 , 任 何 具 有 有 效 信 用 选 项 的 请 求 会 匹 配 该 ACL。 假 如 你 需 要 细 化 控 制 , 你 可 以 指 定独 立 的 用 户 名 :auth_param ...acl Auth1 proxy_auth allan bob charlieacl Auth2 proxy_auth dave eric frank代 理 验 证 不 支 持 HTTP 拦 截 , 因 为 用 户 代 理 不 知 道 它 在 与 代 理 服 务 器 , 而 非 原 始 服 务 器 通 信 。用 户 代 理 不 知 道 在 请 求 里 发 送 Proxy-Authorization 头 部 。 见 9.2 章 更 多 细 节 。6.1.2.13 src_as该 类 型 检 查 客 户 源 IP 地 址 所 属 的 具 体 AS 号 ( 见 6.1.1.6 关 于 squid 如 何 将 AS 号 映 射 到 IP地 址 的 信 息 )。 作 为 示 例 , 我 们 虚 构 某 ISP 使 用 AS 64222 并 且 通 告 使 用10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 网 络 。 你 可 以 编 写 这 样 的 ACL, 它 允 许 来 自 该ISP 地 址 空 间 的 任 何 主 机 请 求 :acl TheISP src 10.0.0.0/8acl TheISP src 172.16.0.0/12acl TheISP src 192.168.0.0/16http_access allow TheISP当 然 , 你 还 可 以 这 样 写 :acl TheISP src_as 64222


http_access allow TheISP第 二 种 写 法 不 但 更 短 , 而 且 假 如 ISP 增 加 了 新 的 网 络 , 你 不 必 更 新 ACL 配 置 。6.1.2.14 dst_asdst_as ACL 经 常 与 cache_peer_access 指 令 一 起 使 用 。 在 该 方 法 中 ,squid 使 用 与 IP 路由 一 致 的 方 式 转 发 cache 丢 失 。 考 虑 某 ISP, 它 比 其 他 ISP 更 频 繁 的 更 换 路 由 。 每 个 ISP 处理 他 们 自 己 的 cache 代 理 , 这 些 代 理 能 转 发 请 求 到 其 他 代 理 。 理 论 上 ,ISP A 将 ISP B 网 络里 主 机 的 cache 丢 失 转 发 到 ISP B 的 cache 代 理 。 使 用 AS ACL 和 cache_peer_access 指令 容 易 做 到 这 点 :acl ISP-B-AS dst_as 64222acl ISP-C-AS dst_as 64333cache_peer proxy.isp-b.net parent 3128 3130cache_peer proxy.isp-c.net parent 3128 3130cache_peer_access proxy.isb-b.net allow ISP-B-AScache_peer_access proxy.isb-c.net allow ISP-C-AS我 将 在 第 10 章 里 讨 论 更 多 关 于 cache 协 作 。6.1.2.15 snmp_communitysnmp_community ACL 对 SNMP 查 询 才 有 意 义 , 后 者 被 snmp_access 指 令 控 制 。 例 如 ,你 可 以 这 样 写 :acl OurCommunityName snmp_community hIgHsEcUrItYacl All src 0/0snmp_access allow OurCommunityNamesnmp_access deny All在 该 情 况 中 , 假 如 community 名 字 设 置 为 hIgHsEcUrItY,SNMP 查 询 才 被 允 许 。6.1.2.16 maxconnmaxconn ACL 指 来 自 客 户 IP 地 址 的 大 量 同 时 连 接 。 某 些 squid 管 理 员 发 现 这 是 个 有 用 的 方法 , 用 以 阻 止 用 户 滥 用 代 理 或 者 消 耗 过 多 资 源 。maxconn ACL 在 请 求 超 过 指 定 的 数 量 时 , 会 匹 配 这 个 请 求 。 因 为 这 个 理 由 , 你 应 该 仅 仅 在 deny规 则 里 使 用 maxconn。 考 虑 如 下 例 子 :acl OverConnLimit maxconn 4http_access deny OverConnLimit


在 该 情 况 中 ,squid 允 许 来 自 每 个 IP 地 址 的 同 时 连 接 数 最 大 为 4 个 。 当 某 个 客 户 发 起 第 五 个连 接 时 ,OverConnLimit ACL 被 匹 配 ,http_access 规 则 拒 绝 该 请 求 。6.1.2.17 arparp ACL 用 于 检 测 cache 客 户 端 的 MAC 地 址 ( 以 太 网 卡 的 物 理 地 址 )。 地 址 解 析 协 议 (ARP)是 主 机 查 找 对 应 于 IP 地 址 的 MAC 地 址 的 方 法 。 某 些 大 学 学 生 发 现 , 在 MicrosoftWindows 下 , 他 们 可 以 改 变 系 统 的 IP 地 址 到 任 意 值 , 然 后 欺 骗 squid 的 基 于 地 址 的 控 制 。这 时 arp 功 能 就 派 上 用 场 了 , 聪 明 的 系 统 管 理 员 会 配 置 squid 检 查 客 户 的 以 太 网 地 址 。不 幸 的 是 , 该 特 性 使 用 非 移 植 性 代 码 。 假 如 你 运 行 Solaris 或 Linux, 你 能 使 用 arp ACL。 其他 系 统 不 行 。 当 你 运 行 ./configure 时 增 加 --enable-arp-acl 选 项 , 就 可 以 激 活 该 功 能 。arp ACL 有 另 一 个 重 要 限 制 。ARP 是 数 据 链 路 层 协 议 , 假 如 客 户 主 机 和 squid 在 同 一 子 网 ,它 才 能 工 作 。 你 不 容 易 发 现 不 同 子 网 主 机 的 MAC 地 址 。 假 如 在 squid 和 你 的 用 户 之 间 有 路 由器 存 在 , 你 可 能 不 能 使 用 arp ACL。现 在 你 知 道 何 时 去 使 用 它 们 , 让 我 们 看 看 arp ACL 实 际 上 是 怎 样 的 。 它 的 值 是 以 太 网 地 址 , 当使 用 ifconfig 和 arp 时 你 能 看 到 以 太 网 地 址 。 例 如 :acl WinBoxes arp 00:00:21:55:ed:22acl WinBoxes arp 00:00:21:ff:55:386.1.2.18 srcdom_regexsrcdom_regex ACL 允 许 你 使 用 正 则 表 达 式 匹 配 客 户 域 名 。 这 与 srcdomain ACL 相 似 , 它使 用 改 进 的 的 子 串 匹 配 。 相 同 的 限 制 是 : 某 些 客 户 地 址 不 能 反 向 解 析 到 域 名 。 作 为 示 例 , 下 面 的ACL 匹 配 以 dhcp 开 头 的 主 机 名 :acl DHCPUser srcdom_regex -i ^dhcp因 为 领 头 的 ^ 符 号 , 该 ACL 匹 配 主 机 名 dhcp12.example.com , 但 不 匹 配host12.dhcp.example.com。6.1.2.19 dstdom_regexdstdom_regex ACL 也 与 dstdomain 相 似 。 下 面 的 例 子 匹 配 以 www 开 头 的 主 机 名 :acl WebSite dstdom_regex -i ^www\.如 下 是 另 一 个 有 用 的 正 则 表 达 式 , 用 以 匹 配 在 URL 主 机 名 里 出 现 的 IP 地 址 :acl IPaddr dstdom_regex [0-9]$这 样 可 以 工 作 , 因 为 squid 要 求 URL 主 机 名 完 全 可 验 证 。 既 然 全 局 顶 级 域 名 中 没 有 以 数 字 结


eq_mime_type ACL 值 是 正 则 表 达 式 。 你 可 以 这 样 编 写 ACL 去 捕 获 音 频 文 件 类 型 :acl AuidoFileUploads req_mime_type -i ^audio/6.1.2.24 rep_mime_type该 类 型 ACL 指 原 始 服 务 器 的 HTTP 响 应 里 的 Content-Type 头 部 。 它 仅 在 使 用http_reply_access 规 则 时 才 有 用 。 所 有 的 其 他 访 问 控 制 形 式 是 基 于 客 户 端 请 求 的 。 该 ACL 基于 服 务 器 响 应 。假 如 你 想 使 用 squid 阻 塞 Java 代 码 , 你 可 以 这 样 写 :acl JavaDownload rep_mime_type application/x-javahttp_reply_access deny JavaDownload6.1.2.25 ident_regex在 本 节 早 些 时 讲 过 ident ACL。ident_regex 允 许 你 使 用 正 则 表 达 式 , 代 替 严 格 的 字 符 串 匹 配 ,这 些 匹 配 是 对 ident 协 议 返 回 的 用 户 名 进 行 。 例 如 , 如 下 ACL 匹 配 包 含 数 字 的 用 户 名 :acl NumberInName ident_regex [0-9]6.1.2.26 proxy_auth_regex该 ACL 允 许 对 代 理 认 证 用 户 名 使 用 正 则 表 达 式 。 例 如 , 如 下 ACL 匹 配admin,administrator 和 administrators:acl Admins proxy_auth_regex -i ^admin6.1.3 外 部 ACL<strong>Squid</strong> 2.5 版 本 介 绍 了 一 个 新 特 性 : 外 部 ACL。 你 可 以 指 示 squid 发 送 某 些 信 息 片 断 到 外 部 进程 , 然 后 外 部 的 辅 助 程 序 告 诉 squid, 数 据 匹 配 或 不 匹 配 。squid 附 带 着 大 量 的 外 部 ACL 辅 助 程 序 ; 大 部 分 用 于 确 定 命 名 用 户 是 不 是 某 个 特 殊 组 的 成 员 。请 见 12.5 章 关 于 这 些 程 序 的 描 述 , 以 及 关 于 如 何 编 写 你 自 己 的 程 序 的 信 息 。 现 在 , 我 解 释 如 何定 义 和 使 用 外 部 ACL 类 型 。external_acl_type 指 令 定 义 新 的 外 部 ACL 类 型 。 如 下 是 通 用 语 法 :external_acl_type type-name [options] format helper-commandtype-name 是 用 户 定 义 的 字 串 。 你 也 可 以 在 acl 行 里 引 用 它 。


<strong>Squid</strong> 当 前 支 持 如 下 选 项 (options):ttl=n时 间 数 量 , 单 位 是 秒 , 用 以 缓 存 匹 配 值 的 时 间 长 短 。 默 认 是 3600 秒 , 或 1 小 时 。negative_ttl=n时 间 数 量 , 单 位 是 秒 , 用 以 缓 存 不 匹 配 值 的 时 间 长 短 。 默 认 是 3600 秒 , 或 1 小 时 。concurrency=n衍 生 的 辅 助 程 序 的 数 量 , 默 认 是 5。cache=n缓 存 结 果 的 最 大 数 量 。 默 认 是 0, 即 不 限 制 cache 大 小 。格 式 是 以 % 字 符 开 始 的 一 个 或 多 个 关 键 字 。squid 当 前 支 持 如 下 格 式 :%LOGIN从 代 理 验 证 信 用 选 项 里 获 取 的 用 户 名 。%IDENT从 RFC 1413 ident 获 取 的 用 户 名 。%SRC客 户 端 IP 地 址 。%DST原 始 服 务 器 IP 地 址 。%PROTO传 输 协 议 ( 例 如 HTTP,FTP 等 )%PORT原 始 服 务 器 的 TCP 端 口 。%METHODHTTP 请 求 方 法 。%{Header}HTTP 请 求 头 部 的 值 ; 例 如 , %{User-Agent} 导 致 squid 发 送 这 样 的 字 串 到 验 证 器 :"Mozilla/4.0 (compatible; MSIE 6.0; Win32)"%{Hdr:member}选 择 某 些 数 量 的 基 于 列 表 的 HTTP 头 部 , 例 如 Caceh-Control; 例 如 , 给 出 如 下 HTTP 头 部 :X-Some-Header: foo=xyzzy, bar=plugh, foo=zoinks


对 %{X-Some-Header:foo} 的 取 值 ,squid 发 送 这 样 的 字 串 到 外 部 ACL 进 程 :foo=xyzzy, foo=zoinks%{Hdr:;member}与 %{Hdr:member} 相 同 , 除 了 ";" 是 列 表 分 隔 符 外 。 你 能 使 用 任 何 非 字 母 数 字 的 字 符 作 为 分隔 符 。辅 助 命 令 是 squid 为 辅 助 程 序 衍 生 的 命 令 。 你 也 可 以 在 这 里 包 含 命 令 参 数 。 例 如 , 整 条 命 令 可能 类 似 如 此 :/usr/local/squid/libexec/my-acl-prog.pl -X -5 /usr/local/squid/etc/datafile将 这 些 放 在 一 个 长 行 里 。squid 不 支 持 如 下 通 过 反 斜 杠 分 隔 长 行 的 技 术 , 所 以 请 记 住 所 有 这 些必 须 放 在 单 行 里 :external_acl_type MyAclType cache=100 %LOGIN %{User-Agent} \/usr/local/squid/libexec/my-acl-prog.pl -X -5 \/usr/local/squid/share/usernames \/usr/local/squid/share/useragents现 在 你 知 道 如 何 定 义 外 部 ACL, 下 一 步 是 编 写 引 用 它 的 acl 行 。 这 相 对 容 易 , 语 法 如 下 :acl acl-name external type-name [args ...]如 下 是 个 简 单 示 例 :acl MyAcl external MyAclTypesquid 接 受 在 type-name 后 面 的 任 意 数 量 的 参 数 。 这 些 在 每 个 请 求 里 被 发 送 到 辅 助 程 序 。请 见 12.5.3 章 , 我 描 述 了 unix_group 辅 助 程 序 , 作 为 该 功 能 的 示 例 。6.1.4 处 理 长 ACL 列 表ACL 列 表 某 些 时 候 非 常 长 。 这 样 的 列 表 在 squid.conf 文 件 里 难 以 维 护 。 你 也 可 能 想 从 其 他 资源 里 自 动 产 生 squid ACL 列 表 。 在 如 此 情 况 下 , 你 可 以 从 外 部 文 件 里 包 含 ACL 列 表 。 语 法 如下 :acl name "filename"这 里 的 双 引 号 指 示 squid 打 开 filename, 并 且 将 它 里 面 的 内 容 分 配 给 ACL。 例 如 , 如 下 的 ACL太 长 了 :acl Foo BadClients 1.2.3.4 1.2.3.5 1.2.3.6 1.2.3.7 1.2.3.9 ...你 可 以 这 样 做 :acl Foo BadClients "/usr/local/squid/etc/BadClients"将 IP 地 址 放 在 BadClients 文 件 里 :


1.2.3.41.2.3.51.2.3.61.2.3.71.2.3.9...文 件 可 以 包 含 以 # 开 头 的 注 释 。 注 意 在 该 文 件 里 的 每 个 IP 地 址 必 须 是 一 个 单 独 的 行 。acl 行 里的 任 何 地 方 , 以 空 格 来 分 隔 值 , 新 行 是 包 含 ACL 值 的 文 件 的 分 界 。6.1.5 <strong>Squid</strong> 如 何 匹 配 访 问 控 制 元 素理 解 squid 如 何 搜 索 ACL 元 素 去 匹 配 是 很 重 要 的 。 当 ACL 元 素 有 多 个 值 时 , 任 何 单 个 值 能 导致 匹 配 。 换 句 话 说 ,squid 在 检 查 ACL 元 素 值 时 使 用 OR 逻 辑 。 当 squid 找 到 第 一 个 值 匹 配 时 ,它 停 止 搜 索 。 这 意 味 着 把 最 可 能 匹 配 的 值 放 在 列 表 开 头 处 , 能 减 少 延 时 。让 我 们 看 一 个 特 殊 的 例 子 , 考 虑 如 下 ACL 定 义 :acl Simpsons ident Maggie Lisa Bart Marge Homer当 squid 在 访 问 列 表 里 遇 到 Simpsons ACL 时 , 它 执 行 ident 查 询 。 让 我 们 看 一 下 , 当 用 户ident 服 务 返 回 Marge 时 , 会 发 生 什 么 呢 ?squid 的 ACL 代 码 在 成 功 匹 配 Marge 前 , 会 先后 将 这 个 值 与 Maggie,Lisa, 和 Bart 对 比 。 当 搜 索 完 成 时 , 我 们 认 为 Simpsons ACL 匹 配 了这 个 请 求 。实 际 上 , 这 有 点 欺 骗 。ident ACL 值 并 非 存 储 在 无 序 列 表 里 。 它 们 存 储 在 splay tree 中 。 这 意味 着 , 在 非 匹 配 事 件 中 ,squid 不 会 搜 索 完 所 有 的 名 字 。 对 一 个 splay tree 搜 索 N 个 条 目 需要 记 录 N 个 比 较 。 许 多 其 他 的 ACL 类 型 也 使 用 splay tree。 然 而 , 基 于 正 则 表 达 式 的 类 型 不使 用 。既 然 正 则 表 达 式 不 能 这 样 存 储 , 它 们 以 链 表 形 式 存 储 。 这 使 得 在 大 链 表 里 它 们 特 别 低 效 , 特 别 是不 匹 配 链 表 里 任 何 正 则 表 达 式 的 请 求 。 为 了 改 进 这 个 形 式 , 当 匹 配 发 生 时 ,squid 将 正 则 表 达式 移 到 列 表 的 顶 部 。 实 际 上 , 因 为 ACL 匹 配 代 码 的 天 然 特 性 ,squid 将 匹 配 的 条 目 移 到 列 表 的第 二 个 位 置 。 这 样 , 普 通 的 匹 配 值 自 然 移 到 ACL 列 表 的 顶 部 , 这 样 会 减 少 比 较 数 量 。让 我 们 看 另 一 个 简 单 示 例 :acl Schmever port 80-90 101 103 107 1 2 3 9999该 ACL 匹 配 到 原 始 服 务 器 80-90 端 口 , 和 其 他 独 立 端 口 的 请 求 。 对 80 端 口 的 请 求 ,squid通 过 查 看 第 一 个 值 就 匹 配 了 该 ACL。 对 9999 端 口 , 其 他 每 个 值 都 先 被 检 查 。 对 某 个 不 在 列 表里 的 端 口 ,squid 要 检 查 所 有 值 才 宣 布 它 不 匹 配 。 就 像 我 已 经 讲 过 的 , 将 最 常 用 的 值 放 在 第 一位 能 优 化 ACL 匹 配 。


6.2 访 问 控 制 规 则前 面 提 过 ,ACL 元 素 是 建 立 访 问 控 制 的 第 一 步 。 第 二 步 是 访 问 控 制 规 则 , 用 来 允 许 或 拒 绝 某 些动 作 。 在 早 先 的 例 子 里 , 你 已 见 过 http_access 规 则 。squid 有 大 量 其 他 的 访 问 控 制 列 表 :http_access这 是 最 重 要 的 访 问 控 制 列 表 。 它 决 定 哪 些 客 户 HTTP 请 求 被 允 许 , 和 哪 些 被 拒 绝 。 假 如http_access 配 置 错 误 ,squid cache 容 易 遭 受 攻 击 或 被 不 当 利 用 。http_reply_accesshttp_reply_access 与 http_access 类 似 。 不 同 之 处 是 前 者 在 squid 接 受 到 来 自 原 始 服 务 器或 上 级 代 理 的 响 应 时 , 才 会 被 检 测 。 大 部 分 访 问 控 制 基 于 客 户 请 求 的 方 式 , 对 这 些 使 用http_access 就 够 了 。 然 而 , 某 些 人 喜 欢 基 于 响 应 内 容 类 型 来 允 许 或 拒 绝 请 求 。 更 多 信 息 请 见6.3.9 章 。icp_access假 如 你 的 squid 被 配 置 来 服 务 ICP 响 应 ( 见 10.6 章 ), 那 么 该 使 用 icp_access 列 表 。 大 部分 情 况 下 , 你 该 仅 仅 允 许 来 自 邻 居 cache 的 ICP 请 求 。no_cache你 能 使 用 no_cache 访 问 列 表 来 指 示 squid, 它 不 必 存 储 某 些 响 应 ( 在 磁 盘 或 内 存 里 )。 该 列 表典 型 的 与 dst,dstdomain,url_regex ACL 结 合 使 用 。对 no_cache 使 用 " 否 " 条 件 , 这 样 的 双 重 否 定 会 导 致 某 些 混 乱 。 被 no_cache 列 表 拒 绝 的 请 求不 被 缓 存 。 换 句 话 说 ,no_cache deny... 是 让 目 标 不 被 缓 存 。 见 6.3.10 章 的 示 例 。miss_accessmiss_access 列 表 主 要 用 于 squid 的 邻 居 cache。 它 决 定 squid 怎 样 处 理 cache 丢 失 的 请求 。 如 果 squid 使 用 集 群 技 术 , 那 么 该 功 能 必 需 。 见 6.3.7 的 示 例 。redirector_access该 访 问 列 表 决 定 哪 个 请 求 被 发 送 到 重 定 向 进 程 ( 见 11 章 )。 默 认 情 况 下 , 假 如 你 使 用 重 定 向 器 ,那 么 所 有 的 请 求 都 通 过 重 定 向 器 。 你 可 以 使 用 redirector_access 列 表 来 阻 止 某 些 请 求 被 重 写 。这 点 特 别 有 用 , 因 为 这 样 的 访 问 列 表 , 使 重 定 向 器 相 对 于 访 问 控 制 系 统 , 接 受 的 请 求 信 息 要 少 一些 。ident_lookup_accessident_lookup_access 列 表 与 redirector_access 类 似 。 它 允 许 你 对 某 些 请 求 执 行 懒 惰 ident查 询 。squid 默 认 不 发 布 ident 查 询 。 假 如 请 求 被 ident_lookup_access 规 则 ( 或 ident ACL)允 许 , 那 么 squid 才 会 进 行 ident 查 询 。always_direct该 访 问 列 表 影 响 squid 怎 样 处 理 与 邻 居 cache 转 发 cache 丢 失 。 通 常 squid 试 图 转 发 cache丢 失 到 父 cache, 和 / 或 squid 使 用 ICP 来 查 找 临 近 cache 响 应 。 然 而 , 当 请 求 匹 配always_direct 规 则 时 ,squid 直 接 转 发 请 求 到 原 始 服 务 器 。


使 用 该 规 则 , 对 "allow" 规 则 的 匹 配 导 致 squid 直 接 转 发 请 求 , 见 10.4.4 章 的 更 多 细 节 和 示 例 。never_directnever_direct 与 always_direct 相 反 。 匹 配 该 列 表 的 cache 丢 失 请 求 必 须 发 送 到 邻 居cache。 这 点 对 在 防 火 墙 之 后 的 代 理 特 别 有 用 。使 用 该 列 表 , 对 "allow" 规 则 的 匹 配 导 致 squid 转 发 请 求 到 邻 居 cache。 见 10.4.3 章 的 更 多细 节 和 示 例 。snmp_access该 访 问 列 表 应 用 到 发 送 给 squid 的 SNMP 端 口 的 查 询 。 你 能 配 合 该 列 表 使 用 的 ACL 是snmp_community 和 src。 假 如 你 确 实 想 使 用 它 , 那 也 能 使 用 srcdomain,srcdom_regex和 src_as。 见 14.3 章 的 示 例 。broken_posts该 访 问 列 表 影 响 squid 处 理 某 些 POST 请 求 的 方 法 。 某 些 老 的 用 户 代 理 在 请 求 主 体 的 结 尾 处 发送 一 个 特 别 的 回 车 换 行 符 。 那 就 是 说 , 消 息 主 体 比 content-length 头 部 指 示 的 长 度 要 多 2 个字 节 。 更 糟 糕 的 是 , 某 些 老 的 HTTP 服 务 器 实 际 上 依 赖 于 这 种 不 正 确 的 行 为 。 当 请 求 匹 配 该 访问 列 表 时 ,squid 模 拟 这 种 客 户 端 并 且 发 送 特 殊 的 回 车 换 行 符 。<strong>Squid</strong> 有 大 量 的 使 用 ACL 元 素 的 其 他 配 置 指 令 。 它 们 中 的 某 些 过 去 是 全 局 配 置 , 后 被 修 改 来 使用 ACL 以 提 供 更 灵 活 的 控 制 。cache_peer_access该 访 问 列 表 控 制 发 送 到 邻 居 cache 的 HTTP 请 求 和 ICP/HTCP 查 询 。 见 10.4.1 章 的 更 多 信息 和 示 例 。reply_body_max_size该 访 问 列 表 限 制 对 HTTP 响 应 主 体 的 最 大 可 接 受 size。 见 附 录 A 的 更 多 信 息 。delay_access该 访 问 规 则 列 表 控 制 是 否 延 时 池 被 应 用 到 某 个 请 求 的 cache 丢 失 响 应 。 见 附 录 C。tcp_outgoing_address该 访 问 列 表 绑 定 服 务 端 TCP 连 接 到 指 定 的 本 地 IP 地 址 。 见 附 录 A。tcp_outgoing_tos该 访 问 列 表 能 设 置 到 原 始 服 务 器 和 邻 居 cache 的 TCP 连 接 的 不 同 TOS/Diffserv 值 , 见 附 录A。header_access使 用 该 指 令 , 你 能 配 置 squid 从 它 转 发 的 请 求 里 删 除 某 些 HTTP 头 部 。 例 如 , 你 也 许 想 <strong>Squid</strong>过 滤 掉 发 送 到 某 些 原 始 服 务 器 的 请 求 里 的 Cookie 头 部 。 见 附 录 A。header_replace该 指 令 允 许 你 替 换 , 而 不 是 删 除 ,HTTP 头 部 的 内 容 。 例 如 , 你 能 设 置 user-agent 头 部 为 假


值 , 满 足 某 些 原 始 服 务 器 的 要 求 , 但 仍 保 护 你 的 隐 私 。 见 附 录 A。6.2.1 访 问 规 则 语 法访 问 控 制 规 则 的 语 法 如 下 :access_list allow|deny [!]ACLname ...例 如 :http_access allow MyClientshttp_access deny !Safe_Portshttp_access allow GameSites AfterHours当 读 取 配 置 文 件 时 ,squid 仅 仅 扫 描 一 遍 访 问 控 制 行 。 这 样 , 在 访 问 列 表 里 引 用 ACL 元 素 之 前 ,你 必 须 在 acl 行 里 定 义 它 们 。 甚 至 , 访 问 列 表 规 则 的 顺 序 也 非 常 重 要 。 你 以 怎 样 的 顺 序 编 写 访问 列 表 , 那 么 squid 就 按 怎 样 的 顺 序 来 检 查 它 们 。 将 最 常 用 的 ACL 放 在 列 表 的 开 始 位 置 , 可以 减 少 squid 的 CPU 负 载 。对 大 部 分 访 问 列 表 ,deny 和 allow 的 意 义 明 显 。 然 而 , 它 们 中 的 某 些 , 却 并 非 如 此 含 义 清 楚 。请 谨 慎 的 编 写 always_direct,never_direct, 和 no_cache 规 则 。 在 always_direct 中 ,allow规 则 意 味 着 匹 配 的 请 求 直 接 转 发 到 原 始 服 务 器 。always_direct deny 规 则 意 味 着 匹 配 的 请 求不 强 迫 发 送 到 原 始 服 务 器 , 但 假 如 邻 居 cache 不 可 到 达 , 那 可 能 还 是 会 这 么 做 。no_cache 规则 也 有 点 麻 烦 。 这 里 , 你 必 须 对 不 必 被 cache 的 请 求 使 用 deny。6.2.2 <strong>Squid</strong> 如 何 匹 配 访 问 规 则回 想 一 下 squid 在 搜 索 ACL 元 素 时 使 用 的 “ 或 ” 逻 辑 。 在 acl 里 的 任 何 单 值 都 可 以 导 致 匹 配 。然 而 , 访 问 规 则 恰 好 相 反 。 对 http_access 和 其 他 规 则 设 置 ,squid 使 用 “ 与 ” 逻 辑 。 考 虑 如 下示 例 :access_list allow ACL1 ACL2 ACL3对 该 匹 配 规 则 来 说 , 请 求 必 须 匹 配 ACL1,ACL2,ACL3 中 的 任 何 一 个 。 假 如 这 些 ACL 中 的 任 何一 个 不 匹 配 请 求 ,squid 停 止 搜 索 该 规 则 , 并 继 续 处 理 下 一 条 。 对 某 个 规 则 来 说 , 将 最 少 匹 配的 ACL 放 在 首 位 , 能 使 效 率 最 佳 。 考 虑 如 下 示 例 :acl A method httpacl B port 8080http_access deny A B该 http_access 规 则 有 点 低 效 , 因 为 A ACL 看 起 来 比 B ACL 更 容 易 匹 配 。 反 转 顺 序 应 该 更好 , 以 便 squid 仅 仅 检 查 一 个 ACL, 而 不 是 两 个 :http_access deny B A


人 们 易 犯 的 典 型 错 误 是 编 写 永 不 正 确 的 规 则 。 例 如 :acl A src 1.2.3.4acl B src 5.6.7.8http_access allow A B该 规 则 永 不 正 确 , 因 为 某 个 源 IP 地 址 不 可 能 同 时 等 同 于 1.2.3.4 和 5.6.7.8。 这 条 规 则 的 真正 意 图 是 :acl A src 1.2.3.4 5.6.7.8http_access allow A对 某 个 ACL 值 的 匹 配 算 法 是 ,squid 在 访 问 列 表 里 找 到 匹 配 规 则 时 , 搜 索 终 止 。 假 如 没 有 访 问规 则 导 致 匹 配 , 默 认 动 作 是 列 表 里 最 后 一 条 规 则 的 取 反 。 例 如 , 考 虑 如 下 简 单 访 问 配 置 :acl Bob ident bobhttp_access allow Bob假 如 用 户 Mary 发 起 请 求 , 她 会 被 拒 绝 。 列 表 里 最 后 的 ( 唯 一 的 ) 规 则 是 allow 规 则 , 它 不 匹配 用 户 名 mary。 这 样 , 默 认 的 动 作 是 allow 的 取 反 , 故 请 求 被 拒 绝 。 类 似 的 , 假 如 最 后 的 规则 是 deny 规 则 , 默 认 动 作 是 允 许 请 求 。 在 访 问 列 表 的 最 后 加 上 一 条 , 明 确 允 许 或 拒 绝 所 有 请求 , 是 好 的 实 际 做 法 。 为 清 楚 起 见 , 以 前 的 示 例 应 该 如 此 写 :acl All src 0/0acl Bob ident bobhttp_access allow Bobhttp_access deny Allsrc 0/0 ACL 表 示 匹 配 每 一 个 和 任 意 类 型 的 请 求 。6.2.3 访 问 列 表 风 格squid 的 访 问 控 制 语 法 非 常 强 大 。 大 多 数 情 况 下 , 你 可 以 使 用 两 种 或 多 种 方 法 来 完 成 同 样 的 事 。通 常 , 你 该 将 更 具 体 的 和 受 限 制 的 访 问 列 表 放 在 首 位 。 例 如 , 如 下 语 句 并 非 很 好 :acl All src 0/0acl Net1 src 1.2.3.0/24acl Net2 src 1.2.4.0/24acl Net3 src 1.2.5.0/24acl Net4 src 1.2.6.0/24acl WorkingHours time 08:00-17:00http_access allow Net1 WorkingHourshttp_access allow Net2 WorkingHourshttp_access allow Net3 WorkingHourshttp_access allow Net4http_access deny All假 如 你 这 样 写 , 访 问 控 制 列 表 会 更 容 易 维 护 和 理 解 :


http_access allow Net4http_access deny !WorkingHourshttp_access allow Net1http_access allow Net2http_access allow Net3http_access deny All无 论 何 时 , 你 编 写 了 一 个 带 两 个 或 更 多 ACL 元 素 的 规 则 , 建 议 你 在 其 后 紧 跟 一 条 相 反 的 , 更 广泛 的 规 则 。 例 如 , 默 认 的 squid 配 置 拒 绝 非 来 自 本 机 IP 地 址 的 cache 管 理 请 求 , 你 也 许 试 图这 样 写 :acl CacheManager proto cache_objectacl Localhost src 127.0.0.1http_access deny CacheManager !Localhost然 而 , 这 里 的 问 题 是 , 你 没 有 允 许 确 实 来 自 本 机 的 cache 管 理 请 求 。 随 后 的 规 则 可 能 导 致 请 求被 拒 绝 。 如 下 规 则 就 产 生 了 问 题 :acl CacheManager proto cache_objectacl Localhost src 127.0.0.1acl MyNet 10.0.0.0/24acl All src 0/0http_access deny CacheManager !Localhosthttp_access allow MyNethttp_access deny All既 然 来 自 本 机 的 请 求 不 匹 配 MyNet, 它 被 拒 绝 。 编 写 本 规 则 的 更 好 方 法 是 :http_access allow CacheManager localhosthttp_access deny CacheManagerhttp_access allow MyNethttp_access deny All6.2.4 延 时 检 查某 些 ACL 不 能 在 一 个 过 程 里 被 检 查 , 因 为 必 要 的 信 息 不 可 用 。ident,dst,srcdomain 和proxy_auth 类 型 属 于 该 范 畴 。 当 squid 遇 到 某 个 ACL 不 能 被 检 查 时 , 它 延 迟 决 定 并 且 发 布对 必 要 信 息 的 查 询 (IP 地 址 , 域 名 , 用 户 名 等 )。 当 信 息 可 用 时 ,squid 再 次 在 列 表 的 开 头 位置 检 查 这 些 规 则 。 它 不 会 从 前 次 检 查 剩 下 的 位 置 继 续 。 假 如 可 能 , 你 应 该 将 这 些 最 可 能 被 延 时 的ACL 放 在 规 则 的 顶 部 , 以 避 免 不 必 要 的 , 重 复 的 检 查 。因 为 延 时 的 代 价 太 大 ,squid 会 尽 可 能 缓 存 查 询 获 取 的 信 息 。ident 查 询 在 每 个 连 接 里 发 生 ,而 不 是 在 每 个 请 求 里 。 这 意 味 着 , 当 你 使 用 ident 查 询 时 , 持 续 HTTP 连 接 切 实 对 你 有 利 。DNS响 应 的 主 机 名 和 IP 地 址 也 被 缓 存 , 除 非 你 使 用 早 期 的 外 部 dnsserver 进 程 。 代 理 验证 信 息 被 缓 存 , 请 见 6.1.2.12 章 节 的 描 述 。


6.2.5 减 缓 和 加 速 规 则 检 查<strong>Squid</strong> 内 部 考 虑 某 些 访 问 规 则 被 快 速 检 查 , 其 他 的 被 减 缓 检 查 。 区 别 是 squid 是 否 延 迟 它 的 决定 , 以 等 待 附 加 信 息 。 换 句 话 说 , 在 squid 查 询 附 加 信 息 时 , 某 个 减 缓 检 查 会 被 延 时 , 例 如 :+ 反 向 DNS 查 询 : 客 户 IP 地 址 的 主 机 名+ RFC 1413 ident 查 询 : 客 户 TCP 连 接 的 用 户 名+ 验 证 器 : 验 证 用 户 信 用+ DNS 转 发 查 询 : 原 始 服 务 器 的 IP 地 址+ 用 户 定 义 的 外 部 ACL某 些 访 问 规 则 使 用 快 速 检 查 。 例 如 ,icp_access 规 则 被 快 速 检 查 。 为 了 快 速 响 应 ICP 查 询 ,它 必 须 被 快 速 检 查 。 甚 至 , 某 些 ACL 类 型 例 如 proxy_auth, 对 ICP 查 询 来 说 无 意 义 。 下 列访 问 规 则 被 快 速 检 查 :header_accessreply_body_max_sizereply_accessident_lookupdelay_accessmiss_accessbroken_postsicp_accesscache_peer_accessredirector_accesssnmp_access下 列 ACL 类 型 可 能 需 要 来 自 外 部 数 据 源 (DNS, 验 证 器 等 ) 的 信 息 , 这 样 与 快 速 的 访 问 规 则 不兼 容 :srcdomain, dstdomain, srcdom_regex, dstdom_regexdst, dst_asproxy_authidentexternal_acl_type这 意 味 着 , 例 如 , 不 能 在 header_access 规 则 里 使 用 ident ACL。6.3 常 见 用 法因 为 访 问 控 制 可 能 很 复 杂 , 本 节 包 含 一 些 示 例 。 它 们 描 述 了 一 些 访 问 控 制 的 普 通 用 法 。 你 可 以 在实 际 中 调 整 它 们 。6.3.1 仅 仅 允 许 本 地 客 户


几 乎 每 个 squid 安 装 后 , 都 限 制 基 于 客 户 IP 地 址 的 访 问 。 这 是 保 护 你 的 系 统 不 被 滥 用 的 最 好的 方 法 之 一 。 做 到 这 点 最 容 易 的 方 法 是 , 编 写 包 含 IP 地 址 空 间 的 ACL, 然 后 允 许 该 ACL 的 HTTP请 求 , 并 拒 绝 其 他 的 。acl All src 0/0acl MyNetwork src 172.16.5.0/24 172.16.6.0/24http_access allow MyNetworkhttp_access deny All也 许 该 访 问 控 制 配 置 过 于 简 单 , 所 以 你 要 增 加 更 多 行 。 记 住 http_access 的 顺 序 至 关 重 要 。 不要 在 deny all 后 面 增 加 任 何 语 句 。 假 如 必 要 , 应 该 在 allow MyNetwork 之 前 或 之 后 增 加 新 规则 。6.3.2 阻 止 恶 意 客 户因 为 某 种 理 由 , 你 也 许 有 必 要 拒 绝 特 定 客 户 IP 地 址 的 访 问 。 这 种 情 况 可 能 发 生 , 例 如 , 假 如 某个 雇 员 或 学 生 发 起 一 个 异 常 耗 费 网 络 带 宽 或 其 他 资 源 的 web 连 接 , 在 根 本 解 决 这 个 问 题 前 , 你可 以 配 置 squid 来 阻 止 这 个 请 求 :acl All src 0/0acl MyNetwork src 172.16.5.0/24 172.16.6.0/24acl ProblemHost src 172.16.5.9http_access deny ProblemHosthttp_access allow MyNetworkhttp_access deny All6.3.3 内 容 过 滤阻 塞 对 特 定 内 容 的 访 问 是 棘 手 的 问 题 。 通 常 , 使 用 squid 进 行 内 容 过 滤 最 难 的 部 分 , 是 被 阻 塞的 站 点 列 表 。 你 也 许 想 自 己 维 护 一 个 这 样 的 列 表 , 或 从 其 他 地 方 获 取 一 个 。squid FAQ 的 “ 访 问控 制 ” 章 节 有 链 接 指 向 免 费 的 可 用 列 表 。使 用 这 样 的 列 表 的 ACL 语 法 依 赖 于 它 的 内 容 。 假 如 列 表 包 含 正 则 表 达 式 , 你 可 能 要 这 样 写 :acl PornSites url_regex "/usr/local/squid/etc/pornlist"http_access deny PornSites另 一 方 面 , 假 如 列 表 包 含 原 始 服 务 器 主 机 名 , 那 么 简 单 的 更 改 url_regex 为 dstdomain。6.3.4 在 工 作 时 间 的 受 限 使 用某 些 公 司 喜 欢 在 工 作 时 间 限 制 web 使 用 , 为 了 节 省 带 宽 , 或 者 是 公 司 政 策 禁 止 员 工 在 工 作 时 做某 些 事 情 。 关 于 这 个 最 难 的 部 分 是 , 所 谓 合 适 的 和 不 合 适 的 internet 使 用 之 间 的 区 别 是 什 么 。不 幸 的 是 , 我 不 能 对 这 个 问 题 作 出 回 答 。 在 该 例 子 里 , 假 设 你 已 收 集 了 一 份 web 站 点 域 名 列 表 ,


它 包 含 已 知 的 不 适 合 于 你 的 站 点 名 , 那 么 这 样 配 置 squid:acl NotWorkRelated dstdomain "/usr/local/squid/etc/not-work-related-sites"acl WorkingHours time D 08:00-17:30http_access deny !WorkingHours NotWorkRelated请 注 意 在 该 规 则 里 首 先 放 置 !WorkingHours ACL。 相 对 于 字 符 串 或 列 表 ,dstdomain ACL 产生 的 性 能 代 价 较 大 , 但 time ACL 检 查 却 很 简 单 。下 面 的 例 子 , 进 一 步 理 解 如 何 结 合 如 下 方 法 和 前 面 描 述 的 源 地 址 控 制 , 来 控 制 访 问 。acl All src 0/0acl MyNetwork src 172.16.5.0/24 172.16.6.0/24acl NotWorkRelated dstdomain "/usr/local/squid/etc/not-work-related-sites"acl WorkingHours time D 08:00-17:30http_access deny !WorkingHours NotWorkRelatedhttp_access allow MyNetworkhttp_access deny All上 面 的 方 法 可 行 , 因 为 它 实 现 了 我 们 的 目 标 , 在 工 作 时 间 内 拒 绝 某 些 请 求 , 并 允 许 来 自 你 自 己 网络 的 请 求 。 然 而 , 它 也 许 有 点 低 效 。 注 意 NotWorkRelated ACL 在 所 有 请 求 里 被 搜 索 , 而 不管 源 IP 地 址 。 假 如 那 个 列 表 非 常 长 , 在 列 表 里 对 外 部 网 络 请 求 的 搜 索 , 纯 粹 是 浪 费 CPU 资 源 。所 以 , 你 该 这 样 改 变 规 则 :http_access deny !MyNetworkhttp_access deny !WorkingHours NotWorkRelatedhttp_access Allow All这 里 , 将 代 价 较 大 的 检 查 放 在 最 后 。 试 图 滥 用 squid 的 外 部 用 户 不 会 再 浪 费 你 的 CPU 资 源 。6.3.5 阻 止 squid 与 非 HTTP 服 务 器 会 话你 必 须 尽 可 能 不 让 squid 与 某 些 类 型 的 TCP/IP 服 务 器 通 信 。 例 如 , 永 不 能 够 使 用 squid 缓 存来 转 发 SMTP 传 输 。 我 在 前 面 介 绍 port ACL 时 提 到 过 这 点 。 然 而 , 它 是 至 关 重 要 的 , 所 以 再强 调 一 下 。首 先 , 你 必 须 关 注 CONNECT 请 求 方 法 。 使 用 该 方 法 的 用 户 代 理 , 通 过 HTTP 代 理 来 封 装 TCP连 接 。 它 被 创 造 用 于 HTTP/TLS 请 求 , 这 是 CONNECT 方 法 的 主 要 用 途 。 某 些 用 户 代 理 也 可以 通 过 防 火 墙 代 理 来 封 装 NNTP/TLS 传 输 。 所 有 其 他 的 用 法 应 该 被 拒 绝 。 所 以 ,你 的 访 问 列 表 , 应 该 仅 仅 允 许 到 HTTP/TLS 和 NNTP/TLS 端 口 的 CONNECT 请 求 。第 二 , 你 应 该 阻 止 squid 连 接 到 某 些 服 务 , 例 如 SMTP。 你 也 可 以 开 放 安 全 端 口 和 拒 绝 危 险 端口 。 我 对 这 两 种 技 术 给 出 示 例 。让 我 们 看 看 默 认 的 squid.conf 文 件 提 供 的 规 则 :acl Safe_ports port 80 # http


acl Safe_ports port 21 # ftpacl Safe_ports port 443 563 # https, snewsacl Safe_ports port 70 # gopheracl Safe_ports port 210 # waisacl Safe_ports port 280 # http-mgmtacl Safe_ports port 488 # gss-httpacl Safe_ports port 591 # filemakeracl Safe_ports port 777 # multiling httpacl Safe_ports port 1025-65535 # unregistered portsacl SSL_ports port 443 563acl CONNECT method CONNECThttp_access deny !Safe_portshttp_access deny CONNECT !SSL_ports;Safe_ports ACL 列 举 了 所 有 的 squid 有 合 法 响 应 的 特 权 端 口 ( 小 于 1024)。 它 也 列 举 了 所 有非 特 权 端 口 范 围 。 注 意 Safe_ports ACL 也 包 括 了 安 全 HTTP 和 NNTP 端 口 (443 和 563),即 使 它 们 也 出 现 在 SSL_ports ACL 里 。 这 是 因 为 Safe_ports 在 规 则 里 首 先 被 检 查 。 假 如 你交 换 了 两 个 http_access 行 的 顺 序 , 你 也 许 能 从 Safe_ports 列 表 里 删 除 443 和 563, 但 没必 要 这 么 麻 烦 。与 此 相 似 的 其 他 方 法 是 , 列 举 已 知 不 安 全 的 特 权 端 口 :acl Dangerous_ports 7 9 19 22 23 25 53 109 110 119acl SSL_ports port 443 563acl CONNECT method CONNECThttp_access deny Dangerous_portshttp_access deny CONNECT !SSL_ports;假 如 你 不 熟 悉 这 些 奇 特 的 端 口 号 , 也 不 要 担 心 。 你 可 以 阅 读 unix 系 统 的 /etc/services 文 件 ,或 者 阅 读 IANA 的 注 册 TCP/UDP 端 口 号 列 表 :http://www.iana.org/assignments/port-numbers6.3.6 授 予 某 些 用 户 特 殊 的 访 问使 用 基 于 用 户 名 进 行 访 问 控 制 的 组 织 , 通 常 需 要 授 予 某 些 用 户 特 殊 的 权 限 。 在 该 简 单 示 例 里 , 有三 个 元 素 : 所 有 授 权 用 户 , 管 理 员 用 户 名 , 限 制 访 问 的 web 站 点 列 表 。 正 常 的 用 户 不 允 许 访 问受 限 站 点 , 但 管 理 员 有 维 护 这 个 列 表 的 任 务 。 他 们 必 须 连 接 到 所 有 服 务 器 , 去 验 证 某 个 特 殊 站 点是 否 该 放 到 受 限 站 点 列 表 里 。 如 下 显 示 如 何 完 成 这 个 任 务 :auth_param basic program /usr/local/squid/libexec/ncsa_auth/usr/local/squid/etc/passwdacl Authenticated proxy_auth REQUIREDacl Admins proxy_auth Pat Jean Chris


acl Porn dstdomain "/usr/local/squid/etc/porn.domains"acl All src 0/0http_access allow Adminshttp_access deny Pornhttp_access allow Authenticatedhttp_access deny All首 先 , 有 三 个 ACL 定 义 。Authenticated ACL 匹 配 任 何 有 效 的 代 理 验 证 信 用 。Admins ACL匹 配 来 自 用 户 Pat,Jean, 和 Chris 的 有 效 信 用 。Porn ACL 匹 配 某 些 原 始 服 务 器 主 机 名 , 它 们在 porn.domains 文 件 里 找 到 。该 示 例 有 四 个 访 问 控 制 规 则 。 第 一 个 仅 仅 检 查 Admins ACL, 允 许 所 有 来 自 Pat,Jean, 和 Chris的 请 求 。 对 其 他 用 户 ,squid 转 移 到 下 一 条 规 则 。 对 第 二 条 规 则 , 假 如 原 始 主 机 名 位 于porn.domains 文 件 , 那 么 该 请 求 被 拒 绝 。 对 不 匹 配 Porn ACL 的 请 求 ,squid 转 移 到 第 三 条规 则 。 第 三 条 规 则 里 , 假 如 请 求 包 含 有 效 的 验 证 信 用 , 那 么 该 请 求 被 允 许 。 外 部 验 证 器 ( 这 里 的ncsa_auth) 决 定 是 否 信 用 有 效 。 假 如 它 们 无 效 , 最 后 的 规 则 出 现 , 该 请 求 被 拒 绝 。注 意 ncsa_auth 验 证 器 并 非 必 需 。 你 可 以 使 用 12 章 里 描 述 的 任 何 验 证 辅 助 程 序 。6.3.7 阻 止 邻 近 cache 的 滥 用假 如 你 使 用 了 cache 集 群 , 你 必 须 付 出 多 余 的 小 心 。cache 通 常 使 用 ICP 来 发 现 哪 些 对 象 被缓 存 在 它 们 的 邻 居 机 器 上 。 你 仅 该 接 受 来 自 已 知 授 权 的 邻 居 cache 的 ICP 查 询 。更 进 一 步 , 通 过 使 用 miss_access 规 则 列 表 , 你 能 配 置 squid 强 制 限 制 邻 近 关 系 。squid 仅仅 在 cache 丢 失 , 没 有 cache 命 中 时 才 检 查 这 些 规 则 。 这 样 , 在 miss_access 列 表 生 效 前 ,所 有 请 求 必 须 首 先 通 过 http_access 规 则 。在 本 示 例 里 , 有 三 个 独 立 的 ACL。 一 个 是 直 接 连 接 到 cache 的 本 地 用 户 ; 另 一 个 是 子 cache,它 被 允 许 来 转 发 cache 丢 失 的 请 求 ; 第 三 个 是 邻 近 cache, 它 必 须 从 不 转 发 导 致 cache 丢 失的 请 求 。 如 下 是 它 们 如 何 工 作 :alc All src 0/0acl OurUsers src 172.16.5.0/24acl ChildCache src 192.168.1.1acl SiblingCache src 192.168.3.3http_access allow OurUsershttp_access allow ChildCachehttp_access allow SiblingCachehttp_access deny Allmiss_access deny SiblingCacheicp_access allow ChildCacheicp_access allow SiblingCacheicp_access deny All


6.3.8 使 用 IP 地 址 拒 绝 请 求我 在 6.1.2.4 章 节 里 提 过 ,dstdomain 类 型 是 阻 塞 对 指 定 原 始 主 机 访 问 的 好 选 择 。 然 而 , 聪明 的 用 户 通 过 替 换 URL 主 机 名 成 IP 地 址 , 能 够 绕 过 这 样 的 规 则 。 假 如 你 想 彻 底 阻 止 这 样 的 请求 , 你 可 能 得 阻 塞 所 有 包 含 IP 地 址 的 请 求 。 你 可 以 使 用 重 定 向 器 , 或 者 使 用 dstdom_regexACL 来 完 成 。 例 如 :acl IPForHostname dstdom_regex ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$http_access deny IPForHostname6.3.9 http_reply_access 示 例回 想 一 下 , 当 squid 检 查 http_reply_access 规 则 时 , 响 应 的 内 容 类 型 是 唯 一 的 可 用 新 信 息 。这 样 , 你 能 保 持 http_reply_access 规 则 简 单 化 。 你 只 需 检 查 rep_mime_type ACL。 例 如 ,如 下 示 例 告 诉 你 如 何 拒 绝 某 些 内 容 类 型 的 响 应 :acl All src 0/0acl Movies rep_mime_type video/mpegacl MP3s rep_mime_type audio/mpeghttp_reply_access deny Movieshttp_reply_access deny MP3shttp_reply_access allow All你 不 必 在 http_reply_access 列 表 里 重 复 http_access 规 则 。 这 里 的 allow ALL 规 则 不 意味 着 所 有 对 squid 的 请 求 被 允 许 。 任 何 被 http_access 拒 绝 的 请 求 , 从 来 不 会 再 被http_reply_access 检 查 。6.3.10 阻 止 对 本 地 站 点 的 cache 命 中假 如 你 有 许 多 原 始 服 务 器 在 本 地 网 络 中 , 你 也 许 想 配 置 squid, 以 便 它 们 的 响 应 永 不 被 缓 存 。 因为 服 务 器 就 在 附 近 , 它 们 不 会 从 cache 命 中 里 获 益 很 多 。 另 外 , 它 释 放 存 储 空 间 给 其 他 远 程 原始 主 机 。第 一 步 是 定 义 本 地 服 务 器 的 ACL。 你 可 能 使 用 基 于 地 址 的 ACL, 例 如 :acl LocalServers dst 172.17.1.0/24假 如 服 务 器 不 位 于 单 一 的 子 网 , 你 也 许 该 创 建 dstdomain ACL:acl LocalServers dstdomain .example.com接 下 来 , 你 简 单 的 使 用 no_cache access 规 则 , 拒 绝 这 些 服 务 器 的 cache:no_cache deny LocalServers


no_cache 规 则 不 会 阻 止 客 户 发 送 请 求 到 squid。 没 有 办 法 配 置 squid 阻 止 这 样 的 请 求 进 来 。代 替 的 , 你 必 须 配 置 用 户 代 理 自 身 。假 如 你 在 squid 运 行 一 段 时 间 后 增 加 no_cache 规 则 ,cache 可 能 包 含 一 些 匹 配 新 规 则 的 对象 。 在 squid2.5 之 前 的 版 本 , 这 些 以 前 缓 存 的 对 象 可 能 以 cache 命 中 返 回 。 然 而 现 在 ,squid清 除 掉 所 有 匹 配 no_cache 规 则 的 缓 存 响 应 。6.4 测 试 访 问 控 制访 问 控 制 配 置 越 长 , 它 就 越 复 杂 。 强 烈 建 议 你 在 将 它 们 用 于 产 品 环 境 之 前 , 先 测 试 访 问 控 制 。 当然 , 首 先 做 的 事 是 确 认 squid 能 正 确 的 解 析 配 置 文 件 。 使 用 -k parse 功 能 :% squid -k parse为 了 进 一 步 测 试 访 问 控 制 , 你 需 要 安 装 一 个 用 于 测 试 的 squid。 容 易 做 到 的 方 法 是 , 编 译 另 一 份squid 到 其 他 $prefix 位 置 。 例 如 :% tar xzvf squid-2.5.STABLE4.tar.gz% cd squid-2.5.STABLE4% ./configure --prefix=/tmp/squid ...% make && make install在 安 装 完 后 , 你 必 须 编 辑 新 的 squid.conf 文 件 , 更 改 一 些 指 令 。 假 如 squid 已 经 运 行 在默 认 端 口 , 那 么 请 改 变 http_port。 为 了 执 行 简 单 的 测 试 , 创 建 单 一 的 小 目 录 :cache_dir ufs /tmp/squid/cache 100 4 4假 如 你 不 想 重 编 译 squid, 你 也 能 创 建 一 份 新 的 配 置 文 件 。 该 方 法 的 弊 端 是 你 必 须 设 置 所 有 的 日志 文 件 路 径 为 临 时 目 录 , 以 便 不 会 覆 盖 真 正 的 文 件 。你 可 以 使 用 squidclient 程 序 来 轻 松 的 测 试 某 些 访 问 控 制 。 例 如 , 假 如 你 有 一 条 规 则 , 它 依 赖于 原 始 服 务 器 主 机 名 ( dstdomain ACL ), 或 者 某 些 URL 部 分 ( url_regex 或urlpath_regex), 简 单 的 输 入 你 期 望 被 允 许 或 拒 绝 的 URI:% squidclient -p 4128 http://blocked.host.name/blah/blahor:% squidclient -p 4128 http://some.host.name/blocked.ext某 些 类 型 的 请 求 难 以 控 制 。 假 如 你 有 src ACL, 它 们 阻 止 来 自 外 部 网 络 的 请 求 , 你 也 许 需 要 从 外部 主 机 测 试 它 们 。 测 试 time ACL 也 很 困 难 , 除 非 你 能 改 变 系 统 时 钟 , 或 者 等 待 足 够 长 时 间 。你 能 使 用 squidclient 的 -H 选 项 来 设 置 任 意 请 求 头 。 例 如 , 假 如 你 需 要 测 试 browser ACL,那 么 这 样 做 :% squidclient -p 4128 http://www.host.name/blah \-H 'User-Agent: Mozilla/5.0 (compatible; Konqueror/3)\r\n'更 多 的 复 杂 请 求 , 包 括 多 个 头 部 , 请 参 考 16.4 章 中 描 述 的 技 术 。你 也 许 考 虑 制 订 一 项 cron, 定 期 检 查 ACL, 以 发 现 期 望 的 行 为 , 并 报 告 任 何 异 常 。 如 下 是 可 以


制 , 它 与 aufs 和 diskd 一 致 。7.1.2 参 数 :Directory该 参 数 是 文 件 系 统 目 录 ,squid 将 cache 对 象 文 件 存 放 在 这 个 目 录 下 。 正 常 的 ,cache_dir 使用 整 个 文 件 系 统 或 磁 盘 分 区 。 它 通 常 不 介 意 是 否 在 单 个 文 件 系 统 分 区 里 放 置 了 多 个 cache 目 录 。然 而 , 我 推 荐 在 每 个 物 理 磁 盘 中 , 仅 仅 设 置 一 个 cache 目 录 。 例 如 , 假 如 你 有 2 个 无 用 磁 盘 ,你 可 以 这 样 做 :# newfs /dev/da1d# newfs /dev/da2d# mount /dev/da1d /cache0# mount /dev/da2d /cache1然 后 在 squid.conf 里 增 加 如 下 行 :cache_dir ufs /cache0 7000 16 256cache_dir ufs /cache1 7000 16 256假 如 你 没 有 空 闲 硬 盘 , 当 然 你 也 能 使 用 已 经 存 在 的 文 件 系 统 分 区 。 选 择 有 大 量 空 闲 空 间 的 分 区 ,例 如 /usr 或 /var, 然 后 在 下 面 创 建 一 个 新 目 录 。 例 如 :# mkdir /var/squidcache然 后 在 squid.conf 里 增 加 如 下 一 行 :cache_dir ufs /var/squidcache 7000 16 2567.1.3 参 数 :Size该 参 数 指 定 了 cache 目 录 的 大 小 。 这 是 squid 能 使 用 的 cache_dir 目 录 的 空 间 上 限 。 计 算 出 合理 的 值 也 许 有 点 难 。 你 必 须 给 临 时 文 件 和 swap.state 日 志 , 留 出 足 够 的 自 由 空 间 ( 见 13.6 章 )。我 推 荐 挂 载 空 文 件 系 统 , 可 以 运 行 df:% df -kFilesystem 1K-blocks Used Avail Capacity Mounted on/dev/da1d 3037766 8 2794737 0% /cache0/dev/da2d 3037766 8 2794737 0% /cache1这 里 你 可 以 看 到 文 件 系 统 有 大 约 2790M 的 可 用 空 间 。 记 住 ,UFS 保 留 了 部 分 最 小 自 由 空 间 ,这 里 约 是 8%, 这 就 是 squid 为 什 么 不 能 使 用 全 部 3040M 空 间 的 原 因 。你 也 许 试 图 分 配 2790M 给 cache_dir。 如 果 cache 不 很 繁 忙 , 并 且 你 经 常 轮 转 日 志 , 那 么 这样 做 也 许 可 行 。 然 而 , 为 安 全 起 见 , 我 推 荐 保 留 10% 的 空 间 。 这 些 额 外 的 空 间 用 于 存 放 squid的 swap.state 文 件 和 临 时 文 件 。注 意 cache_swap_low 指 令 也 影 响 了 squid 使 用 多 少 空 间 。 我 将 在 7.2 章 里 讨 论 它 的 上 限 和下 限 。


底 线 是 , 你 在 初 始 时 应 保 守 的 估 计 cache_dir 的 大 小 。 将 cache_dir 设 为 较 小 的 值 , 并 允 许 写满 cache。 在 squid 运 行 一 段 时 间 后 ,cache 目 录 会 填 满 , 这 样 你 可 以 重 新 评 估 cache_dir 的大 小 设 置 。 假 如 你 有 大 量 的 自 由 空 间 , 就 可 以 轻 松 的 增 加 cache 目 录 的 大 小 了 。7.1.3.1 InodesInodes(i 节 点 ) 是 unix 文 件 系 统 的 基 本 结 构 。 它 们 包 含 磁 盘 文 件 的 信 息 , 例 如 许 可 , 属 主 ,大 小 , 和 时 间 戳 。 假 如 你 的 文 件 系 统 运 行 超 出 了 i 节 点 限 制 , 就 不 能 创 造 新 文 件 , 即 使 还 有 空 间可 用 。 超 出 i 节 点 的 系 统 运 行 非 常 糟 糕 , 所 以 在 运 行 squid 之 前 , 你 应 该 确 认 有 足 够 的 i 节 点 。创 建 新 文 件 系 统 的 程 序 ( 例 如 ,newfs 或 mkfs) 基 于 总 空 间 的 大 小 , 保 留 了 一 定 数 量 的 i 节 点 。这 些 程 序 通 常 允 许 你 设 置 磁 盘 空 间 的 i 节 点 比 率 。 例 如 , 请 阅 读 newfs 和 mkfs 手 册 的 -i 选 项 。磁 盘 空 间 对 i 节 点 的 比 率 , 决 定 了 文 件 系 统 能 实 际 支 持 的 文 件 大 小 。 大 部 分 unix 系 统 每 4KB 创建 一 个 i 节 点 , 这 对 squid 通 常 是 足 够 的 。 研 究 显 示 , 对 大 部 分 cache 代 理 , 实 际 文 件 大 小 大约 是 10KB。 你 也 许 能 以 每 i 节 点 8KB 开 始 , 但 这 有 风 险 。你 能 使 用 df -i 命 令 来 监 视 系 统 的 i 节 点 , 例 如 :% df -ikFilesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on/dev/ad0s1a 197951 57114 125001 31% 1413 52345 3% //dev/ad0s1f 5004533 2352120 2252051 51% 129175 1084263 11% /usr/dev/ad0s1e 396895 6786 358358 2% 205 99633 0% /var/dev/da0d 8533292 7222148 628481 92% 430894 539184 44% /cache1/dev/da1d 8533292 7181645 668984 91% 430272 539806 44% /cache2/dev/da2d 8533292 7198600 652029 92% 434726 535352 45% /cache3/dev/da3d 8533292 7208948 641681 92% 427866 542212 44% /cache4如 果 i 节 点 的 使 用 (%iused) 少 于 空 间 使 用 (Capacity), 那 就 很 好 。 不 幸 的 是 , 你 不 能 对 已经 存 在 的 文 件 系 统 增 加 更 多 i 节 点 。 假 如 你 发 现 运 行 超 出 了 i 节 点 , 那 就 必 须 停 止 squid, 并 且重 新 创 建 文 件 系 统 。 假 如 你 不 愿 意 这 样 做 , 那 么 请 削 减 cache_dir 的 大 小 。7.1.3.2 在 磁 盘 空 间 和 进 程 大 小 之 间 的 联 系<strong>Squid</strong> 的 磁 盘 空 间 使 用 也 直 接 影 响 了 它 的 内 存 使 用 。 每 个 在 磁 盘 中 存 在 的 对 象 , 要 求 少 量 的 内存 。squid 使 用 内 存 来 索 引 磁 盘 数 据 。 假 如 你 增 加 了 新 的 cache 目 录 , 或 者 增 加 了 磁 盘 cache大 小 , 请 确 认 你 已 有 足 够 的 自 由 内 存 。 假 如 squid 的 进 程 大 小 达 到 或 超 过 了 系 统 的 物 理 内 存 容


量 ,squid 的 性 能 下 降 得 非 常 块 。<strong>Squid</strong> 的 cache 目 录 里 的 每 个 对 象 消 耗 76 或 112 字 节 的 内 存 , 这 依 赖 于 你 的 系 统 。 内 存 以StoreEntry, MD5 Digest, 和 LRU policy node 结 构 来 分 配 。 小 指 令 ( 例 如 ,32 位 ) 系 统 ,象 那 些 基 于 Intel Pentium 的 , 取 76 字 节 。 使 用 64 位 指 令 CPU 的 系 统 , 每 个 目 标 取 112 字节 。 通 过 阅 读 cache 管 理 的 内 存 管 理 文 档 , 你 能 发 现 这 些 结 构 在 你 的 系 统 中 耗 费 多 少 内 存 ( 请见 14.2.1.2 章 )。不 幸 的 是 , 难 以 精 确 预 测 对 于 给 定 数 量 的 磁 盘 空 间 , 需 要 使 用 多 少 附 加 内 存 。 它 依 赖 于 实 际 响 应大 小 , 而 这 个 大 小 基 于 时 间 波 动 。 另 外 ,<strong>Squid</strong> 还 为 其 他 数 据 结 构 和 目 的 分 配 内 存 。 不 要 假 设你 的 估 计 正 确 。 你 该 经 常 监 视 squid 的 进 程 大 小 , 假 如 必 要 , 考 虑 削 减 cache 大 小 。7.1.4 参 数 :L1 和 L2对 ufs,aufs, 和 diskd 机 制 ,squid 在 cache 目 录 下 创 建 二 级 目 录 树 。L1 和 L2 参 数 指 定 了 第一 级 和 第 二 级 目 录 的 数 量 。 默 认 的 是 16 和 256。 图 7-1 显 示 文 件 系 统 结 构 。Figure 7-1. 基 于 ufs 存 储 机 制 的 cache 目 录 结 构( 略 图 )某 些 人 认 为 squid 依 赖 于 L1 和 L2 的 特 殊 值 , 会 执 行 得 更 好 或 更 差 。 这 点 听 起 来 有 关 系 , 即 小目 录 比 大 目 录 被 检 索 得 更 快 。 这 样 ,L1 和 L2 也 许 该 足 够 大 , 以 便 L2 目 录 的 文 件 更 少 。例 如 , 假 设 你 的 cache 目 录 存 储 了 7000M, 假 设 实 际 文 件 大 小 是 10KB, 你 能 在 这 个 cache_dir里 存 储 700,000 个 文 件 。 使 用 16 个 L1 和 256 个 L2 目 录 , 总 共 有 4096 个 二 级 目 录 。700,000/4096 的 结 果 是 , 每 个 二 级 目 录 大 约 有 170 个 文 件 。如 果 L1 和 L2 的 值 比 较 小 , 那 么 使 用 squid -z 创 建 交 换 目 录 的 过 程 , 会 执 行 更 快 。 这 样 , 假 如你 的 cache 文 件 确 实 小 , 你 也 许 该 减 少 L1 和 L2 目 录 的 数 量 。<strong>Squid</strong> 给 每 个 cache 目 标 分 配 一 个 唯 一 的 文 件 号 。 这 是 个 32 位 的 整 数 , 它 唯 一 标 明 磁 盘 中 的文 件 。squid 使 用 相 对 简 单 的 算 法 , 将 文 件 号 转 换 位 路 径 名 。 该 算 法 使 用 L1 和 L2 作 为 参 数 。这 样 , 假 如 你 改 变 了 L1 和 L2, 你 改 变 了 从 文 件 号 到 路 径 名 的 映 射 关 系 。 对 非 空 的 cache_dir改 变 这 些 参 数 , 导 致 存 在 的 文 件 不 可 访 问 。 在 cache 目 录 激 活 后 , 你 永 不 要 改 变 L1 和 L2 值 。<strong>Squid</strong> 在 cache 目 录 顺 序 中 分 配 文 件 号 。 文 件 号 到 路 径 名 的 算 法 ( 例 如 ,storeUfsDirFullPath( )), 用 以 将 每 组 L2 文 件 映 射 到 同 样 的 二 级 目 录 。<strong>Squid</strong> 使 用 了 参 考 位置 来 做 到 这 点 。 该 算 法 让 HTML 文 件 和 它 内 嵌 的 图 片 更 可 能 的 保 存 在 同 一 个 二 级 目 录 中 。 某 些人 希 望 squid 均 匀 的 将 cache 文 件 放 在 每 个 二 级 目 录 中 。 然 而 , 当 cache 初 始 写 入 时 , 你 可 以发 现 仅 仅 开 头 的 少 数 目 录 包 含 了 一 些 文 件 , 例 如 :% cd /cache0; du -k2164 ./00/002146 ./00/012689 ./00/021974 ./00/032201 ./00/042463 ./00/052724 ./00/063174 ./00/071144 ./00/08


1 ./00/091 ./00/0A1 ./00/0B这 是 完 全 正 常 的 , 不 必 担 心 。7.1.5 参 数 :Options<strong>Squid</strong> 有 2 个 依 赖 于 不 同 存 储 机 制 的 cache_dir 选 项 :read-only 标 签 和 max-size 值 。7.1.5.1 read-onlyread-only 选 项 指 示 <strong>Squid</strong> 继 续 从 cache_dir 读 取 文 件 , 但 不 往 里 面 写 新 目 标 。 它 在 squid.conf文 件 里 看 起 来 如 下 :cache_dir ufs /cache0 7000 16 256 read-only假 如 你 想 把 cache 文 件 从 一 个 磁 盘 迁 移 到 另 一 个 磁 盘 , 那 么 可 使 用 该 选 项 。 如 果 你 简 单 的 增 加一 个 cache_dir, 并 且 删 除 另 一 个 ,squid 的 命 中 率 会 显 著 下 降 。 在 旧 目 录 是 read-only 时 ,你 仍 能 从 那 里 获 取 cache 命 中 。 在 一 段 时 间 后 , 就 可 以 从 配 置 文 件 里 删 除 read-only 缓 存 目 录 。7.1.5.2 max-size使 用 该 选 项 , 你 可 以 指 定 存 储 在 cache 目 录 里 的 最 大 目 标 大 小 。 例 如 :cache_dir ufs /cache0 7000 16 256 max-size=1048576注 意 值 是 以 字 节 为 单 位 的 。 在 大 多 数 情 况 下 , 你 不 必 增 加 该 选 项 。 假 如 你 做 了 , 请 尽 力 将 所 有cache_dir 行 以 max-size 大 小 顺 序 来 存 放 ( 从 小 到 大 )。7.2 磁 盘 空 间 基 准cache_swap_low 和 cache_swap_high 指 令 控 制 了 存 储 在 磁 盘 上 的 对 象 的 置 换 。 它 们 的 值 是最 大 cache 体 积 的 百 分 比 , 这 个 最 大 cache 体 积 来 自 于 所 有 cache_dir 大 小 的 总 和 。 例 如 :cache_swap_low 90cache_swap_high 95如 果 总 共 磁 盘 使 用 低 于 cache_swap_low,squid 不 会 删 除 cache 目 标 。 如 果 cache 体 积 增加 ,squid 会 逐 渐 删 除 目 标 。 在 稳 定 状 态 下 , 你 发 现 磁 盘 使 用 总 是 相 对 接 近 cache_swap_low值 。 你 可 以 通 过 请 求 cache 管 理 器 的 storedir 页 面 来 查 看 当 前 磁 盘 使 用 状 况 ( 见 14.2.1.39章 )。请 注 意 , 改 变 cache_swap_high 也 许 不 会 对 squid 的 磁 盘 使 用 有 太 大 效 果 。 在 squid 的 早 期版 本 里 , 该 参 数 有 重 要 作 用 ; 然 而 现 在 , 它 不 是 这 样 了 。7.3 对 象 大 小 限 制你 可 以 控 制 缓 存 对 象 的 最 大 和 最 小 体 积 。 比 maximum_object_size 更 大 的 响 应 不 会 被 缓 存 在磁 盘 。 然 而 , 它 们 仍 然 是 代 理 方 式 的 。 在 该 指 令 后 的 逻 辑 是 , 你 不 想 某 个 非 常 大 的 响 应 来 浪 费 空间 , 这 些 空 间 能 被 许 多 小 响 应 更 好 的 利 用 。 该 语 法 如 下 :maximum_object_size size-specification如 下 是 一 些 示 例 :maximum_object_size 100 KB


maximum_object_size 1 MBmaximum_object_size 12382 bytesmaximum_object_size 2 GB<strong>Squid</strong> 以 两 个 不 同 的 方 法 来 检 查 响 应 大 小 。 假 如 响 应 包 含 了 Content-Length 头 部 ,squid 将这 个 值 与 maximum_object_size 值 进 行 比 较 。 假 如 前 者 大 于 后 者 , 该 对 象 立 刻 不 可 缓 存 , 并且 不 会 消 耗 任 何 磁 盘 空 间 。不 幸 的 是 , 并 非 每 个 响 应 都 有 Content-Length 头 部 。 在 这 样 的 情 形 下 ,squid 将 响 应 写 往 磁盘 , 把 它 当 作 来 自 原 始 服 务 器 的 数 据 。 在 响 应 完 成 后 ,squid 再 检 查 对 象 大 小 。 这 样 , 假 如 对 象的 大 小 达 到 maximum_object_size 限 制 , 它 继 续 消 耗 磁 盘 空 间 。 仅 仅 当 squid 在 做 读 取 响应 的 动 作 时 , 总 共 cache 大 小 才 会 增 大 。换 句 话 说 , 活 动 的 , 或 者 传 输 中 的 目 标 , 不 会 对 squid 内 在 的 cache 大 小 值 有 影 响 。 这 点 有 好处 , 因 为 它 意 味 着 squid 不 会 删 除 cache 里 的 其 他 目 标 , 除 非 目 标 不 可 缓 存 , 并 对 总 共 cache大 小 有 影 响 。 然 而 , 这 点 也 有 坏 处 , 假 如 响 应 非 常 大 ,squid 可 能 运 行 超 出 了 磁 盘 自 由 空 间 。 为了 减 少 发 生 这 种 情 况 的 机 会 , 你 应 该 使 用 reply_body_max_size 指 令 。 某 个 达 到reply_body_max_size 限 制 的 响 应 立 即 被 删 除 。<strong>Squid</strong> 也 有 一 个 minimum_object_size 指 令 。 它 允 许 你 对 缓 存 对 象 的 大 小 设 置 最 低 限 制 。 比这 个 值 更 小 的 响 应 不 会 被 缓 存 在 磁 盘 或 内 存 里 。 注 意 这 个 大 小 是 与 响 应 的 内 容 长 度 ( 例 如 , 响 应body 大 小 ) 进 行 比 较 , 后 者 包 含 在 HTTP 头 部 里 。7.4 分 配 对 象 到 缓 存 目 录当 squid 想 将 某 个 可 缓 存 的 响 应 存 储 到 磁 盘 时 , 它 调 用 一 个 函 数 , 用 以 选 择 cache 目 录 。 然 后它 在 选 择 的 目 录 里 打 开 一 个 磁 盘 文 件 用 于 写 。 假 如 因 为 某 些 理 由 ,open() 调 用 失 败 , 响 应 不 会被 存 储 。 在 这 样 的 情 况 下 ,squid 不 会 试 图 在 其 他 cache 目 录 里 打 开 另 一 个 磁 盘 文 件 。<strong>Squid</strong> 有 2 个 cache_dir 选 择 算 法 。 默 认 的 算 法 叫 做 lease-load; 替 代 的 算 法 是 round-robin。least-load 算 法 , 就 如 其 名 字 的 意 义 一 样 , 它 选 择 当 前 工 作 负 载 最 小 的 cache 目 录 。 负 载 概 念依 赖 于 存 储 机 制 。 对 aufs,coss 和 diskd 机 制 来 说 , 负 载 与 挂 起 操 作 的 数 量 有 关 。 对 ufs 来 说 ,负 载 是 不 变 的 。 在 cache_dir 负 载 相 等 的 情 况 下 , 该 算 法 使 用 自 由 空 间 和 最 大 目 标 大 小 作 为 附加 选 择 条 件 。该 选 择 算 法 也 取 决 于 max-size 和 read-only 选 项 。 假 如 squid 知 道 目 标 大 小 超 出 了 限 制 , 它会 跳 过 这 个 cache 目 录 。 它 也 会 跳 过 任 何 只 读 目 录 。round-robin 算 法 也 使 用 负 载 作 为 衡 量 标 准 。 它 选 择 某 个 负 载 小 于 100% 的 cache 目 录 , 当 然 ,该 目 录 里 的 存 储 目 标 没 有 超 出 大 小 限 制 , 并 且 不 是 只 读 的 。在 某 些 情 况 下 ,squid 可 能 选 择 cache 目 录 失 败 。 假 如 所 有 的 cache_dir 是 满 负 载 , 或 者 所 有


目 录 的 实 际 目 标 大 小 超 出 了 max-size 限 制 , 那 么 这 种 情 况 可 能 发 生 。 这 时 ,squid 不 会 将 目 标写 往 磁 盘 。 你 可 以 使 用 cache 管 理 器 来 跟 踪 squid 选 择 cache 目 录 失 败 的 次 数 。 请 见 store_io页 (14.2.1.41 章 ), 找 到 create.select_fail 行 。7.5 置 换 策 略cache_replacement_policy 指 令 控 制 了 squid 的 磁 盘 cache 的 置 换 策 略 。<strong>Squid</strong>2.5 版 本 提供 了 三 种 不 同 的 置 换 策 略 : 最 少 近 来 使 用 (LRU), 贪 婪 对 偶 大 小 次 数 (GDSF), 和 动 态 衰 老 最少 经 常 使 用 (LFUDA)。LRU 是 默 认 的 策 略 , 并 非 对 squid, 对 其 他 大 部 分 cache 产 品 都 是 这 样 。LRU 是 流 行 的 选 择 ,因 为 它 容 易 执 行 , 并 提 供 了 非 常 好 的 性 能 。 在 32 位 系 统 上 ,LRU 相 对 于 其 他 使 用 更 少 的 内 存 ( 每目 标 12 对 16 字 节 )。 在 64 位 系 统 上 , 所 有 的 策 略 每 目 标 使 用 24 字 节 。在 过 去 , 许 多 研 究 者 已 经 提 议 选 择 LRU。 其 他 策 略 典 型 的 被 设 计 来 改 善 cache 的 其 他 特 性 , 例如 响 应 时 间 , 命 中 率 , 或 字 节 命 中 率 。 然 而 研 究 者 的 改 进 结 果 也 可 能 在 误 导 人 。 某 些 研 究 使 用 并不 现 实 的 小 cache 目 标 ; 其 他 研 究 显 示 当 cache 大 小 增 加 时 , 置 换 策 略 的 选 择 变 得 不 那 么 重 要 。假 如 你 想 使 用 GDSF 或 LFUDA 策 略 , 你 必 须 在 ./configure 时 使 用 --enable-removalpolicies选 项 ( 见 3.4.1 章 )。Martin Arlitt 和 HP 实 验 室 的 John Dilley 为 squid 写 了 GDSF和 LFUDA 算 法 。 你 可 以 在 线 阅 读 他 们 的 文 档 :http://www.hpl.hp.com/techreports/1999/HPL-1999-69.html我 在 O'Reilly 出 版 的 书 "Web Caching", 也 讨 论 了 这 些 算 法 。cache_replacement_policy 指 令 的 值 是 唯 一 的 , 这 点 很 重 要 。 不 象 squid.conf 里 的 大 部 分其 他 指 令 , 这 个 指 令 的 位 置 很 重 要 。cache_replacement_policy 指 令 的 值 在 squid 解 析cache_dir 指 令 时 , 被 实 际 用 到 。 通 过 预 先 设 置 替 换 策 略 , 你 可 以 改 变 cache_dir 的 替 换 策 略 。例 如 :cache_replacement_policy lrucache_dir ufs /cache0 2000 16 32cache_dir ufs /cache1 2000 16 32cache_replacement_policy heap GDSFcache_dir ufs /cache2 2000 16 32cache_dir ufs /cache3 2000 16 32在 该 情 形 中 , 头 2 个 cache 目 录 使 用 LRU 置 换 策 略 , 接 下 来 2 个 cache 目 录 使 用 GDSF。 请记 住 , 假 如 你 已 决 定 使 用 cache 管 理 器 的 config 选 项 ( 见 14.2.1.7 章 ), 这 个 置 换 策 略 指 令的 特 性 就 非 常 重 要 。cache 管 理 器 仅 仅 输 出 最 后 一 个 置 换 策 略 的 值 , 将 它 置 于 所 有 的 cache 目录 之 前 。 例 如 , 你 可 能 在 squid.conf 里 有 如 下 行 :cache_replacement_policy heap GDSFcache_dir ufs /tmp/cache1 10 4 4


cache_replacement_policy lrucache_dir ufs /tmp/cache2 10 4 4但 当 你 从 cache 管 理 器 选 择 config 时 , 你 得 到 :cache_replacement_policy lrucache_dir ufs /tmp/cache1 10 4 4cache_dir ufs /tmp/cache2 10 4 4就 象 你 看 到 的 一 样 , 对 头 2 个 cache 目 录 的 heap GDSF 设 置 被 丢 失 了 。7.6 删 除 缓 存 对 象在 某 些 情 况 下 , 你 必 须 从 squid 的 cache 里 手 工 删 除 一 个 或 多 个 对 象 。 这 些 情 况 可 能 包 括 :+ 你 的 用 户 抱 怨 总 接 收 到 过 时 的 数 据 ;+ 你 的 cache 因 为 某 个 响 应 而 “ 中 毒 ”;+ <strong>Squid</strong> 的 cache 索 引 在 经 历 磁 盘 I/O 错 误 或 频 繁 的 crash 和 重 启 后 , 变 得 有 问 题 ;+ 你 想 删 除 一 些 大 目 标 来 释 放 空 间 给 新 的 数 据 ;+ <strong>Squid</strong> 总 从 本 地 服 务 器 中 cache 响 应 , 现 在 你 不 想 它 这 样 做 。上 述 问 题 中 的 一 些 可 以 通 过 强 迫 web 浏 览 器 reload 来 解 决 。 然 而 , 这 并 非 总 是 可 靠 。 例 如 ,一 些 浏 览 器 通 过 载 入 另 外 的 程 序 , 从 而 显 示 某 些 类 容 类 型 ; 那 个 程 序 可 能 没 有 reload 按 钮 , 或甚 至 它 了 解 cache 的 情 况 。假 如 必 要 , 你 总 可 以 使 用 squidclient 程 序 来 reload 缓 存 目 标 。 简 单 的 在 uri 前 面 使 用 -r 选 项 :% squidclient -r http://www.lrrr.org/junk >;/tmp/foo假 如 你 碰 巧 在 refresh_pattern 指 令 里 设 置 了 ignore-reload 选 项 , 你 和 你 的 用 户 将 不 能 强 迫缓 存 响 应 更 新 。 在 这 样 的 情 形 下 , 你 最 好 清 除 这 些 有 错 误 的 缓 存 对 象 。7.6.1 删 除 个 别 对 象<strong>Squid</strong> 接 受 一 种 客 户 请 求 方 式 , 用 于 删 除 cache 对 象 。PURGE 方 式 并 非 官 方 HTTP 请 求 方 式之 一 。 它 与 DELETE 不 同 , 对 后 者 ,squid 将 其 转 发 到 原 始 服 务 器 。PURGE 请 求 要 求 squid删 除 在 uri 里 提 交 的 目 标 。squid 返 回 200(OK) 或 404(Not Found)。PURGE 方 式 某 种 程 度 上 有 点 危 险 , 因 为 它 删 除 了 cache 目 标 。 除 非 你 定 义 了 相 应 的 ACL, 否则 squid 禁 止 PURGE 方 式 。 正 常 的 , 你 仅 仅 允 许 来 自 本 机 和 少 数 可 信 任 主 机 的 PURGE 请 求 。配 置 看 起 来 如 下 :acl AdminBoxes src 127.0.0.1 172.16.0.1 192.168.0.1acl Purge method PURGEhttp_access allow AdminBoxes Purge


http_access deny Purgesquidclient 程 序 提 供 了 产 生 PURGE 请 求 的 容 易 方 法 , 如 下 :% squidclient -m PURGE http://www.lrrr.org/junk代 替 的 , 你 可 以 使 用 其 他 工 具 ( 例 如 perl 脚 本 ) 来 产 生 你 自 己 的 HTTP 请 求 。 它 非 常 简 单 :PURGE http://www.lrrr.org/junk HTTP/1.0Accept: */*注 意 某 个 单 独 的 URI 不 唯 一 标 明 一 个 缓 存 响 应 。<strong>Squid</strong> 也 在 cache 关 键 字 里 使 用 原 始 请 求 方 式 。假 如 响 应 包 含 了 不 同 的 头 部 , 它 也 可 以 使 用 其 他 请 求 头 。 当 你 发 布 PURGE 请 求 时 ,<strong>Squid</strong> 使 用GET 和 HEAD 的 原 始 请 求 方 式 来 查 找 缓 存 目 标 。 而 且 ,<strong>Squid</strong> 会 删 除 响 应 里 的 所 有 variants,除 非 你 在 PURGE 请 求 的 相 应 头 部 里 指 定 了 要 删 除 的 variants。<strong>Squid</strong> 仅 仅 删 除 GET 和 HEAD请 求 的 variants。7.6.2 删 除 一 组 对 象不 幸 的 是 ,<strong>Squid</strong> 没 有 提 供 一 个 好 的 机 制 , 用 以 立 刻 删 除 一 组 对 象 。 这 种 要 求 通 常 出 现 在 某 人想 删 除 所 有 属 于 同 一 台 原 始 服 务 器 的 对 象 时 。因 为 很 多 理 由 ,squid 不 提 供 这 种 功 能 。 首 先 ,squid 必 须 遍 历 所 有 缓 存 对 象 , 执 行 线 性 搜 索 ,这 很 耗 费 CPU, 并 且 耗 时 较 长 。 当 squid 在 搜 索 时 , 用 户 会 面 临 性 能 下 降 问 题 。 第 二 ,squid在 内 存 里 对 URI 保 持 MD5 算 法 ,MD5 是 单 向 哈 希 , 这 意 味 着 , 例 如 , 你 不 能 确 认 是 否 某 个 给定 的 MD5 哈 希 是 由 包 含 "www.example.com" 字 符 串 的 URI 产 生 而 来 。 唯 一 的 方 法 是 从 原 始URI 重 新 计 算 MD5 值 , 并 且 看 它 们 是 否 匹 配 。 因 为 squid 没 有 保 持 原 始 的 URI, 它 不 能 执 行这 个 重 计 算 。那 么 该 怎 么 办 呢 ?你 可 以 使 用 access.log 里 的 数 据 来 获 取 URI 列 表 , 它 们 可 能 位 于 cache 里 。 然 后 , 将 它 们 用于 squidclient 或 其 他 工 具 来 产 生 PURGE 请 求 , 例 如 :% awk '{print $7}' /usr/local/squid/var/logs/access.log \| grep www.example.com \| xargs -n 1 squidclient -m PURGE7.6.3 删 除 所 有 对 象在 极 度 情 形 下 , 你 可 能 需 要 删 除 整 个 cache, 或 至 少 某 个 cache 目 录 。 首 先 , 你 必 须 确 认 squid没 有 在 运 行 。让 squid 忘 记 所 有 缓 存 对 象 的 最 容 易 的 方 法 之 一 , 是 覆 盖 swap.state 文 件 。 注 意 你 不 能 简 单的 删 除 swap.state 文 件 , 因 为 squid 接 着 要 扫 描 cache 目 录 和 打 开 所 有 的 目 标 文 件 。 你 也 不


efresh_pattern -i \.html$ 0 20% 1440refresh_pattern -i . 5 25% 2880regexp 参 数 是 大 小 写 敏 感 的 正 则 表 达 式 。 你 可 以 使 用 -i 选 项 来 使 它 们 大 小 写 不 敏 感 。squid 按顺 序 来 检 查 refresh_pattern 行 ; 当 正 则 表 达 式 之 一 匹 配 URI 时 , 它 停 止 搜 索 。min 参 数 是 分 钟 数 量 。 它 是 过 时 响 应 的 最 低 时 间 限 制 。 如 果 某 个 响 应 驻 留 在 cache 里 的 时 间 没有 超 过 这 个 最 低 限 制 , 那 么 它 不 会 过 期 。 类 似 的 ,max 参 数 是 存 活 响 应 的 最 高 时 间 限 制 。 如 果某 个 响 应 驻 留 在 cache 里 的 时 间 高 于 这 个 最 高 限 制 , 那 么 它 必 须 被 刷 新 。在 最 低 和 最 高 时 间 限 制 之 间 的 响 应 , 会 面 对 squid 的 最 后 修 改 系 数 (LM-factor) 算 法 。 对 这 样的 响 应 ,squid 计 算 响 应 的 年 龄 和 最 后 修 改 系 数 , 然 后 将 它 作 为 百 分 比 值 进 行 比 较 。 响 应 年 龄 简单 的 就 是 从 原 始 服 务 器 产 生 , 或 最 后 一 次 验 证 响 应 后 , 经 历 的 时 间 数 量 。 源 年 龄 在 Last-Modified和 Date 头 部 之 间 是 不 同 的 。LM-factor 是 响 应 年 龄 与 源 年 龄 的 比 率 。图 7-2 论 证 了 LM-factor 算 法 。squid 缓 存 了 某 个 目 标 3 个 小 时 ( 基 于 Date 和 Last-Modified头 部 )。LM-factor 的 值 是 50%, 响 应 在 接 下 来 的 1.5 个 小 时 里 是 存 活 的 , 在 这 之 后 , 目 标 会过 期 并 被 当 作 过 时 处 理 。 假 如 用 户 在 存 活 期 间 请 求 cache 目 标 ,squid 返 回 没 有 确 认 的 cache命 中 。 若 在 过 时 期 间 发 生 请 求 ,squid 转 发 确 认 请 求 到 原 始 服 务 器 。图 7-2 基 于 LM-factor 计 算 过 期 时 间( 略 图 )理 解 squid 检 查 不 同 值 的 顺 序 非 常 重 要 。 如 下 是 squid 的 refresh_pattern 算 法 的 简 单 描 述 :+ 假 如 响 应 年 龄 超 过 refresh_pattern 的 max 值 , 该 响 应 过 期 ;+ 假 如 LM-factor 少 于 refresh_pattern 百 分 比 值 , 该 响 应 存 活 ;+ 假 如 响 应 年 龄 少 于 refresh_pattern 的 min 值 , 该 响 应 存 活 ;+ 其 他 情 况 下 , 响 应 过 期 。refresh_pattern 指 令 也 有 少 数 选 项 导 致 squid 违 背 HTTP 协 议 规 范 。 它 们 如 下 :override-expire该 选 项 导 致 squid 在 检 查 Expires 头 部 之 前 , 先 检 查 min 值 。 这 样 , 一 个 非 零 的 min 时 间 让 squid返 回 一 个 未 确 认 的 cache 命 中 , 即 使 该 响 应 准 备 过 期 。override-lastmod改 选 项 导 致 squid 在 检 查 LM-factor 百 分 比 之 前 先 检 查 min 值 。reload-into-ims该 选 项 让 squid 在 确 认 请 求 里 , 以 no-cache 指 令 传 送 一 个 请 求 。 换 句 话 说 ,squid 在 转 发 请求 之 前 , 对 该 请 求 增 加 一 个 If-Modified-Since 头 部 。 注 意 这 点 仅 仅 在 目 标 有 Last-Modified时 间 戳 时 才 能 工 作 。 外 面 进 来 的 请 求 保 留 no-cache 指 令 , 以 便 它 到 达 原 始 服 务 器 。ignore-reload


该 选 项 导 致 squid 忽 略 请 求 里 的 任 何 no-cache 指 令 。第 8 章 高 级 磁 盘 缓 存 主 题8.1 是 否 存 在 磁 盘 I/O 瓶 颈 ?Web 缓 存 器 例 如 squid, 通 常 在 磁 盘 I/O 变 成 瓶 颈 时 , 不 会 正 确 的 体 现 和 告 知 你 。 代 替 的 是 ,随 着 负 载 的 增 加 , 响 应 时 间 和 / 或 命 中 率 会 更 低 效 。 当 然 , 响 应 时 间 和 命 中 率 可 能 因 为 其 他 原 因而 改 变 , 例 如 网 络 延 时 和 客 户 请 求 方 式 的 改 变 。也 许 探 测 cache 性 能 瓶 颈 的 最 好 方 式 是 做 压 力 测 试 , 例 如 Web Polygraph。 压 力 测 试 的 前 提是 你 能 完 全 控 制 环 境 , 消 除 未 知 因 素 。 你 可 以 用 不 同 的 cache 配 置 来 重 复 相 同 的 测 试 。 不 幸 的是 , 压 力 测 试 通 常 需 要 大 量 的 时 间 , 并 要 求 有 空 闲 的 系 统 ( 也 许 它 们 正 在 使 用 中 )。假 如 你 有 资 源 执 行 squid 压 力 测 试 , 请 以 标 准 的 cache 工 作 负 载 开 始 。 当 你 增 加 负 载 时 , 在 某些 点 上 你 能 看 到 明 显 的 响 应 延 时 和 / 或 命 中 率 下 降 。 一 旦 你 观 察 到 这 样 的 性 能 降 低 , 就 禁 止 掉 磁盘 缓 存 , 再 测 试 一 次 。 你 可 以 配 置 squid 从 来 不 缓 存 任 何 响 应 ( 使 用 null 存 储 机 制 , 见 8.7 章 )。代 替 的 , 你 能 配 置 工 作 负 载 到 100% 不 可 cache 响 应 。 假 如 不 使 用 cache 时 , 平 均 响 应 时 间 明显 更 好 , 那 么 可 以 确 认 磁 盘 I/O 是 该 水 平 吞 吐 量 的 瓶 颈 。假 如 你 没 有 时 间 或 没 有 资 源 来 执 行 squid 压 力 测 试 , 那 么 可 检 查 squid 的 运 行 时 统 计 来 查 找 磁盘 I/O 瓶 颈 。cache 管 理 器 的 General Runtime Information 页 面 ( 见 14 章 ) 会 显 示 出 cache命 中 和 cache 丢 失 的 中 值 响 应 时 间 。Median Service Times (seconds) 5 min 60 min:HTTP Requests (All): 0.39928 0.35832Cache Misses: 0.42149 0.39928Cache Hits: 0.12783 0.11465Near Hits: 0.37825 0.39928Not-Modified Replies: 0.07825 0.07409对 健 壮 的 squid 缓 存 来 说 , 命 中 显 然 快 于 丢 失 。 中 值 命 中 响 应 时 间 典 型 的 少 于 0.5 秒 或 更 少 。我 强 烈 建 议 你 使 用 SNMP 或 其 他 的 网 络 监 视 工 具 来 从 squid 缓 存 采 集 定 期 测 量 值 。 如 果 平 均 命中 响 应 时 间 增 加 得 太 明 显 , 意 味 着 系 统 有 磁 盘 I/0 瓶 颈 。假 如 你 认 为 产 品 cache 面 临 此 类 问 题 , 可 以 用 前 面 提 到 的 同 样 的 技 术 来 验 证 你 的 推 测 。 配 置squid 不 cache 任 何 响 应 , 这 样 就 避 开 了 所 有 磁 盘 I/O。 然 后 仔 细 观 察 cache 丢 失 响 应 时 间 。假 如 它 降 下 去 , 那 么 你 的 推 测 该 是 正 确 的 。一 旦 你 确 认 了 磁 盘 吞 吐 能 力 是 squid 的 性 能 瓶 颈 , 那 么 可 做 许 多 事 来 改 进 它 。 其 中 一 些 方 法 要求 重 编 译 squid, 然 而 另 一 些 相 对 较 简 单 , 只 需 调 整 Unix 文 件 系 统 。8.2 文 件 系 统 调 整 选 项


首 先 , 从 来 不 在 squid 的 缓 存 目 录 中 使 用 RAID。 以 我 的 经 验 看 ,RAID 总 是 降 低 squid 使 用 的文 件 系 统 的 性 能 。 最 好 有 许 多 独 立 的 文 件 系 统 , 每 个 文 件 系 统 使 用 单 独 的 磁 盘 驱 动 器 。我 发 现 4 个 简 单 的 方 法 来 改 进 squid 的 UFS 性 能 。 其 中 某 些 特 指 某 种 类 型 的 操 作 系 统 例 如 BSD和 Linux, 也 许 对 你 的 平 台 不 太 合 适 :1. 某 些 UFS 支 持 一 个 noatime 的 mount 选 项 。 使 用 noatime 选 项 来 mount 的 文 件 系 统 ,不 会 在 读 取 时 , 更 新 相 应 的 i 节 点 访 问 时 间 。 使 用 该 选 项 的 最 容 易 的 方 法 是 在 /etc/fstab 里 增 加如 下 行 :# Device Mountpoint FStype Options Dump Pass#/dev/ad1s1c /cache0 ufs rw,noatime 0 02. 检 查 mount( 的 manpage 里 的 async 选 项 。 设 置 了 该 选 项 , 特 定 的 I/O 操 作 ( 例 如 更 新目 录 ) 会 异 步 执 行 。 某 些 系 统 的 文 档 会 标 明 这 是 个 危 险 的 标 签 。 某 天 你 的 系 统 崩 溃 , 你 也 许 会 丢失 整 个 文 件 系 统 。 对 许 多 squid 安 装 来 说 , 执 行 性 能 的 提 高 值 得 冒 此 风 险 。 假 如 你 不 介 意 丢 失整 个 cache 内 容 , 那 么 可 以 使 用 该 选 项 。 假 如 cache 数 据 非 常 有 价 值 ,async 选 项 也 许 不 适 合你 。3.BSD 有 一 个 功 能 叫 做 软 更 新 。 软 更 新 是 BSD 用 于 Journaling 文 件 系 统 的 代 替 品 。 在 FreeBSD上 , 你 可 以 在 没 有 mount 的 文 件 系 统 中 , 使 用 tunefs 命 令 来 激 活 该 选 项 :# umount /cache0# tunefs -n enable /cache0# mount /cache04. 你 对 每 个 文 件 系 统 运 行 一 次 tunefs 命 令 就 可 以 了 。 在 系 统 重 启 时 , 软 更 新 自 动 在 文 件 系 统 中激 活 了 。在 OpenBSD 和 NetBSD 中 , 可 使 用 softdep mount 选 项 :# Device Mountpoint FStype Options Dump Pass#/dev/sd0f /usr ffs rw,softdep 1 2假 如 你 象 我 一 样 , 你 可 能 想 知 道 在 async 选 项 和 软 更 新 选 项 之 间 有 何 不 同 。 一 个 重 要 的 区 别 是 ,软 更 新 代 码 被 设 计 成 在 系 统 崩 溃 事 件 中 , 保 持 文 件 系 统 的 一 致 性 , 而 async 选 项 不 是 这 样 的 。这 也 许 让 你 推 断 async 执 行 性 能 好 于 软 更 新 。 然 而 , 如 我 在 附 录 D 中 指 出 的 , 事 实 相 反 。以 前 我 提 到 过 ,UFS 性 能 特 别 是 写 性 能 , 依 赖 于 空 闲 磁 盘 的 数 量 。 对 空 文 件 系 统 的 磁 盘 写 操 作 ,要 比 满 文 件 系 统 快 得 多 。 这 是 UFS 的 最 小 自 由 空 间 参 数 , 和 空 间 / 时 间 优 化 权 衡 参 数 背 后 的 理 由之 一 。 假 如 cache 磁 盘 满 了 ,squid 执 行 性 能 看 起 来 很 糟 , 那 么 试 着 减 少 cache_dir 的 容 量 值 ,以 便 更 多 的 自 由 空 间 可 用 。 当 然 , 减 少 cache 大 小 也 会 降 低 命 中 率 , 但 响 应 时 间 的 改 进 也 许 值得 这 么 做 。 假 如 你 给 squid 缓 存 配 置 新 的 设 备 , 请 考 虑 使 用 超 过 你 需 要 的 更 大 磁 盘 , 并 且 仅 仅使 用 空 间 的 一 半 。8.3 可 选 择 的 文 件 系 统


某 些 操 作 系 统 支 持 不 同 于 U FS( 或 ext2fs) 的 文 件 系 统 。Journaling 文 件 系 统 是 较 普 遍 的 选 择 。在 UFS 和 Journaling 文 件 系 统 之 间 的 主 要 不 同 在 于 它 们 处 理 更 新 的 方 式 。 在 UFS 下 , 更 新 是实 时 的 。 例 如 , 当 你 改 变 了 某 个 文 件 并 且 将 它 存 储 到 磁 盘 , 新 数 据 就 替 换 了 旧 数 据 。 当 你 删 除 文件 时 ,UFS 直 接 更 新 了 目 录 。Journaling 文 件 系 统 与 之 相 反 , 它 将 更 新 写 往 独 立 的 记 帐 系 统 , 或 日 志 文 件 。 典 型 的 你 能 选 择是 否 记 录 文 件 改 变 或 元 数 据 改 变 , 或 两 者 兼 备 。 某 个 后 台 进 程 在 空 闲 时 刻 读 取 记 帐 , 并 且 执 行 实际 的 改 变 操 作 。Journaling 文 件 系 统 典 型 的 在 系 统 崩 溃 后 比 UFS 恢 复 更 快 。 在 系 统 崩 溃 后 ,Journaling 文 件 系 统 简 单 的 读 取 记 帐 , 并 且 提 交 所 有 显 著 的 改 变 。Journaling 文 件 系 统 的 主 要 弊 端 在 于 它 们 需 要 额 外 的 磁 盘 写 操 作 。 改 变 首 先 写 往 日 志 文 件 , 然后 才 写 往 实 际 的 文 件 或 目 录 。 这 对 web 缓 存 影 响 尤 其 明 显 , 因 为 首 先 web 缓 存 倾 向 于 更 多 的磁 盘 写 操 作 。Journaling 文 件 系 统 对 许 多 操 作 系 统 可 用 。 在 Linux 上 , 你 能 选 择 ext3fs,reiserfs, XFS, 和 其他 的 。XFS 也 可 用 在 SGI/IRIX, 它 原 始 是 在 这 里 开 发 的 。Solaris 用 户 能 使 用 Veritas 文 件 系统 产 品 。TRU64( 以 前 的 Digital Unix) 高 级 文 件 系 统 (advfs) 支 持 Journaling。你 可 以 不 改 变 squid 的 任 何 配 置 而 使 用 Journaling 文 件 系 统 。 简 单 的 创 建 和 挂 载 在 操 作 系 统 文档 里 描 述 的 文 件 系 统 , 而 不 必 改 变 squid.cf 配 置 文 件 里 的 cache_dir 行 。用 类 似 如 下 命 令 在 Linux 中 制 作 reiserfs 文 件 系 统 :# /sbin/mkreiserfs /dev/sda2对 XFS, 使 用 :# mkfs -t xfs -f /dev/sda2注 意 ext3fs 其 实 简 单 的 就 是 激 活 了 记 帐 的 ext2fs。 当 创 建 该 文 件 系 统 时 , 对 mke2fs 使 用 -j选 项 :# /sbin/mke2fs -j /dev/sda2请 参 考 其 他 操 作 系 统 的 相 关 文 档 。8.4 aufs 存 储 机 制aufs 存 储 机 制 已 经 发 展 到 超 出 了 改 进 squid 磁 盘 I/O 响 应 时 间 的 最 初 尝 试 。"a" 代 表 着 异 步 I/O。默 认 的 ufs 和 aufs 之 间 的 唯 一 区 别 , 在 于 I/O 是 否 被 squid 主 进 程 执 行 。 数 据 格 式 都 是 一 样 的 ,所 以 你 能 在 两 者 之 间 轻 松 选 择 , 而 不 用 丢 失 任 何 cache 数 据 。aufs 使 用 大 量 线 程 进 行 磁 盘 I/O 操 作 。 每 次 squid 需 要 读 写 , 打 开 关 闭 , 或 删 除 cache 文 件时 ,I/O 请 求 被 分 派 到 这 些 线 程 之 一 。 当 线 程 完 成 了 I/O 后 , 它 给 squid 主 进 程 发 送 信 号 , 并且 返 回 一 个 状 态 码 。 实 际 上 在 squid2.5 中 , 某 些 文 件 操 作 默 认 不 是 异 步 执 行 的 。 最 明 显 的 , 磁盘 写 总 是 同 步 执 行 。 你 可 以 修 改 src/fs/aufs/store_asyncufs.h 文 件 , 将 ASYNC_WRITE 设


为 1, 并 且 重 编 译 squid。aufs 代 码 需 要 pthreads 库 。 这 是 POSIX 定 义 的 标 准 线 程 接 口 。 尽 管 许 多 Unix 系 统 支 持pthreads 库 , 但 我 经 常 遇 到 兼 容 性 问 题 。aufs 存 储 系 统 看 起 来 仅 仅 在 Linux 和 Solaris 上 运行 良 好 。 在 其 他 操 作 系 统 上 , 尽 管 代 码 能 编 译 , 但 也 许 会 面 临 严 重 的 问 题 。为 了 使 用 aufs, 可 以 在 ./configure 时 增 加 一 个 选 项 :% ./configure --enable-storeio=aufs,ufs严 格 讲 , 你 不 必 在 storeio 模 块 列 表 中 指 定 ufs。 然 而 , 假 如 你 以 后 不 喜 欢 aufs, 那 么 就 需 要指 定 ufs, 以 便 能 重 新 使 用 稳 定 的 ufs 存 储 机 制 。假 如 愿 意 , 你 也 能 使 用 —with-aio-threads=N 选 项 。 假 如 你 忽 略 它 , squid 基 于 aufscache_dir 的 数 量 , 自 动 计 算 可 使 用 的 线 程 数 量 。 表 8-1 显 示 了 1-6 个 cache 目 录 的 默 认 线 程数 量 。Table 8-1. Default number of threads for up to six cache directoriescache_dirs Threads1 162 263 324 365 406 44将 aufs 支 持 编 译 进 squid 后 , 你 能 在 squid.conf 文 件 里 的 cache_dir 行 后 指 定 它 :cache_dir aufs /cache0 4096 16 256在 激 活 了 aufs 并 启 动 squid 后 , 请 确 认 每 件 事 仍 能 工 作 正 常 。 可 以 运 行 tail -f store.log 一 会儿 , 以 确 认 缓 存 目 标 被 交 换 到 磁 盘 。 也 可 以 运 行 tail -f cache.log 并 且 观 察 任 何 新 的 错 误 或 警告 。8.4.1 aufs 如 何 工 作<strong>Squid</strong> 通 过 调 用 pthread_create() 来 创 建 大 量 的 线 程 。 所 有 线 程 在 任 何 磁 盘 活 动 之 上 创 建 。 这样 , 即 使 squid 空 闲 , 你 也 能 见 到 所 有 的 线 程 。无 论 何 时 ,squid 想 执 行 某 些 磁 盘 I/O 操 作 ( 例 如 打 开 文 件 读 ), 它 分 配 一 对 数 据 结 构 , 并 将 I/O请 求 放 进 队 列 中 。 线 程 循 环 读 取 队 列 , 取 得 I/O 请 求 并 执 行 它 们 。 因 为 请 求 队 列 共 享 给 所 有 线程 ,squid 使 用 独 享 锁 来 保 证 仅 仅 一 个 线 程 能 在 给 定 时 间 内 更 新 队 列 。I/O 操 作 阻 塞 线 程 直 到 它 们 被 完 成 。 然 后 , 将 操 作 状 态 放 进 一 个 完 成 队 列 里 。 作 为 完 整 的 操 作 ,squid 主 进 程 周 期 性 的 检 查 完 成 队 列 。 请 求 磁 盘 I/O 的 模 块 被 通 知 操 作 已 完 成 , 并 获 取 结 果 。你 可 能 已 猜 想 到 ,aufs 在 多 CPU 系 统 上 优 势 更 明 显 。 唯 一 的 锁 操 作 发 生 在 请 求 和 结 果 队 列 。 然而 , 所 有 其 他 的 函 数 执 行 都 是 独 立 的 。 当 主 进 程 在 一 个 CPU 上 执 行 时 , 其 他 的 CPU 处 理 实 际


的 I/O 系 统 调 用 。8.4.2 aufs 发 行线 程 的 有 趣 特 性 是 所 有 线 程 共 享 相 同 的 资 源 , 包 括 内 存 和 文 件 描 述 符 。 例 如 , 某 个 线 程 打 开 一 个文 件 , 文 件 描 述 符 为 27, 所 有 其 他 线 程 能 以 相 同 的 文 件 描 述 符 来 访 问 该 文 件 。 可 能 你 已 知 道 ,在 初 次 管 理 squid 时 , 文 件 描 述 符 短 缺 是 较 普 遍 问 题 。Unix 内 核 典 型 的 有 两 种 文 件 描 述 符 限 制 :进 程 级 的 限 制 和 系 统 级 的 限 制 。 你 也 许 认 为 每 个 进 程 拥 有 256 个 文 件 描 述 符 足 够 了 ( 因 为 使 用线 程 ), 然 而 并 非 如 此 。 在 这 样 的 情 况 下 , 所 有 线 程 共 享 少 量 的 文 件 描 述 符 。 请 确 认 增 加 系 统 的进 程 文 件 描 述 符 限 制 到 4096 或 更 高 , 特 别 在 使 用 aufs 时 。调 整 线 程 数 量 有 点 棘 手 。 在 某 些 情 况 下 , 可 在 cache.log 里 见 到 如 下 警 告 :2003/09/29 13:42:47| squidaio_queue_request: WARNING - Disk I/Ooverloading这 意 味 着 squid 有 大 量 的 I/O 操 作 请 求 充 满 队 列 , 等 待 着 可 用 的 线 程 。 你 首 先 会 想 到 增 加 线 程数 量 , 然 而 我 建 议 , 你 该 减 少 线 程 数 量 。增 加 线 程 数 量 也 会 增 加 队 列 的 大 小 。 超 过 一 定 数 量 , 它 不 会 改 进 aufs 的 负 载 能 力 。 它 仅 仅 意 味着 更 多 的 操 作 变 成 队 列 。 太 长 的 队 列 导 致 响 应 时 间 变 长 , 这 绝 不 是 你 想 要 的 。减 少 线 程 数 量 和 队 列 大 小 , 意 味 着 squid 检 测 负 载 条 件 更 快 。 当 某 个 cache_dir 超 载 , 它 会 从选 择 算 法 里 移 除 掉 ( 见 7.4 章 )。 然 后 ,squid 选 择 其 他 的 cache_dir 或 简 单 的 不 存 储 响 应 到 磁盘 。 这 可 能 是 较 好 的 解 决 方 法 。 尽 管 命 中 率 下 降 , 响 应 时 间 却 保 持 相 对 较 低 。8.4.3 监 视 aufs 操 作Cache 管 理 器 菜 单 里 的 Async IO Counters 选 项 , 可 以 显 示 涉 及 到 aufs 的 统 计 信 息 。 它 显 示打 开 , 关 闭 , 读 写 ,stat, 和 删 除 接 受 到 的 请 求 的 数 量 。 例 如 :% squidclient mgr:squidaio_counts...ASYNC IO Counters:Operation # Requestsopen 15318822close 15318813cancel 15318813write 0read 19237139stat 0unlink 2484325check_callback 311678364queue 0


取 消 (cancel) 计 数 器 正 常 情 况 下 等 同 于 关 闭 (close) 计 数 器 。 这 是 因 为 close 函 数 总 是 调 用cancel 函 数 , 以 确 认 任 何 未 决 的 I/O 操 作 被 忽 略 。写 (write) 计 数 器 为 0, 因 为 该 版 本 的 squid 执 行 同 步 写 操 作 , 即 使 是 aufs。check_callbak 计 数 器 显 示 squid 主 进 程 对 完 成 队 列 检 查 了 多 少 次 。queue 值 显 示 当 前 请 求 队 列 的 长 度 。 正 常 情 况 下 , 队 列 长 度 少 于 线 程 数 量 的 5 倍 。 假 如 你 持 续观 察 到 队 列 长 度 大 于 这 个 值 , 说 明 squid 配 得 有 问 题 。 增 加 更 多 的 线 程 也 许 有 帮 助 , 但 仅 仅 在特 定 范 围 内 。8.5 diskd 存 储 机 制diskd(disk 守 护 进 程 的 短 称 ) 类 似 于 aufs, 磁 盘 I/O 被 外 部 进 程 来 执 行 。 不 同 于 aufs 的 是 ,diskd 不 使 用 线 程 。 代 替 的 , 它 通 过 消 息 队 列 和 共 享 内 存 来 实 现 内 部 进 程 间 通 信 。消 息 队 列 是 现 代 Unix 操 作 系 统 的 标 准 功 能 。 许 多 年 以 前 在 AT&T 的 Unix System V 的 版 本 1上 实 现 了 它 们 。 进 程 间 的 队 列 消 息 以 较 少 的 字 节 传 递 :32-40 字 节 。 每 个 diskd 进 程 使 用 一 个队 列 来 接 受 来 自 squid 的 请 求 , 并 使 用 另 一 个 队 列 来 传 回 请 求 。8.5.1 diskd 如 何 工 作<strong>Squid</strong> 对 每 个 cache_dir 创 建 一 个 diskd 进 程 。 这 不 同 于 aufs,aufs 对 所 有 的 cache_dir 使用 一 个 大 的 线 程 池 。 对 每 个 I/O 操 作 ,squid 发 送 消 息 到 相 应 的 diskd 进 程 。 当 该 操 作 完 成 后 ,diskd 进 程 返 回 一 个 状 态 消 息 给 squid。squid 和 diskd 进 程 维 护 队 列 里 的 消 息 的 顺 序 。 这 样 ,不 必 担 心 I/O 会 无 序 执 行 。对 读 和 写 操 作 ,squid 和 diskd 进 程 使 用 共 享 内 存 区 域 。 两 个 进 程 能 对 同 一 内 存 区 域 进 行 读 和写 。 例 如 , 当 squid 产 生 读 请 求 时 , 它 告 诉 diskd 进 程 在 内 存 中 何 处 放 置 数 据 。diskd 将 内 存位 置 传 递 给 read() 系 统 调 用 , 并 且 通 过 发 送 队 列 消 息 , 通 知 squid 该 过 程 完 成 了 。 然 后 squid从 共 享 内 存 区 域 访 问 最 近 的 可 读 数 据 。diskd 与 aufs 本 质 上 都 支 持 squid 的 无 阻 塞 磁 盘 I/O。 当 diskd 进 程 在 I/O 操 作 上 阻 塞 时 ,squid有 空 去 处 理 其 他 任 务 。 在 diskd 进 程 能 跟 上 负 载 情 况 下 , 这 点 确 实 工 作 良 好 。 因 为 squid 主 进程 现 在 能 够 去 做 更 多 工 作 , 当 然 它 有 可 能 会 加 大 diskd 的 负 载 。diskd 有 两 个 功 能 来 帮 助 解 决 这个 问 题 。首 先 ,squid 等 待 diskd 进 程 捕 获 是 否 队 列 超 出 了 某 种 极 限 。 默 认 值 是 64 个 排 队 消 息 。 假 如 diskd进 程 获 取 的 数 值 远 大 于 此 ,squid 会 休 眠 片 刻 , 并 等 待 diskd 完 成 一 些 未 决 操 作 。 这 本 质 上 让squid 进 入 阻 塞 I/O 模 式 。 它 也 让 更 多 的 CPU 时 间 对 diskd 进 程 可 用 。 通 过 指 定 cache_dir行 的 Q2 参 数 的 值 , 你 可 以 配 置 这 个 极 限 值 :cache_dir diskd /cache0 7000 16 256 Q2=50第 二 , 假 如 排 队 操 作 的 数 量 抵 达 了 另 一 个 极 限 ,squid 会 停 止 要 求 diskd 进 程 打 开 文 件 。 这 里


的 默 认 值 是 72 个 消 息 。 假 如 squid 想 打 开 一 个 磁 盘 文 件 读 或 写 , 但 选 中 的 cache_dir 有 太 多的 未 完 成 操 作 , 那 么 打 开 请 求 会 失 败 。 当 打 开 文 件 读 时 , 会 导 致 cache 丢 失 。 当 打 开 文 件 写 时 ,会 阻 碍 squid 存 储 cache 响 应 。 这 两 种 情 况 下 用 户 仍 能 接 受 到 有 效 响 应 。 唯 一 实 际 的 影 响 是squid 的 命 中 率 下 降 。 这 个 极 限 用 Q1 参 数 来 配 置 :cache_dir diskd /cache0 7000 16 256 Q1=60 Q2=50注 意 在 某 些 版 本 的 squid 中 ,Q1 和 Q2 参 数 混 杂 在 默 认 的 配 置 文 件 里 。 最 佳 选 择 是 ,Q1 应 该大 于 Q2。8.5.2 编 译 和 配 置 diskd为 了 使 用 diskd, 你 必 须 在 运 行 ./configure 时 , 在 --enable-storeio 列 表 后 增 加 一 项 :% ./configure --enable-storeio=ufs,diskddiskd 看 起 来 是 可 移 植 的 , 既 然 共 享 内 存 和 消 息 队 列 在 现 代 Unix 系 统 上 被 广 泛 支 持 。 然 而 , 你可 能 需 要 调 整 与 这 两 者 相 关 的 内 核 限 制 。 内 核 典 型 的 有 如 下 可 用 参 数 :MSGMNB每 个 消 息 队 列 的 最 大 字 节 限 制 。 对 diskd 的 实 际 限 制 是 每 个 队 列 大 约 100 个 排 队 消 息 。squid传 送 的 消 息 是 32-40 字 节 , 依 赖 于 你 的 CPU 体 系 。 这 样 ,MSGMNB 应 该 是 4000 或 更 多 。为 安 全 起 见 , 我 推 荐 设 置 到 8192。MSGMNI整 个 系 统 的 最 大 数 量 的 消 息 队 列 。squid 对 每 个 cache_dir 使 用 两 个 队 列 。 假 如 你 有 10 个 磁 盘 ,那 就 有 20 个 队 列 。 你 也 许 该 增 加 更 多 , 因 为 其 他 应 用 程 序 也 要 使 用 消 息 队 列 。 我 推 荐 的 值 是 40。MSGGSZ消 息 片 断 的 大 小 ( 字 节 )。 大 于 该 值 的 消 息 被 分 割 成 多 个 片 断 。 我 通 常 将 这 个 值 设 为 64, 以 使diskd 消 息 不 被 分 割 成 多 个 片 断 。MSGSEG在 单 个 队 列 里 能 存 在 的 最 大 数 量 的 消 息 片 断 。squid 正 常 情 况 下 , 限 制 队 列 的 长 度 为 100 个 排队 消 息 。 记 住 , 在 64 位 系 统 中 , 假 如 你 没 有 增 加 MSGSSZ 的 值 到 64, 那 么 每 个 消 息 就 会 被分 割 成 不 止 1 个 片 断 。 为 了 安 全 起 见 , 我 推 荐 设 置 该 值 到 512。MSGTQL整 个 系 统 的 最 大 数 量 的 消 息 。 至 少 是 cache_dir 数 量 的 100 倍 。 在 10 个 cache 目 录 情 况 下 ,我 推 荐 设 置 到 2048。MSGMAX单 个 消 息 的 最 大 size。 对 <strong>Squid</strong> 来 说 ,64 字 节 足 够 了 。 然 而 , 你 系 统 中 的 其 他 应 用 程 序 可 能 要用 到 更 大 的 消 息 。 在 某 些 操 作 系 统 例 如 BSD 中 , 你 不 必 设 置 这 个 。BSD 自 动 设 置 它 为 MSGSSZ* MSGSEG。 其 他 操 作 系 统 中 , 你 也 许 需 要 改 变 这 个 参 数 的 默 认 值 , 你 可 以 设 置 它 与 MSGMNB


相 同 。SHMSEG每 个 进 程 的 最 大 数 量 的 共 享 内 存 片 断 。squid 对 每 个 cache_dir 使 用 1 个 共 享 内 存 标 签 。 我 推荐 设 置 到 16 或 更 高 。SHMMNI共 享 内 存 片 断 数 量 的 系 统 级 的 限 制 。 大 多 数 情 况 下 , 值 为 40 足 够 了 。SHMMAX单 个 共 享 内 存 片 断 的 最 大 size。 默 认 的 ,squid 对 每 个 片 断 使 用 大 约 409600 字 节 。为 安 全 起 见 , 我 推 荐 设 置 到 2MB, 或 2097152。SHMALL可 分 配 的 共 享 内 存 数 量 的 系 统 级 限 制 。 在 某 些 系 统 上 ,SHMALL 可 能 表 示 成 页 数 量 , 而 不 是 字节 数 量 。 在 10 个 cache_dir 的 系 统 上 , 设 置 该 值 到 16MB(4096 页 ) 足 够 了 , 并 有 足 够 的 保留 给 其 他 应 用 程 序 。在 BSD 上 配 置 消 息 队 列 , 增 加 下 列 选 项 到 内 核 配 置 文 件 里 :# System V message queues and tunable parametersoptions SYSVMSG # include support for message queuesoptions MSGMNB=8192 # max characters per message queueoptions MSGMNI=40 # max number of message queue identifiersoptions MSGSEG=512 # max number of message segments per queueoptions MSGSSZ=64 # size of a message segment MUST be power of2options MSGTQL=2048 # max number of messages in the systemoptions SYSVSHMoptions SHMSEG=16 # max shared mem segments per processoptions SHMMNI=32 # max shared mem segments in the systemoptions SHMMAX=2097152 # max size of a shared mem segmentoptions SHMALL=4096 # max size of all shared memory (pages)在 Linux 上 配 置 消 息 队 列 , 增 加 下 列 行 到 /etc/sysctl.conf:kernel.msgmnb=8192kernel.msgmni=40kernel.msgmax=8192kernel.shmall=2097152kernel.shmmni=32kernel.shmmax=16777216另 外 , 假 如 你 需 要 更 多 的 控 制 , 可 以 手 工 编 辑 内 核 资 源 文 件 中 的 include/linux/msg.h 和


include/linux/shm.h。在 Solaris 上 , 增 加 下 列 行 到 /etc/system, 然 后 重 启 :set msgsys:msginfo_msgmax=8192set msgsys:msginfo_msgmnb=8192set msgsys:msginfo_msgmni=40set msgsys:msginfo_msgssz=64set msgsys:msginfo_msgtql=2048set shmsys:shminfo_shmmax=2097152set shmsys:shminfo_shmmni=32set shmsys:shminfo_shmseg=16在 Digital Unix(TRU64) 上 , 可 以 增 加 相 应 行 到 BSD 风 格 的 内 核 配 置 文 件 中 , 见 前 面 所 叙 。 另外 , 你 可 使 用 sysconfig 命 令 。 首 先 , 创 建 如 下 的 ipc.stanza 文 件 :ipc:msg-max = 2048msg-mni = 40msg-tql = 2048msg-mnb = 8192shm-seg = 16shm-mni = 32shm-max = 2097152shm-max = 4096然 后 , 运 行 这 个 命 令 并 重 启 :# sysconfigdb -a -f ipc.stanza一 旦 你 在 操 作 系 统 中 配 置 了 消 息 队 列 和 共 享 内 存 , 就 可 以 在 squid.conf 里 增 加 如 下 的cache_dir 行 :cache_dir diskd /cache0 7000 16 256 Q1=72 Q2=64cache_dir diskd /cache1 7000 16 256 Q1=72 Q2=64...8.5.3 监 视 diskd监 视 diskd 运 行 的 最 好 方 法 是 使 用 cache 管 理 器 。 请 求 diskd 页 面 , 例 如 :% squidclient mgr:diskd...sent_count: 755627recv_count: 755627


max_away: 14max_shmuse: 14open_fail_queue_len: 0block_queue_len: 0OPS SUCCESS FAILopen 51534 51530 4create 67232 67232 0close 118762 118762 0unlink 56527 56526 1read 98157 98153 0write 363415 363415 0请 见 14.2.1.6 章 关 于 该 输 出 的 详 细 描 述 。8.6 coss 存 储 机 制循 环 目 标 存 储 机 制 (Cyclic Object Storage Scheme,coss) 尝 试 为 squid 定 制 一 个 新 的 文 件系 统 。 在 ufs 基 础 的 机 制 下 , 主 要 的 性 能 瓶 颈 来 自 频 繁 的 open() 和 unlink() 系 统 调 用 。 因 为 每个 cache 响 应 都 存 储 在 独 立 的 磁 盘 文 件 里 ,squid 总 是 在 打 开 , 关 闭 , 和 删 除 文 件 。与 之 相 反 的 是 ,coss 使 用 1 个 大 文 件 来 存 储 所 有 响 应 。 在 这 种 情 形 下 , 它 是 特 定 供 squid 使 用的 , 小 的 定 制 文 件 系 统 。coss 实 现 许 多 底 层 文 件 系 统 的 正 常 功 能 , 例 如 给 新 数 据 分 配 空 间 , 记忆 何 处 有 自 由 空 间 等 。不 幸 的 是 ,coss 仍 没 开 发 完 善 。coss 的 开 发 在 过 去 数 年 里 进 展 缓 慢 。 虽 然 如 此 , 基 于 有 人 喜 欢冒 险 的 事 实 , 我 还 是 在 这 里 描 述 它 。8.6.1 coss 如 何 工 作在 磁 盘 上 , 每 个 coss cache_dir 是 一 个 大 文 件 。 文 件 大 小 一 直 增 加 , 直 到 抵 达 它 的 大 小 上 限 。这 样 ,squid 从 文 件 的 开 头 处 开 始 , 覆 盖 掉 任 何 存 储 在 这 里 的 数 据 。 然 后 , 新 的 目 标 总 是 存 储 在该 文 件 的 末 尾 处 。squid 实 际 上 并 不 立 刻 写 新 的 目 标 数 据 到 磁 盘 上 。 代 替 的 , 数 据 被 拷 贝 进 1MB 的 内 存 缓 冲 区 ,叫 做 stripe。 在 stripe 变 满 后 , 它 被 写 往 磁 盘 。coss 使 用 异 步 写 操 作 , 以 便 squid 主 进 程 不 会在 磁 盘 I/O 上 阻 塞 。象 其 他 文 件 系 统 一 样 ,coss 也 使 用 块 大 小 概 念 。 在 7.1.4 章 里 , 我 谈 到 了 文 件 号 码 。 每 个 cache目 标 有 一 个 文 件 号 码 , 以 便 squid 用 于 定 位 磁 盘 中 的 数 据 。 对 coss 来 说 , 文 件 号 码 与 块 号 码 一样 。 例 如 , 某 个 cache 目 标 , 其 交 换 文 件 号 码 等 于 112, 那 它 在 coss 文 件 系 统 中 就 从 第 112块 开 始 。 因 此 coss 不 分 配 文 件 号 码 。 某 些 文 件 号 码 不 可 用 , 因 为 cache 目 标 通 常 在 coss 文 件


里 占 用 了 不 止 一 个 块 。coss 块 大 小 在 cache_dir 选 项 中 配 置 。 因 为 squid 的 文 件 号 码 仅 仅 24 位 , 块 大 小 决 定 了 coss缓 存 目 录 的 最 大 size:size = 块 大 小 x (2 的 24 次 方 )。 例 如 , 对 512 字 节 的 块 大 小 , 你 能在 coss cache_dir 中 存 储 8GB 数 据 。coss 不 执 行 任 何 squid 正 常 的 cache 置 换 算 法 ( 见 7.5 章 )。 代 替 的 ,cache 命 中 被 " 移 动 " 到循 环 文 件 的 末 尾 。 这 本 质 上 是 LRU 算 法 。 不 幸 的 是 , 它 确 实 意 味 着 cache 命 中 导 致 磁 盘 写 操 作 ,虽 然 是 间 接 的 。在 coss 中 , 没 必 要 去 删 除 cache 目 标 。squid 简 单 的 忘 记 无 用 目 标 所 分 配 的 空 间 。 当 循 环 文 件的 终 点 再 次 抵 达 该 空 间 时 , 它 就 被 重 新 利 用 。8.6.2 编 译 和 配 置 coss为 了 使 用 coss, 你 必 须 在 运 行 ./configure 时 , 在 --enable-storeio 列 表 里 增 加 它 :% ./configure --enable-storeio=ufs,coss ...coss 缓 存 目 录 要 求 max-size 选 项 。 它 的 值 必 须 少 于 stripe 大 小 ( 默 认 1MB, 但 可 以 用 --enable-coss-membuf-size 选 项 来 配 置 )。 也 请 注 意 你 必 须 忽 略 L1 和 L2 的 值 , 它 们 被 ufs基 础 的 文 件 系 统 使 用 。 如 下 是 示 例 :cache_dir coss /cache0/coss 7000 max-size=1000000cache_dir coss /cache1/coss 7000 max-size=1000000cache_dir coss /cache2/coss 7000 max-size=1000000cache_dir coss /cache3/coss 7000 max-size=1000000cache_dir coss /cache4/coss 7000 max-size=1000000甚 至 , 你 可 以 使 用 block-size 选 项 来 改 变 默 认 的 coss 块 大 小 。cache_dir coss /cache0/coss 30000 max-size=1000000 block-size=2048关 于 coss 的 棘 手 的 事 情 是 ,cache_dir 目 录 参 数 ( 例 如 /cache0/coss) 实 际 上 不 是 目 录 , 它是 squid 打 开 或 创 建 的 常 规 文 件 。 所 以 你 可 以 用 裸 设 备 作 为 coss 文 件 。 假 如 你 错 误 的 创 建 coss文 件 作 为 目 录 , 你 可 以 在 squid 启 动 时 见 到 如 下 错 误 :2003/09/29 18:51:42| /usr/local/squid/var/cache: (21) Is a directoryFATAL: storeCossDirInit: Failed to open a coss file.因 为 cache_dir 参 数 不 是 目 录 , 你 必 须 使 用 cache_swap_log 指 令 ( 见 13.6 章 )。 否 则 squid试 图 在 cache_dir 目 录 中 创 建 swap.state 文 件 。 在 该 情 形 下 , 你 可 以 见 到 这 样 的 错 误 :2003/09/29 18:53:38| /usr/local/squid/var/cache/coss/swap.state:(2) No such file or directory


FATAL: storeCossDirOpenSwapLog: Failed to open swap log.coss 使 用 异 步 I/O 以 实 现 更 好 的 性 能 。 实 际 上 , 它 使 用 aio_read() 和 aio_write() 系 统 调 用 。这 点 也 许 并 非 在 所 有 操 作 系 统 中 可 用 。 当 前 它 们 可 用 在 FreeBSD,Solaris, 和 Linux 中 。 假 如coss 代 码 看 起 来 编 译 正 常 , 但 你 得 到 "Function not implemented" 错 误 消 息 , 那 就 必 须 在 内核 里 激 活 这 些 系 统 调 用 。 在 FreeBSD 上 , 必 须 在 内 核 配 置 文 件 中 有 如 下 选 项 :options VFS_AIO8.6.3 coss 发 行coss 还 是 实 验 性 的 功 能 。 没 有 充 分 证 实 源 代 码 在 日 常 使 用 中 的 稳 定 性 。 假 如 你 想 试 验 一 下 , 请做 好 存 储 在 coss cache_dir 中 的 资 料 丢 失 的 准 备 。 从 另 一 面 说 ,coss 的 初 步 性 能 测 试 表 现 非常 优 秀 。 示 例 请 见 附 录 D。coss 没 有 很 好 的 支 持 从 磁 盘 重 建 cache 数 据 。 当 你 重 启 squid 时 , 你 也 许 会 发 现 从 swap.state文 件 读 取 数 据 失 败 , 这 样 就 丢 失 了 所 有 的 缓 存 数 据 。 甚 至 ,squid 在 重 启 后 , 不 能 记 忆 它 在 循 环文 件 里 的 位 置 。 它 总 是 从 头 开 始 。coss 对 目 标 置 换 采 用 非 标 准 的 方 式 。 相 对 其 他 存 储 机 制 来 说 , 这 可 能 导 致 命 中 率 更 低 。某 些 操 作 系 统 在 单 个 文 件 大 于 2GB 时 , 会 有 问 题 。 假 如 这 样 的 事 发 生 , 你 可 以 创 建 更 多 小 的 coss区 域 。 例 如 :cache_dir coss /cache0/coss0 1900 max-size=1000000 block-size=128cache_dir coss /cache0/coss1 1900 max-size=1000000 block-size=128cache_dir coss /cache0/coss2 1900 max-size=1000000 block-size=128cache_dir coss /cache0/coss3 1900 max-size=1000000 block-size=128使 用 裸 磁 盘 设 备 ( 例 如 /dev/da0s1c) 也 不 会 工 作 得 很 好 。 理 由 之 一 是 磁 盘 设 备 通 常 要 求 I/O发 生 在 512 个 字 节 的 块 边 界 ( 译 者 注 : 也 就 是 块 设 备 访 问 )。 另 外 直 接 的 磁 盘 访 问 绕 过 了 系 统 高速 缓 存 , 可 能 会 降 低 性 能 。 然 而 , 今 天 的 许 多 磁 盘 驱 动 器 , 已 经 内 建 了 高 速 缓 存 。8.7 null 存 储 机 制<strong>Squid</strong> 有 第 5 种 存 储 机 制 叫 做 null。 就 像 名 字 暗 示 的 一 样 , 这 是 最 不 健 壮 的 机 制 。 写 往 nullcache_dir 的 文 件 实 际 上 不 被 写 往 磁 盘 。大 多 数 人 没 有 任 何 理 由 要 使 用 null 存 储 系 统 。 当 你 想 完 全 禁 止 squid 的 磁 盘 缓 存 时 ,null 才 有用 。 你 不 能 简 单 的 从 squid.conf 文 件 里 删 除 所 有 cache_dir 行 , 因 为 这 样 的 话 squid 会 增 加默 认 的 ufs cache_dir。null 存 储 系 统 有 些 时 候 在 测 试 squid, 和 压 力 测 试 时 有 用 。 既 然 文 件 系统 是 典 型 的 性 能 瓶 颈 , 使 用 null 存 储 机 制 能 获 取 基 于 当 前 硬 件 的 squid 的 性 能 上 限 。为 了 使 用 该 机 制 , 在 运 行 ./configure 时 , 你 必 须 首 先 在 --enable-storeio 列 表 里 指 定 它 :% ./configure --enable-storeio=ufs,null ...


然 后 在 squid.conf 里 创 建 cache_dir 类 型 为 null:cache_dir /tmp null也 许 看 起 来 有 点 奇 怪 , 你 必 须 指 定 目 录 给 null 存 储 机 制 。squid 使 用 目 录 名 字 作 为 cache_dir标 识 符 。 例 如 , 你 能 在 cache 管 理 器 的 输 出 里 见 到 它 。8.8 哪 种 最 适 合 我 ?<strong>Squid</strong> 的 存 储 机 制 选 择 看 起 来 有 点 混 乱 和 迷 惑 。aufs 比 diskd 更 好 ? 我 的 系 统 支 持 aufs 或 coss吗 ? 假 如 我 使 用 新 的 机 制 , 会 丢 失 数 据 吗 ? 可 否 混 合 使 用 存 储 机 制 ?首 先 , 假 如 <strong>Squid</strong> 轻 度 使 用 ( 就 是 说 每 秒 的 请 求 数 少 于 5 个 ), 默 认 的 ufs 存 储 机 制 足 够 了 。 在这 样 的 低 请 求 率 中 , 使 用 其 他 存 储 机 制 , 你 不 会 观 察 到 明 显 的 性 能 改 进 。假 如 你 想 决 定 何 种 机 制 值 得 一 试 , 那 你 的 操 作 系 统 可 能 是 个 决 定 因 素 。 例 如 ,aufs 在 Linux 和Solaris 上 运 行 良 好 , 但 看 起 来 在 其 他 系 统 中 有 问 题 。 另 外 ,coss 代 码 所 用 到 的 函 数 , 当 前 不可 用 在 某 些 操 作 系 统 中 ( 例 如 NetBSD)。从 我 的 观 点 看 来 , 高 性 能 的 存 储 机 制 在 系 统 崩 溃 事 件 中 , 更 易 受 数 据 丢 失 的 影 响 。 这 就 是 追 求 最好 性 能 的 权 衡 点 。 然 而 对 大 多 数 人 来 说 ,cache 数 据 相 对 价 值 较 低 。 假 如 squid 的 缓 存 因 为 系统 崩 溃 而 破 坏 掉 , 你 会 发 现 这 很 容 易 , 只 需 简 单 的 newfs 磁 盘 分 区 , 让 cache 重 新 填 满 即 可 。如 果 你 觉 得 替 换 <strong>Squid</strong> 的 缓 存 内 容 较 困 难 或 代 价 很 大 , 你 就 应 该 使 用 低 速 的 , 但 可 信 的 文 件 系统 和 存 储 机 制 。近 期 的 <strong>Squid</strong> 允 许 你 对 每 个 cache_dir 使 用 不 同 的 文 件 系 统 和 存 储 机 制 。 然 而 实 际 上 , 这 种 做法 是 少 见 的 。 假 如 所 有 的 cache_dir 使 用 相 同 的 size 和 相 同 的 存 储 机 制 , 可 能 冲 突 更 少 。第 9 章 Cache 拦 截Cache 拦 截 是 让 传 输 流 向 <strong>Squid</strong> 的 流 行 技 术 , 它 不 用 配 置 任 何 客 户 端 。 你 可 以 配 置 路 由 器 或 交换 机 将 HTTP 连 接 转 发 到 squid 运 行 的 主 机 。squid 运 行 的 操 作 系 统 被 配 置 成 接 受 外 部 数 据 包 ,并 将 其 递 交 给 squid 进 程 。 为 了 让 HTTP 拦 截 生 效 , 你 必 须 配 置 3 个 独 立 的 因 素 : 网 络 设 备 ,squid运 行 的 操 作 系 统 , 和 squid 自 身 。;( 译 者 注 :Cache 拦 截 实 际 上 指 的 是 <strong>Squid</strong> 的 透 明 代 理 )9.1 它 如 何 工 作 ?Cache 拦 截 包 含 了 某 些 网 络 欺 骗 , 它 对 理 解 在 客 户 端 和 <strong>Squid</strong> 之 间 的 会 话 有 用 。 我 使 用 图 9-1和 如 下 的 tcpdump 示 例 输 出 , 来 解 释 当 数 据 包 通 过 网 络 时 , 如 何 被 拦 截 。


1. 用 户 代 理 (user-agent) 想 请 求 某 个 资 源 , 它 对 原 始 服 务 器 发 起 index.html 请 求 , 例 如 :www.oreilly.com。 它 需 要 原 始 服 务 器 的 IP 地 址 , 所 以 先 发 起 一 个 DNS 请 求 :Packet 1TIME: 19:54:41.317310UDP: 206.168.0.3.2459 ->; 206.168.0.2.53DATA: .d...........www.oreilly.com.....---------------------------------------------------------------------------Packet 2TIME: 19:54:41.317707 (0.000397)UDP: 206.168.0.2.53 ->; 206.168.0.3.2459DATA: .d...........www.oreilly.com.............PR.....%........PR.....$........PR...ns1.sonic.net.........PR...ns2.Q........PR...ns...M...............h.............!.z.......b......2. 现 在 有 了 IP 地 址 , 用 户 代 理 初 始 化 到 原 始 服 务 器 80 端 口 的 TCP 连 接 :Packet 3TIME: 19:54:41.320652 (0.002945)TCP: 206.168.0.3.3897 ->; 208.201.239.37.80 SynDATA: ;3. 路 由 器 或 交 换 机 注 意 到 目 的 地 址 是 80 端 口 的 TCP SYN 包 。 下 一 步 会 发 生 什 么 依 赖 于 特 定 的拦 截 技 术 。 在 4 层 交 换 和 路 由 策 略 上 , 网 络 设 备 简 单 的 将 TCP 包 转 发 到 <strong>Squid</strong> 的 数 据 链 路 地 址 。当 squid 直 接 挂 在 网 络 设 备 上 时 , 就 这 样 工 作 。 对 WCCP 来 说 , 路 由 器 封 装 TCP 包 为 GRE 包 。因 为 GRE 包 有 它 自 己 的 IP 地 址 , 它 可 能 被 通 过 多 个 子 网 进 行 路 由 。 换 句 话 说 ,WCCP 不 要 求squid 直 接 挂 在 路 由 器 上 。4.<strong>Squid</strong> 主 机 的 操 作 系 统 接 受 到 拦 截 包 。 对 4 层 交 换 来 说 ,TCP/IP 包 并 没 有 改 变 。假 如 包 使 用 了 GRE 封 装 , 主 机 会 剥 离 外 部 的 IP 和 GRE 头 部 , 并 将 原 始 的 TCP/IP 包 放 在 输 入队 列 里 。注 意 squid 主 机 接 受 到 的 包 是 针 对 外 部 地 址 的 ( 原 始 服 务 器 的 )。 正 常 情 况 下 , 这 个 包 不 匹 配 任何 本 地 地 址 , 它 会 被 丢 弃 。 为 了 让 主 机 接 受 外 部 数 据 包 , 你 必 须 在 大 多 数 操 作 系 统 上 激 活 IP 转发 。5. 客 户 端 的 TCP/IP 包 被 包 过 滤 代 码 处 理 。 数 据 包 必 须 匹 配 某 个 规 则 , 该 规 则 指 示 内 核 转 交 这 个包 给 squid。 如 果 没 有 这 样 的 规 则 , 内 核 简 单 的 将 包 按 照 它 自 己 的 方 式 转 发 给 原 始 服 务 器 , 这 不是 你 想 要 的 。注 意 SYN 包 的 目 的 端 口 是 80, 但 squid 可 能 侦 听 在 不 同 的 端 口 , 例 如 3128。 包 过 滤 规 则 允


许 你 改 变 端 口 号 。 你 不 必 让 squid 侦 听 在 80 端 口 。 通 过 tcpdump, 你 能 见 到 这 步 , 因 为 转 发的 包 不 会 再 次 通 过 网 络 接 口 代 码 。即 使 squid 侦 听 在 80 端 口 , 包 过 滤 器 的 重 定 向 规 则 仍 是 必 要 的 。 可 以 让 squid 不 在 这 些 端 口上 接 受 拦 截 包 。 重 定 向 规 则 有 点 神 奇 , 它 转 交 外 部 数 据 包 给 squid。6.<strong>Squid</strong> 接 受 到 新 连 接 的 通 知 , 它 接 受 这 个 连 接 。 内 核 发 送 SYN/ACK 包 返 回 给 客 户 端 :Packet 4TIME: 19:54:41.320735 (0.000083)TCP: 208.201.239.37.80 ->; 206.168.0.3.3897 SynAckDATA: ;就 象 你 见 到 的 一 样 , 源 地 址 是 原 始 服 务 器 , 尽 管 这 个 包 不 会 抵 达 原 始 服 务 器 。 操 作 系 统 只 是 简 单的 将 源 地 址 和 目 的 地 址 交 换 一 下 , 并 将 它 放 进 响 应 数 据 包 里 。7. 用 户 代 理 接 受 到 SYN/ACK 包 , 建 立 起 完 整 的 TCP 连 接 。 用 户 代 理 现 在 相 信 它 是 连 接 到 原 始服 务 器 , 所 以 它 发 送 HTTP 请 求 :Packet 5TIME: 19:54:41.323080 (0.002345)TCP: 206.168.0.3.3897 ->; 208.201.239.37.80 AckDATA: ;---------------------------------------------------------------------------Packet 6TIME: 19:54:41.323482 (0.000402)TCP: 206.168.0.3.3897 ->; 208.201.239.37.80 AckPshDATA: GET / HTTP/1.0User-Agent: Wget/1.8.2Host: www.oreilly.comAccept: */*Connection: Keep-Alive8.<strong>Squid</strong> 接 受 HTTP 请 求 。 它 使 用 HTTP Host 头 部 来 转 换 局 部 URL 为 完 整 的 URL。 在 这 种 情形 下 , 可 在 access.log 文 件 里 见 到 http://www.oreilly.com。9. 从 这 点 开 始 ,squid 正 常 的 处 理 请 求 。 一 般 cache 命 中 会 立 刻 返 回 。cache 丢 失 会 转 发 到 原始 服 务 器 。10. 最 后 , 是 squid 从 原 始 服 务 器 接 受 到 的 响 应 :Packet 8TIME: 19:54:41.448391 (0.030030)TCP: 208.201.239.37.80 ->; 206.168.0.3.3897 AckPsh


DATA: HTTP/1.0 200 OKDate: Mon, 29 Sep 2003 01:54:41 GMTServer: Apache/1.3.26 (Unix) PHP/4.2.1 mod_gzip/1.3.19.1a mod_perl/1.27P3P: policyref="http://www.oreillynet.com/w3c/p3p.xml",CP="CAO DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONo OURDELa PUBi OTRa IND PHY ONL UNI PUR COM NAV INT DEM CNT STA PRE"Last-Modified: Sun, 28 Sep 2003 23:54:44 GMTETag: "1b76bf-b910-3ede86c4"Accept-Ranges: bytesContent-Length: 47376Content-Type: text/htmlX-Cache: MISS from www.oreilly.comX-Cache: MISS from 10.0.0.1Connection: keep-alive不 应 该 让 交 换 机 或 路 由 器 来 拦 截 squid 到 原 始 服 务 器 的 连 接 。 假 如 这 种 情 况 发 生 ,squid 结 束与 自 己 的 会 话 , 并 且 不 能 满 足 任 何 cache 丢 失 。 防 止 这 类 转 发 死 循 环 的 最 好 方 法 是 , 确 认 用 户和 squid 连 接 到 交 换 机 或 路 由 器 的 独 立 接 口 。 无 论 何 时 , 应 该 在 指 定 接 口 上 应 用 拦 截 规 则 。 最明 显 的 , 不 该 在 squid 使 用 的 接 口 上 激 活 拦 截 。9.2 为 何 要 ( 或 不 要 ) 拦 截 ?许 多 单 位 发 现 ,cache 拦 截 很 有 用 , 因 为 他 们 不 能 , 或 不 愿 意 配 置 所 有 用 户 的 web 浏 览 器 。 相对 于 配 置 成 百 上 千 台 工 作 站 来 说 , 在 单 个 交 换 机 或 路 由 器 上 做 一 点 网 络 欺 骗 更 容 易 。 从 我 们 面 临的 许 多 选 择 来 看 ,cache 拦 截 确 实 有 好 也 有 坏 。 它 可 能 让 你 的 生 活 更 容 易 , 但 也 许 会 更 难 。Cache 拦 截 的 最 明 显 的 贡 献 是 , 所 有 HTTP 请 求 通 过 squid 自 动 离 开 你 的 网 络 。 你 不 必 担 心 配置 任 何 浏 览 器 , 用 户 可 能 在 浏 览 器 上 禁 止 他 们 的 代 理 设 置 。cache 拦 截 让 网 络 管 理 员 完 全 控 制HTTP 会 话 。 你 可 以 改 变 , 增 加 , 或 删 除 squid 的 缓 存 , 而 不 会 显 著 影 响 你 的 用 户 上 网 冲 浪 。关 于 HTTP 拦 截 的 主 要 不 利 点 就 是 该 技 术 违 背 了 TCP/IP 的 标 准 。 这 些 协 议 要 求 路 由 器 或 交 换 机转 发 TCP/IP 包 到 目 的 IP 地 址 里 指 定 的 主 机 。 然 而 转 发 包 到 cache 代 理 破 坏 了 这 些 规 则 。 代 理伪 装 身 份 接 受 转 交 过 来 的 连 接 。 用 户 代 理 被 欺 骗 了 , 以 为 它 们 在 与 真 正 的 web 服 务 器 会 话 。这 样 的 混 乱 导 致 在 老 版 本 的 Microsoft IE 浏 览 器 中 产 生 严 重 问 题 。 浏 览 器 的 Reload 按 钮 是 刷新 HTML 页 面 的 最 容 易 的 方 法 。 当 浏 览 器 被 配 置 成 使 用 cache 代 理 时 ,reload 请 求 包 含 了 一 个Cache-Control:no-cache 头 部 , 它 强 迫 产 生 cache 丢 失 ( 或 cache 确 认 ), 并 确 保 响 应 是 最近 更 新 的 。 假 如 没 有 明 确 配 置 使 用 代 理 , 浏 览 器 会 忽 略 该 头 部 。 当 使 用 cache 拦 截 时 , 浏 览 器认 为 它 在 连 接 到 原 始 服 务 器 , 因 此 没 必 要 发 送 该 头 部 。 在 这 种 情 形 下 ,squid 不 会 告 知 用 户 的Reload 按 钮 , 也 许 不 会 验 证 cache 响 应 。squid 的 ie_refresh 提 供 了 解 决 此 bug 的 局 部 解 决方 法 ( 见 附 录 A)。 Microsoft 已 经 在 其 IE 5.5 SP1 中 解 决 了 这 个 问 题 。


因 为 类 似 的 理 由 , 你 不 能 结 合 cache 拦 截 使 用 HTTP 代 理 验 证 。 因 为 客 户 端 不 知 道 这 个 代 理 ,它 不 会 发 送 必 要 的 Proxy-Authorization 头 部 。 另 外 ,407( 代 理 验 证 请 求 ) 响 应 代 码 也 不 恰当 , 因 为 响 应 看 起 来 象 来 自 原 始 服 务 器 , 原 始 服 务 器 从 来 不 会 发 送 如 此 响 应 。也 不 能 在 cache 拦 截 中 使 用 RFC 1413 ident 查 询 ( 见 6.1.2.11 章 节 )。<strong>Squid</strong> 不 能 对 必 要 的IP 地 址 建 立 新 的 TCP Socket 连 接 。 操 作 系 统 在 转 发 拦 截 连 接 到 squid 时 , 它 执 行 欺 骗 。 然 后 ,当 squid 希 望 bind 新 的 TCP Socket 到 外 部 IP 地 址 时 , 它 不 能 执 行 欺 骗 。 它 想 bind 的 地 址实 际 上 并 非 真 正 本 地 的 , 所 以 bind 系 统 调 用 失 败 。cache 拦 截 也 与 设 计 成 阻 止 地 址 欺 骗 的 IP 过 滤 冲 突 ( 见 RFC 2267:Network IngressFiltering: Defeating Denial of Service Attacks Which Employ IP SourceAddressSpoofing)。 考 虑 如 图 9-2 显 示 的 网 络 。 路 由 器 有 2 个 LAN 接 口 :lan0 和 lan1。 网 络管 理 员 在 路 由 器 上 使 用 包 过 滤 器 , 以 确 保 没 有 内 部 主 机 传 送 假 冒 源 地 址 的 数 据 包 。 路 由 器 只 会 转发 源 地 址 对 应 相 连 网 络 的 数 据 包 。 包 过 滤 规 则 也 许 看 起 来 如 下 :# lan0allow ip from 172.16.1.0/24 to any via lan0deny ip from any to any via lan0# lan1allow ip from 10.0.0.0/16 to any via lan1deny ip from any to any via lan1现 在 看 看 , 当 路 由 器 和 lan1 中 的 squid 主 机 配 置 成 拦 截 来 自 lan0 中 的 HTTP 连 接 后 , 会 发 生什 么 。<strong>Squid</strong> 装 扮 成 原 始 服 务 器 , 这 意 味 着 从 squid 到 用 户 的 响 应 TCP 包 欺 骗 了 源 地 址 。lan0过 滤 规 则 导 致 路 由 器 拒 绝 这 些 包 。 为 了 让 cache 拦 截 生 效 , 网 络 管 理 员 须 移 除 lan0 规 则 。 这 样就 让 网 络 有 漏 洞 , 从 而 易 遭 拒 绝 服 务 攻 击 。我 在 先 前 的 章 节 里 描 述 过 , 客 户 端 在 打 开 连 接 之 前 必 须 先 进 行 DNS 查 询 。 在 某 些 防 火 墙 环 境 中 ,这 样 做 可 能 有 问 题 。 你 想 进 行 HTTP 拦 截 的 主 机 必 须 能 够 查 询 DNS。 如 果 客 户 端 了 解 自 己 正 使用 代 理 ( 因 为 手 工 配 置 或 代 理 自 动 配 置 ), 它 通 常 就 不 去 解 析 主 机 名 。 代 替 的 , 它 简 单 的 将 完 整URL 转 发 给 squid, 由 squid 来 查 询 原 始 服 务 器 的 IP 地 址 。另 一 个 小 问 题 是 ,squid 接 受 任 意 目 的 IP 地 址 的 连 接 。 例 如 , 某 个 web 站 点 当 机 了 , 但 它 仍 然有 DNS 记 录 存 在 。squid 伪 装 这 个 站 点 接 受 TCP 连 接 。 客 户 端 会 认 为 该 站 点 仍 然 在 运 行 , 因 为连 接 有 效 。 当 squid 连 接 到 原 始 服 务 器 失 败 时 , 它 强 迫 返 回 错 误 消 息 。万 一 形 势 不 清 ,HTTP 拦 截 在 初 次 使 用 时 有 些 棘 手 或 困 难 。 许 多 不 同 的 组 件 必 须 组 合 工 作 , 并 且要 配 置 正 确 。 甚 至 , 从 内 存 中 恢 复 整 个 配 置 也 很 困 难 。 我 强 烈 建 议 你 在 将 其 应 用 于 生 产 环 境 之 前 ,先 建 立 测 试 环 境 。 一 旦 你 让 它 正 常 运 行 , 请 记 录 每 一 步 细 节 。9.3 网 络 设 备


现 在 你 了 解 了 cache 拦 截 的 相 关 细 节 , 让 我 们 看 看 如 何 实 际 让 它 工 作 。 我 们 先 配 置 网 络 设 备 ,它 们 用 来 拦 截 HTTP 连 接 。9.3.1 内 置 <strong>Squid</strong>在 该 配 置 中 , 你 无 需 交 换 或 网 络 路 由 设 备 来 拦 截 HTTP 连 接 。 代 替 的 ,squid 运 行 的 Unix 系 统 ,也 就 是 路 由 器 ( 或 网 桥 ), 请 见 图 9-2。;该 配 置 本 质 上 跳 过 了 9.1 章 的 头 三 步 。squid 主 机 充 当 网 络 路 由 器 , 它 接 受 HTTP 连 接 包 。 假如 你 采 用 此 方 法 , 请 直 接 跳 到 9.4 章 。9.3.2 四 层 交 换许 多 单 位 使 用 四 层 交 换 机 来 支 持 HTTP 拦 截 。 这 些 产 品 提 供 更 多 的 功 能 , 例 如 健 壮 性 检 测 和 负载 均 衡 。 我 在 这 里 仅 仅 讲 讲 拦 截 。 关 于 健 壮 性 检 测 和 负 载 均 衡 的 信 息 , 请 见 O'Reilly's ServerLoad Balancing and Load Balancing Servers, Firewalls, and Caches (John Wiley &Sons). 下 面 的 章 节 包 含 了 许 多 产 品 和 技 术 的 示 例 配 置 。9.3.2.1 Alteon/Nortel下 面 的 配 置 来 自 ACEswitch 180 和 Alteon's WebOS 8.0.21。 网 络 设 置 请 见 图 9-4。;客 户 端 连 接 到 端 口 1, 通 过 端 口 2 连 接 到 因 特 网 ,squid 运 行 在 端 口 3。 下 面 的 行 是 交 换 机 的/cfg/dump 命 令 的 输 出 。 你 无 须 敲 入 所 有 这 些 行 。 甚 至 , 在 Alteon 的 新 版 软 件 里 , 某 些 命 令可 能 改 变 了 。 注 意 Alteon 把 这 个 功 能 叫 做 Web Cache 重 定 向 (WCR)。 如 下 是 处 理 步 骤 :1. 首 先 , 你 必 须 分 配 给 Alteon 交 换 机 一 个 IP 地 址 。 这 是 必 要 的 , 以 便 交 换 机 能 检 查 squid 的存 活 状 态 。/cfg/ip/if 1enaaddr 172.16.102.1mask 255.255.255.0broad 172.16.102.2552.Alteon 的 WCR 属 于 服 务 负 载 均 衡 (SLB) 配 置 。 所 以 , 必 须 使 用 如 下 命 令 在 交 换 机 上 激 活 SLB功 能 :


cfg/slbon3. 现 在 , 用 squid 的 IP 地 址 定 义 real server:/cfg/slb/real 1enarip 172.16.102.664. 必 须 定 义 一 个 组 , 并 分 配 给 real server 一 个 组 号 :/cfg/slb/group 1health tcpadd 15. 下 一 步 定 义 2 个 过 滤 规 则 。 第 1 条 规 则 匹 配 HTTP 连 接 ( 目 的 端 口 是 80 的 TCP 包 ),并 重 定 向 它 们 到 组 1 里 的 server。 第 2 条 规 则 匹 配 所 有 其 他 数 据 包 , 并 正 常 转 发 它 们 。/cfg/slb/filt 1enaaction redirsip anysmask 0.0.0.0dip anydmask 0.0.0.0proto tcpsport anydport httpgroup 1rport 0/cfg/slb/filt 224enaaction allowsip anysmask 0.0.0.0dip anydmask 0.0.0.0proto any6. 最 后 一 步 是 给 SLB 配 置 指 定 的 交 换 端 口 。 在 端 口 1 上 , 处 理 客 户 端 连 接 ( 这 也 是 客 户端 连 接 的 端 口 ), 并 增 加 2 条 过 滤 规 则 。 在 端 口 2 上 , 仅 须 配 置 它 正 常 服 务 ( 例 如 , 向 上 连 接 到Internet):


cfg/slb/port 1client enafilt enaadd 1add 224/cfg/slb/port 2server ena为 了 验 证 HTTP 拦 截 配 置 正 确 并 工 作 良 好 , 你 可 以 使 用 /stats/slb 和 /info/slb 菜 单 里 的 命 令 。/info/slb/dump 是 快 速 有 效 的 查 看 整 个 SLB 配 置 的 方 法 :>;>; Main# /info/slb/dumpReal server state:1: 172.16.102.66, 00:c0:4f:23:d7:05, vlan 1, port 3, health 3, upVirtual server state:Redirect filter state:1: dport http, rport 0, group 1, health tcp, backup nonereal servers:1: 172.16.102.66, backup none, upPort state:1: 0.0.0.0, clientfilt enabled, filters: 1 2242: 0.0.0.0, serverfilt disabled, filters: empty3: 0.0.0.0filt disabled, filters: empty在 该 输 出 里 , 注 意 到 交 换 机 显 示 <strong>Squid</strong> 在 端 口 3 上 可 到 达 , 并 且 运 行 正 常 。 你 也 能 见 到 过 滤 规则 1 应 用 到 端 口 1。 在 端 口 状 态 节 里 , 端 口 1 定 义 为 客 户 端 连 接 端 口 , 端 口 2 简 单 的 标 记 为 服务 端 口 。/stats/slb/real 命 令 显 示 real server(squid) 的 有 用 统 计 :>;>; Main# /stats/slb/real 1------------------------------------------------------------------Real server 1 stats:Health check failures: 0Current sessions: 41


Total sessions: 760Highest sessions: 55Octets: 0大 部 分 统 计 与 任 务 ( 例 如 TCP 连 接 ) 数 量 相 关 。 假 如 再 次 运 行 该 命 令 , 总 共 的 任 务 计 数 会 增 加 。最 后 ,/stats/slb/group 命 令 显 示 几 乎 同 样 的 信 息 :>;>; Main# /stats/slb/group 1------------------------------------------------------------------Real server group 1 stats:Current Total HighestReal IP address Sessions Sessions Sessions Octets---- --------------- -------- ---------- -------- ---------------1 172.16.102.66 65 2004 90 0---- --------------- -------- ---------- -------- ---------------65 2004 90 0假 如 不 止 1 个 real server 在 组 里 , 该 输 出 会 更 有 趣 。9.3.2.2 Foundry下 面 的 配 置 示 例 来 自 ServerIron XL, 运 行 的 软 件 版 本 是 07.0.07T12。 跟 前 面 一 样 , 客 户 端在 端 口 1,Internet 连 接 在 端 口 2,squid 运 行 在 端 口 3。 然 而 , 这 样 的 配 置 少 了 点 东 西 , 因 为这 里 可 以 激 活 HTTP 全 局 拦 截 。Foundry 的 cache 拦 截 的 名 字 叫 做 Transparent CacheSwitching(TCS)。 请 参 考 图 9-4。;首 先 请 给 交 换 机 分 配 1 个 IP 地 址 , 以 便 执 行 健 壮 性 检 测 :ip address 172.16.102.1 255.255.255.0Foundry 允 许 你 在 特 定 端 口 上 激 活 或 禁 用 TCS。 然 而 简 单 起 见 , 这 里 全 局 激 活 它 :ip policy 1 cache tcp http global在 该 行 里 ,cache 是 针 对 TCS 功 能 的 关 键 字 。 下 1 行 定 义 web cache, 我 定 义 其 名 字 为 squid1,并 且 告 诉 交 换 机 它 的 IP 地 址 :server cache-name squid1 172.16.102.66最 后 的 步 骤 是 将 web cache 加 进 cache 组 里 :server cache-group 1cache-name squid1


假 如 在 转 发 连 接 时 有 问 题 , 请 参 阅 show cache-group 命 令 的 输 出 :ServerIron#show cache-groupCache-group 1 has 1 members Admin-status = Enabled Active = 0Hash_info: Dest_mask = 255.255.255.0 Src_mask = 0.0.0.0Cache Server Namesquid1 6 3Admin-status Hash-distributionHTTP Traffic From ; to Web-CachesName: squid1 IP: 172.16.102.66 State: 6 Groups = 1Host->;Web-cache Web-cache->;HostState CurConn TotConn Packets Octets Packets OctetsClient active 441 12390 188871 15976623 156962 154750098Web-Server active 193 11664 150722 151828731 175796 15853612Total 634 24054 339593 167805354 332758 170603710某 些 输 出 有 些 模 糊 , 但 通 过 重 复 该 命 令 , 并 且 观 察 计 数 器 的 增 长 , 你 能 了 解 拦 截 是 否 在 进 行 。show server real 提 供 几 乎 同 样 的 信 息 :ServerIron#show server real squid1Real Servers InfoName : squid1Mac-addr: 00c0.4f23.d705IP:172.16.102.66 Range:1 State:Active Wt:1 Max-conn:1000000Src-nat (cfg p) off ff) Dest-nat (cfg p) off ff)squid1 is a TRANSPARENT CACHE in groups 1Remote server : No Dynamic : No Server-resets:0Mem:server: 02009eae Mem:mac: 045a3714Port State Ms CurConn TotConn Rx-pkts Tx-pkts Rx-octet Tx-octet Reas---- ----- -- ------- ------- ------- ------- -------- -------- ----


http active 0 855 29557 379793 471713 373508204 39425322 0default active 0 627 28335 425106 366016 38408994 368496301 0Server Total 1482 57892 804899 837729 411917198 407921623 0最 后 , 使 用 show logging 命 令 来 观 察 交 换 机 是 否 显 示 squid 正 常 或 异 常 :ServerIron#show logging...00d00h11m51s:N:L4 server 172.16.102.66 squid1 port 80 is up00d00h11m49s:N:L4 server 172.16.102.66 squid1 port 80 is down00d00h10m21s:N:L4 server 172.16.102.66 squid1 port 80 is up00d00h10m21s:N:L4 server 172.16.102.66 squid1 is up注 意 ServerIron 认 为 服 务 运 行 在 80 端 口 。 以 后 你 会 见 到 squid 运 行 在 3128 端 口 的 示 例 。 包过 滤 规 则 实 际 上 将 包 的 目 的 地 址 从 80 改 变 为 3128。 这 导 致 一 些 与 状 态 检 测 有 关 的 有 趣 结 果 ,我 在 9.3.2.5 节 里 会 讲 到 。9.3.2.3 Extreme Networks在 该 示 例 里 , 硬 件 是 Summit1i, 软 件 版 本 是 6.1.3b11。 再 次 将 客 户 端 分 配 在 端 口 1,Internet在 端 口 2,squid 在 端 口 3。 网 络 配 置 见 图 9-5。;Extreme 交 换 机 仅 仅 对 在 不 同 子 网 间 进 行 路 由 的 数 据 包 进 行 HTTP 连 接 的 拦 截 。 换 句 话 说 , 如果 你 配 置 Extreme 交 换 机 使 用 二 层 模 式 ( 单 一 VLAN 里 ), 就 不 能 将 包 转 发 给 squid。 为 了 让HTTP 拦 截 正 常 工 作 , 必 须 给 用 户 ,<strong>Squid</strong>, 和 Internet 配 置 不 同 的 VLAN。configure Default delete port 1-8create vlan Usersconfigure Users ip 172.16.102.1 255.255.255.192configure Users add port 1create vlan Internetconfigure Internet ip 172.16.102.129 255.255.255.192configure Internet add port 2


create vlan <strong>Squid</strong>configure <strong>Squid</strong> ip 172.16.102.65 255.255.255.192configure <strong>Squid</strong> add port 3下 一 步 是 激 活 和 配 置 交 换 机 的 路 由 :enable ipforwardingconfigure iproute add default 172.16.102.130最 后 , 配 置 交 换 机 重 定 向 HTTP 连 接 到 <strong>Squid</strong>:create flow-redirect http tcp destination any ip-port 80 source anyconfigure http add next-hop 172.16.102.669.3.2.4 Cisco Arrowpoint下 类 配 置 基 于 我 以 前 的 测 试 笔 记 。 然 而 , 最 近 我 没 有 使 用 这 类 型 的 交 换 机 , 不 能 确 保 如 下 命 令 仍然 正 确 :circuit VLAN1ip address 172.16.102.1 255.255.255.0service pxy1type transparent-cacheip address 172.16.102.66port 80protocol tcpactiveowner foocontent baradd service pxy1protocol tcpport 80active9.3.2.5 关 于 HTTP 服 务 和 健 壮 性 检 测 的 评 论在 上 面 的 示 例 里 , 路 由 器 / 交 换 机 都 直 接 转 发 包 , 不 会 改 变 目 的 TCP 端 口 。 在 9.4 章 里 用 到 的 包过 滤 规 则 改 变 了 目 的 端 口 。 如 果 试 图 在 同 一 主 机 上 运 行 HTTP 服 务 和 squid, 那 么 就 产 生 了 一 个有 趣 的 问 题 。为 了 在 3128 端 口 运 行 <strong>Squid</strong> 的 同 时 , 还 要 在 80 端 口 运 行 HTTP, 包 过 滤 配 置 必 须 有 1 条 特殊 的 规 则 , 它 接 受 到 本 机 HTTP 服 务 的 TCP 连 接 。 否 则 , 连 接 会 直 接 转 交 给 <strong>Squid</strong>。 该 规 则 易于 建 立 。 假 如 目 的 端 口 是 80, 并 且 目 的 地 址 是 服 务 器 的 , 那 么 主 机 正 常 接 受 这 个 包 。 然 而 所 有


的 拦 截 包 有 外 部 目 的 地 址 , 所 以 它 们 不 会 匹 配 该 规 则 。然 而 , 当 路 由 器 / 交 换 机 进 行 HTTP 健 壮 性 检 测 时 , 它 连 接 到 服 务 器 的 IP 地 址 。 这 样 , 健 壮 性 检测 的 数 据 包 匹 配 了 上 述 规 则 , 它 不 会 转 交 给 <strong>Squid</strong>。 路 由 器 / 交 换 机 检 测 了 错 误 的 服 务 。 假 如HTTP 服 务 down 掉 了 , 而 squid 还 在 运 行 , 那 健 壮 性 检 测 就 产 生 错 误 结 果 。解 决 这 个 问 题 的 一 些 选 择 是 :1. 不 要 在 <strong>Squid</strong> 主 机 上 运 行 HTTP 服 务 ;2. 增 加 1 条 特 殊 的 包 过 滤 规 则 , 将 来 自 路 由 器 / 交 换 机 的 状 态 检 测 的 包 转 交 给 squid;3. 配 置 路 由 器 / 交 换 机 , 改 变 目 的 端 口 为 3128;4. 禁 止 4 层 状 态 检 测 。9.3.3 Cisco 策 略 路 由策 略 路 由 与 4 层 交 换 并 非 不 同 。 它 在 Cisco 和 其 他 公 司 的 路 由 产 品 上 执 行 。 主 要 的 区 别 是 策 略路 由 不 包 括 任 何 健 壮 性 检 测 。 这 样 , 假 如 squid 超 载 或 完 全 不 可 响 应 , 路 由 器 还 会 继 续 转 发 包到 squid, 而 不 是 将 包 路 由 到 原 始 服 务 器 。 策 略 路 由 要 求 squid 位 于 路 由 器 直 接 相 连 的 子 网 中 。在 本 示 例 里 , 使 用 了 Cisco 7204 路 由 器 , 运 行 IOS Version 12.0(5)T。 网 络 配 置 与 前 面 的 一样 , 见 图 9-5。;首 先 的 配 置 步 骤 是 定 义 访 问 列 表 , 匹 配 来 自 客 户 端 的 到 80 端 口 的 数 据 包 。 必 须 确 保 <strong>Squid</strong> 发起 的 到 80 端 口 的 数 据 包 不 会 被 再 次 拦 截 。 做 到 这 点 的 方 法 之 一 是 , 定 义 1 个 特 殊 规 则 , 拒 绝 来自 squid 的 数 据 包 , 紧 跟 1 条 规 则 允 许 所 有 其 他 的 数 据 包 :access-list 110 deny tcp host 172.16.102.66 any eq wwwaccess-list 110 permit tcp any any eq www另 外 , 如 果 <strong>Squid</strong> 和 用 户 位 于 不 同 的 子 网 , 你 可 以 仅 仅 允 许 来 自 用 户 所 在 网 络 的 数 据 包 :access-list 110 permit tcp 10.102.0.0 0.0.255.255 any eq www下 一 步 是 定 义 路 由 映 射 。 在 这 里 你 告 诉 路 由 器 转 发 拦 截 包 到 何 处 去 :route-map proxy-redirect permit 10match ip address 110set ip next-hop 172.16.102.66这 些 命 令 表 明 ,“ 假 如 IP 地 址 匹 配 访 问 列 表 110, 就 转 发 该 包 到 172.16.102.66”。 在 routemap行 的 数 字 10 是 一 个 序 列 号 , 假 如 你 有 多 个 路 由 映 射 的 话 。 最 后 一 步 是 应 用 路 由 映 射 到 客户 端 连 接 的 接 口 :interface Ethernet0/0


ip policy route-map proxy-redirectIOS 不 对 策 略 路 由 提 供 很 多 调 试 方 法 。 然 而 ,show route-map 命 令 足 够 可 用 :router#show route-map proxy-redirectroute-map proxy-redirect, permit, sequence 10Match clauses:ip address (access-lists): 110Set clauses:ip next-hop 172.16.102.66Policy routing matches: 730 packets, 64649 bytes9.3.4 Web Cache Coordination 协 议Cisco 对 4 层 交 换 技 术 的 响 应 叫 做 Web Cache Coordination Protocol(WCCP).WCCP 在 许多 方 面 与 典 型 的 4 层 拦 截 不 同 。首 先 , 拦 截 包 被 封 装 在 GRE( 路 由 封 装 类 ) 里 。 这 点 允 许 数 据 包 跨 子 网 传 输 , 也 就 意 味 着 squid不 必 直 接 连 在 路 由 器 上 。 因 为 数 据 包 是 封 装 的 ,squid 主 机 必 须 对 其 进 行 解 包 。 并 非 所 有 的 Unix系 统 有 解 开 GRE 包 的 代 码 。第 二 个 不 同 是 , 路 由 器 如 何 决 定 将 负 载 分 摊 到 多 个 cache 上 。 事 实 上 , 路 由 器 不 做 这 个 决 定 ,由 cache 来 做 。 当 路 由 器 有 一 组 支 持 WCCP 的 cache 时 , 其 中 一 个 cache 主 动 成 为 组 的 领 导 。由 领 导 cache 来 决 定 如 何 分 摊 负 载 和 通 知 路 由 器 。 在 路 由 器 重 定 向 然 任 何 连 接 之 前 , 这 是 一 个额 外 的 必 要 步 骤 。因 为 WCCP 使 用 GRE, 路 由 器 可 能 强 迫 要 求 将 来 自 HTTP 请 求 的 大 TCP 包 分 割 成 片 断 。 幸 运的 是 , 这 点 不 会 经 常 发 生 , 因 为 大 部 分 HTTP 请 求 比 以 太 网 MTU size(1500 字 节 ) 要 小 。 默认 的 TCP 和 IP 包 头 部 是 20 字 节 , 这 意 味 着 以 太 网 帧 能 实 际 携 带 1460 字 节 的 数 据 。GRE 封装 在 GRE 头 部 增 加 了 20 字 节 , 另 外 在 第 二 个 IP 头 部 增 加 了 20 字 节 。 这 样 来 自 客 户 端 的 正 常的 1500 字 节 的 TCP/IP 包 , 在 封 装 后 变 成 了 1540 字 节 。 这 样 数 据 包 就 太 大 而 不 能 在 单 个 以 太网 帧 里 传 输 , 所 以 路 由 器 将 原 始 包 分 割 成 两 个 片 断 。9.3.4.1 WCCPv1该 节 的 配 置 示 例 在 运 行 IOS Version 12.0(5)T 的 Cisco 7204 路 由 器 上 测 试 。 网 络 配 置 跟 图 9-5 同 。首 先 , 在 IOS 配 置 中 输 入 如 下 两 行 , 激 活 路 由 器 的 WCCP:ip wccp version 1ip wccp web-cache


接 着 , 必 须 在 单 独 的 路 由 器 接 口 上 激 活 WCCP。 在 HTTP 包 离 开 路 由 器 的 接 口 上 激 活 WCCP,也 就 是 路 由 器 连 接 到 外 部 原 始 服 务 器 或 Internet 网 关 的 接 口 :interface Ethernet0/1ip address 172.16.102.129 255.255.255.192ip wccp web-cache redirect out请 确 认 保 存 了 配 置 改 变 。你 也 许 想 使 用 访 问 列 表 来 阻 止 某 些 web 站 点 的 拦 截 。 可 以 使 用 访 问 列 表 来 防 止 循 环 转 发 。 例 如 :! don't re-intercept connections coming from <strong>Squid</strong>:access-list 112 denytcp host 172.16.102.66 any eq www! don't intercept this broken web siteaccess-list 112 denytcp any 192.16.8.7 255.255.255.255 eq www! allow other HTTP trafficaccess-list 110 permit tcp any any eq wwwip wccp web-cache redirect-list 112路 由 器 不 发 送 任 何 数 据 到 squid, 直 到 squid 宣 称 它 自 己 是 路 由 器 。 我 在 9.5.1 节 里 解 释 如 何配 置 squid 的 WCCP。9.3.4.2 WCCPv2当 前 标 准 的 <strong>Squid</strong> 发 布 仅 支 持 WCCPv1。 然 而 , 可 在 http://devel.squid-cache.org/ 找 到WCCPv2 的 补 丁 。 该 代 码 仍 是 实 验 性 的 。注 意 从 路 由 器 发 送 到 <strong>Squid</strong> 的 GRE 包 , 包 含 了 额 外 的 4 个 字 节 。WCCPv2 在 GRE 头 部 和 封装 的 IP 包 之 间 , 插 入 了 一 个 重 定 向 头 部 。 也 许 需 要 修 改 内 核 代 码 来 计 算 这 个 额 外 的 头 部 。9.3.4.3 调 试IOS 提 供 许 多 命 令 来 监 视 和 调 试 WCCP。show ip wccp web-cache 命 令 提 供 一 些 基 本 的 信息 :router#show ip wccp web-cacheGlobal WCCP information:Router information:


Router Identifier: 172.16.102.129Protocol Version: 1.0Service Identifier: web-cacheNumber of Cache Engines: 1Number of routers: 1Total Packets Redirected: 1424Redirect access-list:-none-Total Packets Denied Redirect: 0Total Packets Unassigned: 0Group access-list:-none-Total Messages Denied to Group: 0Total Authentication failures: 0欲 了 解 更 多 细 节 , 在 前 叙 命 令 后 加 一 个 detail 单 词 :router#show ip wccp web-cache detailWCCP Cache-Engine information:IP Address: 172.16.102.66Protocol Version: 0.4State:UsableInitial Hash Info: 0000000000000000000000000000000000000000000000000000000000000000Assigned Hash Info: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFHash Allotment: 256 (100.00%)Packets Redirected: 1424Connect Time: 00:17:40这 里 可 以 看 到 squid 的 IP 地 址 和 状 态 。 假 如 不 止 一 个 cache 与 路 由 器 会 话 , 那 么 hash 分 配 信息 看 起 来 不 同 。 大 多 数 情 况 下 , 每 个 cache 接 受 到 相 等 的 hash 值 。注 意 第 二 条 命 令 输 出 的 协 议 版 本 值 , 与 第 一 条 命 令 的 不 一 样 。 不 幸 的 是 , 赋 予 了 版 本 号 太 多 的 意义 。show ip wccp web-cache 命 令 看 起 来 报 告 WCCP 协 议 的 主 版 本 号 ( 例 如 1 或 2), 然 而show ip wccp web-cache detail 的 版 本 号 看 起 来 匹 配 <strong>Squid</strong> 的 wccp_version 指 令 的 值 。9.4 操 作 系 统 配 置为 了 让 cache 拦 截 正 常 工 作 , 必 须 在 操 作 系 统 中 激 活 某 些 网 络 功 能 。 首 先 , 必 须 激 活 IP 包 转 发 。这 就 允 许 操 作 系 统 接 受 目 的 地 址 是 外 部 IP 的 数 据 包 。 接 着 , 必 须 激 活 和 配 置 内 核 中 的 相 关 代 码 ,以 重 定 向 外 部 包 到 <strong>Squid</strong>。


9.4.1 Linux本 节 的 指 导 适 合 2.4 系 列 Linux 内 核 。 我 使 用 RedHat Linux7.2( 内 核 是 2.4.7-10)。 假 如 你使 用 的 版 本 不 同 , 那 可 能 不 能 运 行 。 建 议 搜 索 下 <strong>Squid</strong> 的 FAQ 或 其 他 地 方 , 找 到 关 于 内 核 的 更新 的 或 历 史 的 信 息 。在 我 测 试 iptables 过 程 中 , 不 必 激 活 IP 转 发 。 然 而 , 你 也 可 以 试 试 在 一 开 始 就 激 活 它 , 并 在 一切 运 行 良 好 后 , 看 看 能 否 禁 掉 它 。 激 活 包 转 发 的 最 好 的 方 法 是 在 /etc/sysctl.conf 文 件 里 增 加 如下 行 :net.ipv4.ip_forward = 1一 般 来 说 , 在 HTTP 拦 截 生 效 前 , 不 必 编 译 新 内 核 。 假 如 你 不 知 道 如 何 配 置 和 创 建 新 Linux 内核 , 请 参 阅 O'Reilly's Running Linux by Matt Welsh, Matthias Kalle Dalheimer, andLar Kaufman。 当 你 配 置 内 核 时 , 请 确 认 如 下 选 项 被 激 活 :o General setupNetworking support (CONFIG_NET=y)Sysctl support (CONFIG_SYSCTL=y)o Networking optionsNetwork packet filtering (CONFIG_NETFILTER=y)TCP/IP networking (CONFIG_INET=y)Netfilter ConfigurationConnection tracking (CONFIG_IP_NF_CONNTRACK=y)IP tables support (CONFIG_IP_NF_IPTABLES=y)Full NAT (CONFIG_IP_NF_NAT=y)REDIRECT target support (CONFIG_IP_NF_TARGET_REDIRECT=y)o File systems/proc filesystem support (CONFIG_PROC_FS=y)另 外 , 请 确 认 该 选 项 没 被 激 活 :o Networking optionsFast switching (CONFIG_NET_FASTROUTE=n)重 定 向 外 部 数 据 包 到 squid 的 代 码 是 Netfilter 软 件 的 一 部 分 。 如 下 是 发 送 HTTP 拦 截 连 接 到squid 的 规 则 :iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port3128


Linux 内 核 维 护 许 多 不 同 的 tables。-t nat 选 项 表 明 我 们 正 在 修 改 NAT( 网 络 地 址 转 换 ) 表 。本 质 上 , 我 们 使 用 iptables 将 原 始 服 务 器 的 TCP/IP 地 址 转 换 为 squid 的 本 地 TCP/IP 地 址 。每 个 iptables 表 有 许 多 链 。-A PREROUTING 表 明 我 们 增 加 了 一 条 规 则 到 内 建 的 链 叫 做PREROUTING。PREROUTING 链 仅 对 从 外 部 网 络 进 入 系 统 的 数 据 包 有 效 。接 下 来 的 三 个 选 项 决 定 哪 个 包 匹 配 该 规 则 。-i eth0 选 项 限 制 规 则 仅 对 eth0 接 口 上 接 受 的 数 据包 有 效 。-p tcp 选 项 指 定 TCP 包 ,--dport 80 指 定 包 的 目 的 端 口 是 80。 假 如 这 三 个 条 件 都 是true, 那 么 包 匹 配 该 规 则 。-j REDIRECT 选 项 表 明 对 匹 配 规 则 的 包 , 采 取 何 种 动 作 。REDIRECT 是 内 建 的 动 作 名 , 它 导 致iptables 改 变 包 的 目 的 地 址 为 127.0.0.1。--to-port 3128 选 项 也 指 示 iptables 改 变 目 的 TCP端 口 为 3128。假 如 你 在 squid 主 机 上 运 行 HTTP 服 务 ( 例 如 Apache), 就 必 须 增 加 另 外 的 iptables 规 则 。该 必 要 规 则 允 许 连 接 到 HTTP 服 务 。 否 则 ,REDIRECT 规 则 导 致 iptables 转 发 连 接 到 squid的 3128 端 口 。 可 以 使 用 -I 选 项 在 列 表 顶 部 插 入 一 条 新 规 则 :iptables -t nat -I PREROUTING -i eth0 -p tcp -d 172.16.102.66 --dport 80 -jACCEPT一 旦 确 认 所 有 iptables 规 则 工 作 正 确 , 记 得 运 行 如 下 命 令 来 保 存 配 置 :/sbin/service iptables save将 当 前 规 则 保 存 到 /etc/sysconfig/iptables, 当 系 统 重 启 时 , 这 些 规 则 自 动 载 入 。9.4.1.1 Linux 和 WCCP2.4 版 本 的 Linux 内 核 自 带 1 个 GRE 伪 装 接 口 。 然 而 , 它 不 能 解 码 WCCP 任 务 里 封 装 的 GRE包 。 问 题 看 起 来 在 于 路 由 器 设 置 了 WCCP/GRE 包 的 协 议 类 型 域 为 0x883E。Linux 的 GRE 驱动 不 知 道 如 何 处 理 这 类 型 包 , 因 为 它 不 了 解 0x883E 类 型 的 协 议 。可 以 试 试 给 Linux 打 GRE 模 块 的 补 丁 , 以 便 它 能 在 WCCP 下 工 作 。<strong>Squid</strong> FAQ 包 含 了 对 这 个补 丁 的 链 接 。 然 而 , 假 如 使 用 WCCP 指 定 的 Linux 模 块 , 事 情 会 容 易 些 。 可 以 在 这 里 找 到 它 :http://www.squid-cache.org/WCCP-support/Linux/ip_wccp.c必 须 编 译 ip_wccp.c 文 件 为 可 装 载 内 核 模 块 。 有 点 棘 手 的 是 , 依 赖 于 内 核 版 本 的 不 同 , 编 译 选项 可 能 不 同 。 你 可 以 进 入 内 核 源 代 码 目 录 , 敲 入 make modules 并 观 察 编 译 器 命 令 的 滚 动 。 然后 拷 贝 这 些 命 令 中 的 一 个 , 然 后 改 变 最 后 一 个 参 数 为 ip_wccp.c。 如 下 是 我 在 2.4.7-10 Linux内 核 中 使 用 的 命 令 :% gcc -Wall -D_ _KERNEL_ _ -I/usr/src/linux-2.4.7-10/include \


-DMODULE -DMODVERSIONS -DEXPORT_SYMBAB \-include /usr/src/linux-2.4.7-10/include/linux/modversions.h \-O2 -c ip_wccp.cgcc 命 令 在 当 前 目 录 会 生 成 ip_wccp.o 文 件 。 下 一 步 使 用 insmod 命 令 , 装 载 模 块 到 内 核 中 :# insmod ip_wccp.o注 意 ip_wccp 模 块 接 受 来 自 任 何 源 地 址 的 GRE/WCCP 包 。 换 句 话 说 , 恶 意 用 户 可 能 发 送 数 据到 squid cache。 假 如 使 用 该 模 块 , 应 该 安 装 一 条 iptables 规 则 , 拒 绝 外 部 的 GRE 包 。 例 如 :# iptables -A INPUT -p gre -s 172.16.102.65 -j ACCEPT# iptables -A INPUT -p gre -j DROP不 要 忘 记 敲 入 /sbin/service iptables save 命 令 来 保 存 配 置 。9.4.2 FreeBSD本 节 的 例 子 基 于 FreeBSD-4.8, 并 可 以 在 任 何 FreeBSD-4 和 5 系 列 的 后 续 版 本 上 运 行 。要 激 活 IP 包 转 发 , 在 /etc/sysctl.conf 中 增 加 如 下 行 :net.inet.ip.forwarding=1需 要 在 内 核 中 激 活 2 个 特 殊 选 项 。 假 如 你 不 知 道 如 何 编 译 内 核 , 参 见 FreeBSD Handbook 第 9章 (http://www.freebsd.org/handbook/index.html). 编 辑 内 核 配 置 文 件 , 确 保 有 如 下 行 :optionsoptionsIPFIREWALLIPFIREWALL_FORWARD假 如 squid 主 机 位 于 无 人 照 看 的 机 房 中 , 我 也 推 荐 使 用 IPFIREWALL_DEFAULT_TO_ACCEPT选 项 。 假 如 你 被 防 火 墙 的 规 则 困 扰 , 仍 然 可 以 登 陆 系 统 中 。ipfw 命 令 告 诉 内 核 重 定 向 拦 截 连 接 到 squid:/sbin/ipfw add allow tcp from 172.16.102.66 to any out/sbin/ipfw add allow tcp from any 80 to any out/sbin/ipfw add fwd 127.0.0.1,3128 tcp from any to any 80 in/sbin/ipfw add allow tcp from any 80 to 172.16.102.66 in第 一 条 规 则 匹 配 squid 主 机 发 起 的 数 据 包 。 它 确 保 外 出 的 TCP 连 接 不 会 被 重 新 定 向 回 squid。第 二 条 规 则 匹 配 squid 响 应 客 户 端 的 数 据 包 。 我 在 这 里 列 出 它 , 因 为 随 后 会 有 另 外 的 ipfw 规 则 ,这 些 规 则 会 拒 绝 这 些 包 。 第 三 条 规 则 实 际 重 定 向 进 来 的 连 接 到 squid。 第 四 条 规 则 匹 配 从 原 始 服务 器 返 回 squid 的 数 据 包 。 这 里 又 一 次 假 设 随 后 会 有 相 应 的 拒 绝 规 则 。


假 如 在 squid 主 机 上 运 行 HTTP 服 务 , 就 必 须 增 加 另 外 的 规 则 , 它 放 过 , 而 不 是 重 定 向 , 目 的地 址 是 原 始 服 务 器 的 TCP 包 。 下 列 规 则 在 fwd 规 则 之 前 :/sbin/ipfw add allow tcp from any to 172.16.102.66 80 inFreeBSD 典 型 的 将 ipfw 规 则 存 储 在 /etc/rc.firewall 里 。 一 旦 你 确 认 规 则 设 置 正 确 , 记 得 保 存它 们 。 将 如 下 行 加 入 /etc/rc.local 文 件 , 让 FreeBSD 在 启 动 时 自 动 运 行 /etc/rc.firewall 脚 本 。firewall_enable="YES"9.4.2.1 FreeBSD 和 WCCPFreeBSD 版 本 4.8 和 后 续 版 本 内 建 了 对 GRE 和 WCCP 的 支 持 。 早 期 的 版 本 需 要 补 丁 , 你 可 以在 这 里 找 到 : http://www.squid-cache.org/WCCP-support/FreeBSD/ . 内 建 代 码 的 性 能非 常 好 , 它 是 真 正 的 内 核 组 织 编 写 的 。 可 能 也 需 要 编 译 支 持 GRE 的 新 内 核 。 将 如 下 行 加 入 内 核配 置 文 件 里 :pseudo-devicegre对 Freebsd-5, 使 用 device 代 替 了 pseudo-device。 当 然 , 你 也 需 要 前 面 章 节 里 提 到 的FIREWALL 选 项 。在 安 装 和 重 启 了 新 内 核 后 , 必 须 配 置 GRE 通 道 来 接 受 来 自 路 由 器 的 GRE 包 。 例 如 :# ifconfig gre0 create# ifconfig gre0 172.16.102.66 172.16.102.65 netmask 255.255.255.255 up# ifconfig gre0 tunnel 172.16.102.66 172.16.102.65# route delete 172.16.102.65ifconfig 命 令 在 gre0 接 口 上 , 增 加 了 一 个 到 路 由 器 (172.16.102.65) 的 路 由 表 入 口 。 我 发现 必 须 删 除 该 路 由 , 以 便 squid 能 与 其 他 路 由 器 会 话 。你 也 许 想 或 必 须 对 来 自 路 由 器 的 GRE 包 , 增 加 一 条 ipfw 规 则 :/sbin/ipfw add allow gre from 172.16.102.65 to 172.16.102.669.4.3 OpenBSD本 节 的 示 例 基 于 OpenBSD 3.3为 了 激 活 包 转 发 , 在 /etc/sysctl.conf 文 件 里 增 加 该 行 :net.inet.ip.forwarding=1


现 在 , 在 /etc/pf.conf 文 件 里 增 加 如 下 类 似 行 , 配 置 包 过 滤 规 则 :rdr inet proto tcp from any to any port = www ->; 127.0.0.1 port 3128pass out proto tcp from 172.16.102.66 to anypass out proto tcp from any port = 80 to anypass in proto tcp from any port = 80 to 172.16.102.66假 如 你 没 有 使 用 OpenBSD 的 包 过 滤 器 , 需 要 在 /etc/rc.conf.local 文 件 里 增 加 一 行 来 激 活 它 :pf=YES9.4.3.1 OpenBSD 和 WCCP首 先 , 增 加 如 下 行 到 /etc/sysctl.conf 文 件 , 告 诉 系 统 接 受 和 处 理 GRE 和 WCCP 包 :net.inet.gre.allow=1net.inet.gre.wccp=1然 后 , 用 如 下 命 令 配 置 GRE 接 口 :# ifconfig gre0 172.16.102.66 172.16.102.65 netmask 255.255.255.255 up# ifconfig gre0 tunnel 172.16.102.66 172.16.102.65# route delete 172.16.102.65跟 Freebsd 一 样 , 我 发 现 必 须 删 除 ifconfig 自 动 产 生 的 路 由 。 最 后 , 依 赖 于 包 过 滤 器 的 配 置 ,必 须 增 加 一 条 规 则 以 允 许 GRE 包 :pass in proto gre from 172.16.102.65 to 172.16.102.669.4.4 在 NetBSD 和 其 他 系 统 上 的 IPFilter本 节 的 示 例 基 于 NetBSD 1.6.1。 它 们 也 能 运 行 在 Solaris,HP-UX,IRIX, 和 Tru64 上 , 既 然 这些 系 统 本 身 就 配 备 了 IPFilter.激 活 NetBSD 的 包 转 发 , 将 如 下 行 加 进 /etc/sysctl.conf:net.inet.ip.forwarding=1然 后 , 将 如 下 行 插 入 NAT 配 置 文 件 /etc/ipnat.conf 中 :rdr fxp0 0/0 port 80 ->; 172.16.102.66 port 3128 tcp你 的 接 口 名 可 能 与 本 例 的 fxp0 不 同 。9.4.4.1 NetBSD 和 WCCP我 不 能 在 NetBSD 上 运 行 WCCP, 即 使 打 了 GRE 补 丁 来 接 受 WCCP 包 。 该 问 题 看 起 来 根 源 在


IPFilter rdr 规 则 阻 塞 了 特 定 的 端 口 。 来 自 路 由 器 的 包 通 过 NetBSD 的 gre0 接 口 ( 在 这 里 它 们被 解 包 )。 然 而 , 包 回 到 路 由 器 时 , 走 另 一 条 通 道 , 未 被 封 装 并 且 不 走 同 一 网 络 接 口 。 这 样 ,IPFilter代 码 没 有 将 squid 的 本 地 IP 地 址 转 换 回 原 始 服 务 器 的 地 址 。9.5 配 置 <strong>Squid</strong>假 如 你 使 用 Linux 2.4 和 iptables, 在 运 行 ./configure 时 , 可 使 用 --enable-linux-netfilter选 项 。 它 激 活 某 些 Linux 的 特 殊 代 码 , 以 发 现 发 起 请 求 的 原 始 服 务 器 的 IP 地 址 。<strong>Squid</strong> 正 常 情况 下 从 Host 头 部 , 得 到 原 始 服 务 器 的 名 字 ( 和 / 或 地 址 )。--enable-linux-netfilter 功 能 仅 对没 有 Host 头 部 的 请 求 来 说 是 必 要 的 。 统 计 显 示 几 乎 所 有 的 请 求 有 Host 头 部 , 所 以 实 际 中 可 以不 使 用 --enable-linux-netfilter 选 项 。假 如 正 在 使 用 IPFilter 包 (NetBSD,Solaris, 或 其 他 ), 因 为 同 样 的 理 由 , 你 应 该 使 用 --enableipf-transparent选 项 。 在 OpenBSD 上 , 请 使 用 --enable-pf-transparent 选 项 。 每 次 运行 ./configure 时 , 必 须 重 编 译 squid, 见 3.8 章 的 描 述 。在 运 行 了 ./configure 和 重 编 译 了 squid 后 , 可 以 编 辑 squid.conf 文 件 。 作 为 起 点 , 请 确 认 下列 指 令 定 义 了 给 定 的 值 :httpd_accel_host virtualhttpd_accel_port 80httpd_accel_uses_host_header onhttpd_accel_with_proxy onhttpd_accel_single_host offhttp_accel_host 指 令 是 关 键 。 它 指 示 squid 接 受 包 含 局 部 URI 的 HTTP 请 求 。httpd_accel_uses_host_header 被 激 活 , 允 许 squid 使 用 Host 头 部 来 重 新 构 建 完 整 URI。virtual 关 键 字 指 示 squid 在 缺 乏 Host 头 部 时 , 将 原 始 服 务 器 的 IP 地 址 放 进 URL 里 。httpd_accel_with_proxy 指 令 控 制 squid 是 否 既 接 受 HTTP 服 务 ( 部 分 URI) 请 求 , 又 接 受代 理 ( 完 整 URI) 请 求 。 在 cache 拦 截 里 , 它 应 该 被 激 活 。 如 果 没 有 用 户 明 确 的 配 置 使 用 squid做 代 理 , 那 即 使 httpd_accel_with_proxy 没 被 激 活 ,squid 也 能 工 作 。httpd_acces_single_host 指 令 正 常 情 况 下 被 禁 止 , 在 早 期 版 本 的 squid 里 , 它 可 能 被 默 认 激活 。 在 cache 拦 截 里 , 它 应 明 确 被 禁 止 。假 如 拦 截 不 止 针 对 80 端 口 , 你 也 许 该 将 httpd_accel_port 设 为 0。 见 附 录 A 的 更 多 信 息 。假 如 你 没 有 使 用 WCCP, 就 该 准 备 开 始 发 起 拦 截 会 话 到 squid 了 。 通 过 使 用 浏 览 器 来 上 网 冲 浪 ,或 者 使 用 squidclient 发 起 测 试 请 求 , 就 可 以 放 手 一 试 。 假 如 你 使 用 WCCP, 那 么 还 有 许 多 步骤 要 完 成 。9.5.1 配 置 WCCPv1路 由 器 不 发 送 任 何 会 话 到 squid, 直 到 squid 宣 称 它 自 己 是 路 由 器 。 为 了 让 squid 那 样 做 , 在


squid.conf 中 增 加 如 下 行 :wccp_router 172.16.102.65wccp_version 4路 由 器 有 多 个 接 口 。 请 确 认 使 用 与 squid 相 连 的 接 口 的 IP 地 址 。 这 点 是 必 要 的 , 因 为 来 自 路 由器 的 WCCP 消 息 , 将 源 IP 地 址 设 置 为 外 出 接 口 的 地 址 。 假 如 源 地 址 不 匹 配 wccp_router 值 ,squid 会 拒 绝 WCCP 消 息 。WCCPv1 文 档 规 定 4 作 为 协 议 版 本 号 。 然 而 , 某 些 用 户 报 告 ,Cisco IOS 11.2 仅 支 持 协 议 版本 3。 假 如 你 使 用 该 版 本 的 IOS, 请 在 squid.conf 里 改 变 版 本 号 :wccp_version 39.6 调 试 问 题HTTP 拦 截 比 较 复 杂 , 因 为 许 多 不 同 设 备 必 须 组 合 正 确 工 作 。 为 了 帮 助 你 跟 踪 问 题 , 如 下 是 一 个问 题 解 答 检 查 列 表 :λ 客 户 端 数 据 包 正 在 通 过 路 由 器 / 交 换 机 吗 ?在 简 单 网 络 里 , 这 点 显 而 易 见 。 你 可 以 trace 线 缆 并 观 察 指 示 灯 的 活 动 闪 烁 。 然 而 在 大 而 复 杂 的网 络 , 数 据 包 可 能 走 不 同 的 路 线 。 假 如 你 的 组 织 够 大 , 并 有 网 络 sniffer 设 备 , 就 可 以 观 察 线 路中 web 客 户 端 的 请 求 数 据 包 。 低 技 术 的 方 法 是 , 断 开 有 问 题 的 线 路 , 并 观 察 是 否 影 响 客 户 端 的web 浏 览 。λ 路 由 器 / 交 换 机 配 置 是 否 正 确 ?你 也 许 要 再 次 检 查 路 由 器 / 交 换 机 配 置 。 假 如 你 已 配 置 了 某 个 接 口 , 那 能 否 确 保 它 正 确 呢 ?是 否 新 的 配 置 真 正 在 设 备 上 运 行 ? 也 许 在 你 保 存 配 置 之 前 , 路 由 器 / 交 换 机 已 重 启 了 。 在 改 变 生效 前 , 你 或 许 需 要 reboot 设 备 。λ 交 换 机 / 路 由 器 能 与 squid 主 机 会 话 吗 ?能 从 路 由 器 / 交 换 机 上 ping 通 squid 吗 ? 大 部 分 4 层 拦 截 配 置 要 求 网 络 设 备 和 squid 在 同 一 子网 里 。 登 陆 路 由 器 / 交 换 机 , 确 认 能 ping 通 squid 的 IP 地 址 。λ 交 换 机 / 路 由 器 相 信 squid 在 运 行 吗 ?许 多 传 输 拦 截 设 备 不 会 发 送 会 话 到 squid, 除 非 它 们 知 道 squid 是 健 壮 的 。 使 用 调 试 命 令 来 预览 squid 的 健 壮 性 状 态 。 也 许 会 发 现 三 层 健 壮 性 检 测 ( 例 如 ICMP ping) 比 四 层 检 测 ( 例 如 HTTP)更 容 易 , 它 使 网 络 设 备 更 容 易 将 squid 标 记 为 存 活 状 态 。λ <strong>Squid</strong> 实 际 在 运 行 吗 ?请 再 次 确 认 squid 真 正 在 运 行 , 特 别 是 在 系 统 近 期 重 启 过 的 情 况 下 。


λ 数 据 包 正 在 抵 达 squid 主 机 吗 ?使 用 tcpdump 能 见 到 拦 截 的 TCP 连 接 。 如 下 是 示 例 :# tcpdump -n -i eth0 port 80假 如 使 用 WCCP, 请 检 查 来 自 路 由 器 的 GRE 包 :# tcpdump -n -i eth0 ip proto gre假 如 没 有 看 到 tcpdump 的 任 何 输 出 , 则 路 由 器 / 交 换 机 可 能 没 有 发 送 任 何 数 据 。 在 这 种 情 况 下 ,返 回 到 以 前 的 建 议 。注 意 , 假 如 设 备 正 使 用 四 层 健 壮 性 检 测 , 你 可 以 在 tcpdump 的 输 出 里 见 到 这 些 。 健 壮 性 检 测 来自 路 由 器 / 交 换 机 的 IP 地 址 , 所 以 它 们 容 易 被 认 出 。 假 如 你 见 到 健 壮 性 检 测 , 但 没 有 其 他 数 据 ,那 可 能 意 味 着 路 由 器 / 交 换 机 正 把 squid 的 响 应 理 解 为 不 健 壮 。 例 如 , 设 备 可 能 想 见 到 200(OK)响 应 , 但 squid 返 回 一 个 错 误 , 例 如 401( 未 授 权 ) 或 404( 未 发 现 )。 请 对 access.log 运 行tail -f 命 令 。λ 激 活 了 IP 转 发 吗 ?请 再 次 确 认 squid 运 行 的 操 作 系 统 配 置 了 IP 包 转 发 。 假 如 没 有 , 主 机 可 能 会 丢 弃 拦 截 数 据 包 ,因 为 目 的 IP 地 址 并 非 本 地 。λ 配 置 包 过 滤 了 吗 ?请 确 认 包 过 滤 器 ( 例 如 ipfw,iptables,pf 等 ) 配 置 正 确 。 当 每 件 事 都 运 行 良 好 时 , 你 能 定 期 运行 命 令 来 显 示 过 滤 规 则 , 并 观 察 计 数 器 增 长 。 例 如 :# ipfw show 300 ; sleep 3; ipfw show 30000300 86216 8480458 fwd 127.0.0.1,3128 tcp from any to any 80 in00300 86241 8482240 fwd 127.0.0.1,3128 tcp from any to any 80 in注 意 该 示 例 在 FreeBSD 上 , 包 和 字 节 计 数 器 ( 第 二 和 第 三 列 ) 正 在 增 长 。λ 环 路 接 口 起 来 和 配 置 了 吗 ?假 如 有 一 条 规 则 转 发 / 重 定 向 包 到 127.0.0.1, 请 确 认 环 路 接 口 ( 例 如 lo0,lo 等 ) 起 来 了 , 并 配置 过 它 。 假 如 没 有 , 内 核 简 单 的 跳 过 这 条 转 发 / 重 定 向 规 则 。λ WCCP/GRE 包 被 正 确 解 开 了 吗 ?假 如 使 用 WCCP, 请 确 认 GRE 包 被 正 确 解 开 。 假 如 因 为 某 些 理 由 , 系 统 不 知 道 该 如 何 处 理 GRE包 , 那 就 在 netstat -s 的 输 出 里 会 见 到 "unknown/unsupported protocol" 计 数 器 在 增 长 。# netstat -s | grep unknown46 packets for unknown/unsupported protocol假 如 OS 有 GRE 接 口 , 请 频 繁 运 行 netstat -i 命 令 , 观 察 不 断 增 长 的 包 数 量 :


# netstat -in | grep ^gre0Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Collgre0 1476 ;304452 0 0 4 0另 外 , 在 GRE 接 口 上 运 行 tcpdump:# tcpdump -n -i gre0λ <strong>Squid</strong> 能 响 应 客 户 端 吗 ?有 可 能 路 由 器 / 交 换 机 能 发 送 包 到 squid, 但 squid 不 能 将 包 发 送 回 客 户 端 。 这 种 情 况 可 能 发 生在 : 防 火 墙 过 滤 规 则 拒 绝 外 出 数 据 包 , 或 squid 没 有 到 客 户 端 IP 地 址 的 路 由 。 为 了 检 查 这 种 情况 , 请 运 行 netstat -n 并 观 察 SYN_RCVD 状 态 的 sockets:% netstat -nActive Internet connectionsProto Recv-Q Send-Q Local Address Foreign Address (state)tcp4 0 0 10.102.129.246.80 10.102.0.1.36260 SYN_RCVDtcp4 0 0 10.102.129.226.80 10.102.0.1.36259 SYN_RCVDtcp4 0 0 10.102.128.147.80 10.102.0.1.36258 SYN_RCVDtcp4 0 0 10.102.129.26.80 10.102.0.2.36257 SYN_RCVDtcp4 0 0 10.102.129.29.80 10.102.0.2.36255 SYN_RCVDtcp4 0 0 10.102.129.226.80 10.102.0.1.36254 SYN_RCVDtcp4 0 0 10.102.128.117.80 10.102.0.1.36253 SYN_RCVDtcp4 0 0 10.102.128.149.80 10.102.0.1.36252 SYN_RCVD假 如 你 看 到 这 些 , 请 使 用 ping 和 traceroute 来 确 认 squid 能 与 客 户 端 双 向 通 信 。λ <strong>Squid</strong> 能 与 原 始 服 务 器 会 话 吗 ?假 如 squid 不 能 连 接 到 原 始 服 务 器 , 拦 截 HTTP 连 接 会 无 法 进 行 。 如 果 这 点 发 生 ,netstat 会 显示 许 多 连 接 在 SYN_SENT 状 态 :% netstat -nActive Internet connectionsProto Recv-Q Send-Q Local Address Foreign Address (state)tcp4 0 0 172.16.102.66.5217 10.102.129.145.80 SYN_SENTtcp4 0 0 172.16.102.66.5216 10.102.129.224.80 SYN_SENT


tcp4 0 0 172.16.102.66.5215 10.102.128.71.80 SYN_SENTtcp4 0 0 172.16.102.66.5214 10.102.129.209.80 SYN_SENTtcp4 0 0 172.16.102.66.5213 10.102.129.62.80 SYN_SENTtcp4 0 0 172.16.102.66.5212 10.102.129.160.80 SYN_SENTtcp4 0 0 172.16.102.66.5211 10.102.128.129.80 SYN_SENTtcp4 0 0 172.16.102.66.5210 10.102.129.44.80 SYN_SENTtcp4 0 0 172.16.102.66.5209 10.102.128.73.80 SYN_SENTtcp4 0 0 172.16.102.66.5208 10.102.128.43.80 SYN_SENT再 次 用 ping 和 traceroute 来 确 认 squid 能 与 原 始 服 务 器 会 话 。λ 外 出 连 接 正 被 拦 截 吗 ?假 如 squid 能 ping 通 原 始 服 务 器 , 并 且 仍 然 见 到 大 量 的 连 接 在 SYN_SENT 状 态 , 那 么 路 由 器/ 交 换 机 可 能 正 在 拦 截 squid 的 外 出 TCP 连 接 。 在 某 些 情 况 下 ,squid 能 检 测 到 这 种 转 发 循 环 ,并 写 警 告 日 志 到 cache.log。 如 此 的 转 发 死 循 环 能 迅 速 耗 光 squid 的 所 有 文 件 描 述 符 , 这 样 也会 在 cache.log 里 产 生 警 告 。假 如 你 怀 疑 这 个 问 题 , 请 使 用 squidclient 程 序 来 发 起 一 些 简 单 的 HTTP 请 求 。 例 如 , 该 命 令 发起 一 条 直 接 到 原 始 服 务 器 的 HTTP 请 求 :% /usr/local/squid/bin/squidclient -p 80 -h slashdot.org /假 如 该 命 令 成 功 , 你 可 以 在 屏 幕 上 见 到 来 自 Slashdot 站 点 的 许 多 难 看 的 HTML。 然 后 通 过 squid来 试 试 同 样 的 请 求 :% /usr/local/squid/bin/squidclient -r -p 3128 -h 127.0.0.1 http://slashdot.org/假 如 没 有 在 cache.log 里 看 到 错 误 消 息 , 就 可 以 再 次 在 屏 幕 上 看 到 一 些 HTML。 假 如 看 到 转 发循 环 错 误 , 就 必 须 重 新 配 置 交 换 机 / 路 由 器 , 以 便 它 允 许 squid 的 外 出 连 接 正 常 通 过 , 而 不 被 拦截 。

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!