> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/man5/pf.os.5.md).

# pf.os(5)

`pf.os` — 操作系统指纹文件格式

## 名称

`pf.os`

## 描述

[pf(4)](/man4/pf.4.md) 防火墙和 [tcpdump(1)](/man1/tcpdump.1.md) 程序都可以对发起 IPv4 TCP 连接的主机进行操作系统指纹识别。该文件由换行符分隔的记录组成，每个指纹一条记录，包含九个以冒号（`:`）分隔的字段。这些字段如下：

**window** TCP 窗口大小。

**TTL** IP 生存时间。

**df** IPv4 不分片位的存在。

**packet** size 初始 TCP 数据包的大小。

**TCP** options TCP 选项的有序列表。

**class** 操作系统的类别。

**version** 操作系统的版本。

**subtype** 操作系统版本子类型或补丁级别。

**description** 操作系统、版本和子类型的整体文本描述。

`window` 字段对应 TCP 头中的 th->th\_win 字段，是源主机通告的 TCP 窗口大小。它可以在零到 65,535 之间（含）。窗口大小可以通过在大小前加上百分号 ‘%’ 作为常数的倍数给出，该值将用作模数。窗口大小可以使用三个特殊值：

\*\*\*\*\* 星号将通配该值，因此任何窗口大小都会匹配。

**S** 允许任何为最大段大小（MSS）倍数的窗口大小。

**T** 允许任何为最大传输单元（MTU）倍数的窗口大小。

`ttl` 值是 IP 头中的初始生存时间。指纹代码会考虑数据包穿越网络时 TTL 的波动。

`df` 位对应于 IPv4 头中的不分片位。它告诉中间路由器不要对数据包分片，并用于路径 MTU 发现。它可以是零或一。

`packet size` 是完整 IP 数据包的字面大小，是所有 IP 和 TCP 选项的函数。

`TCP options` 字段是 SYN 数据包中出现的各个 TCP 选项的有序列表。每个选项由单个字符描述，用逗号分隔，某些选项可能包含值。这些选项是：

**Mnnn** 最大段大小（MSS）选项。该值是网络链路的最大数据包大小，可以包括 ‘%’ 模数或使用 ‘\*’ 值匹配所有 MSS。

**N** NOP 选项（无操作）。

**T\[0]** 时间戳选项。某些操作系统始终从零时间戳开始，在这种情况下，向选项添加零值；否则不附加值。

**S** 选择性确认正常（SACKOK）选项。

**Wnnn** 窗口缩放选项。该值是窗口缩放的大小，可以包括 ‘%’ 模数或使用 ‘\*’ 值匹配所有窗口缩放。

指纹中没有 TCP 选项时可以使用单个点 ‘.’ 给出。

OpenBSD 的 TCP 选项示例：

```sh
M*,N,N,S,N,W0,N,N,T
```

第一个选项 `M*` 是 MSS 选项，将匹配所有值。第二个和第三个选项 `N` 将匹配两个 NOP。第四个选项 `S` 将匹配 SACKOK 选项。第五个 `N` 将匹配另一个 NOP。第六个 `W0` 将匹配缩放大小为零的窗口缩放选项。第七个和第八个 `N` 选项将匹配两个 NOP。第九个也是最后一个选项 `T` 将匹配任何时间值的时间戳选项。

指纹中的 TCP 选项仅匹配具有相同顺序的完全相同 TCP 选项的数据包。

`class` 字段是操作系统的类别、类型或供应商。

`version` 是操作系统的版本。它用于区分相同类别但不同版本的操作系统指纹。

`subtype` 是操作系统版本的子类型或补丁级别。它用于区分相同类别和相同版本但补丁或调整略有不同的操作系统指纹。

`description` 是操作系统、其版本、补丁级别和任何其他有用细节的一般描述。

## 实例

普通 OpenBSD 3.3 主机的指纹是：

```sh
  16384:64:1:64:M*,N,N,S,N,W0,N,N,T:OpenBSD:3.3::OpenBSD 3.3
```

在使用带有 no-df 规则的 PF 清理防火墙后面的 OpenBSD 3.3 主机的指纹将是：

```sh
  16384:64:0:64:M*,N,N,S,N,W0,N,N,T:OpenBSD:3.3:!df:OpenBSD 3.3 scrub no-df
```

一个绝对愚蠢的嵌入式操作系统指纹可能是：

```sh
  65535:255:0:40:.:DUMMY:1.1:p3:Dummy embedded OS v1.1p3
```

[tcpdump(1)](/man1/tcpdump.1.md) 的输出

```sh
  # tcpdump -s128 -c1 -nv 'tcp[13] == 2'
  03:13:48.118526 10.0.0.1.3377 > 10.0.0.2.80: S [tcp sum ok] \
      534596083:534596083(0) win 57344 <mss 1460> (DF) [tos 0x10] \
      (ttl 64, id 11315, len 44)
```

几乎可以转换为以下指纹

```sh
  57344:64:1:44:M1460:	exampleOS:1.0::exampleOS 1.0
```

## 参见

[tcpdump(1)](/man1/tcpdump.1.md), [pf(4)](/man4/pf.4.md), [pf.conf(5)](/man5/pf.conf.5.md), pfctl(8)
