--------------------------------------------------------------------------------
目录
介绍
记录数据包
阅读日志文件
过滤日志输出
通过Syslog记录数据包
--------------------------------------------------------------------------------
介绍
当PF记录一个数据包时, 数据包头的拷贝被发送到 pflog(4) 接口, 同时还有一些额外的信息, 像数据包经过的接口, PF采取的动作(放行或禁止), 等。pflog(4) 接口允许用户空间的应用程序从内核接收PF的记录数据。如果系统启动时启用了PF, 守护进程 pflogd(8) 就会启动。默认 pflogd(8) 监听 pflog0 接口并将所有记录的数据写到日志文件 /var/log/pflog 中。
记录数据包
为了记录通过PF的数据包, 必须在 NAT/rdr 和 filter 规则里使用 log 关键字。注意PF只能记录那些自己放行或禁止的数据包;你不能指定一条规则仅记录数据包。
log 关键字将使所有匹配此规则的数据包被记录。这种情形下如果这条规则产生了状态, 仅有看见的第一个数据包(导致产生状态的数据包)会被记录。
可以提供给 log 关键字的选项是:
all
将使所有的匹配数据包, 而非仅有初始化数据包被记录。对产生状态的规则很有用。
to pflogN
将所有的匹配数据包记录到指定的 pflog(4) 接口。例如, 当使用 spamlogd(8) 时, PF将所有的SMTP通讯记录到专用的 pflog(4) 接口。守护进程 spamlogd(8) 被告知监听哪个接口。这可以使PF的主日志文件里没有SMTP通讯的记录而且它们也没有必要被记录在主日志里。使用 ifconfig(8) 来建立 pflog(4) 接口, 默认的记录接口 pflog0 是自动创建的。
user
将UNIX的user-id和group-id拥有的套接字, 数据包的sourced from/destined to(无论具体位置)与常规的记录信息一同记录下来。
选项在 log 关键字的后面的圆括号内给出;多个选项可以用逗号或空格分开。
代码: 全选
pass in log (all, to pflog1) on $ext_if inet proto tcp to $ext_if port 22 keep state
阅读日志文件
pflogd写入的日志文件是二进制格式, 不能使用文本编辑器阅读。想阅读日志必须使用Tcpdump。
查看日志文件:
代码: 全选
# tcpdump -n -e -ttt -r /var/log/pflog
注意, 用tcpdump(8)看pflog文件时并不是实时显示的。要完成一个记录数据包的实时日志显示必须使用 pflog0 接口:
代码: 全选
# tcpdump -n -e -ttt -i pflog0
注意: 当试验日志时, 要特别小心tcpdump的详细协议解码(通过在命令行里增加 -v 选项)。Tcpdump的协议解码器并没有完美的安全历史。 至少在理论上, 通过日志设备记录的部分数据包信息可能发起一个延时的攻击。 推荐的标准做法是在进行试验前将日志文件从防火墙所在机器移出来。
另一个需要注意的是安全地访问日志文件。默认情况下, pflogd 把数据包的96个字节记录在日志文件里, 访问日志文件就能访问数据包的部分敏感信息(像 telnet(1) 或 ftp(1) 的用户名和密码等).
过滤输出日志
因为pflogd记录采用tcpdump二进制格式, 当查看这些记录时可以使用tcpdump的全部功能。例如, 例如只查看匹配一个特定端口的数据包:
代码: 全选
# tcpdump -n -e -ttt -r /var/log/pflog port 80
可以通过指定到特定主机和端口的数据包得到更精确的结果:
代码: 全选
# tcpdump -n -e -ttt -r /var/log/pflog port 80 and host 192.168.1.3
同样, 这种思路也可以用在从pflog0接口读取:
代码: 全选
# tcpdump -n -e -ttt -i pflog0 host 192.168.4.2
注意, 这并不影响数据包被记录到pflogd的日志文件; 上面的命令仅显示正在被记录的数据包。
除了使用标准的 tcpdump(8) 过滤规则, 为了阅读pflogd的输出tcpdump过滤语言代码已经进行的扩展:
ip - 地址族是IPv4。
ip6 - 地址族是IPv6。
on int - 数据包经过接口int。
ifname int - 同上。
ruleset name - 数据包匹配的规则集/锚。
rulenum num - 数据包匹配的过滤规则号码 num。
action act - 对数据包执行的动作。可能的动作是 pass 和 block。
reason res - 执行动作的原因。可能的原因是match, bad-offset, fragment, short, normalize, memory, bad-timestamp, congestion, ip-option, proto-cksum, state-mismatch, state-insert, state-limit, src-limit, 和 synproxy。
inbound - 数据包进站。
outbound - 数据包出站。
例如:
代码: 全选
# tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0
这将实时显示在wi0接口上被阻止的进站数据包的记录。
通过Syslog记录数据包
在许多情况下, 我们希望有ASCII格式的防火墙日志和/或把它们发送到一个远程日志服务器。所有这些可以通过用一个小的 shell 脚本, OpenBSD配置文件的一些小改动, 以及守护进程 syslogd(8) 来完成。Syslogd以ASCII格式记录并可以发送到一个远程日志服务器上。
创建下列脚本:
代码: 全选
/etc/pflogrotate
#!/bin/sh
PFLOG=/var/log/pflog
FILE=/var/log/pflog5min.$(date "+%Y%m%d%H%M")
kill -ALRM $(cat /var/run/pflogd.pid)
if [ -r $PFLOG ] && [ $(stat -f %z $PFLOG) -gt 24 ]; then
mv $PFLOG $FILE
kill -HUP $(cat /var/run/pflogd.pid)
tcpdump -n -e -ttt -r $FILE | logger -t pf -p local0.info
rm $FILE
fi
编辑 root 的 定时任务cron job:
代码: 全选
# crontab -u root -e
加上下面的两行:
代码: 全选
# rotate pf log file every 5 minutes
0-59/5 * * * * /bin/sh /etc/pflogrotate
将下面这行加到/etc/syslog.conf:
代码: 全选
local0.info /var/log/pflog.txt
如果你还想记录到一个远程日志服务器上, 加上这行:
代码: 全选
local0.info @syslogger
确定主机 syslogger 已经在 hosts(5) 文件中被定义过了。
创建文件 /var/log/pflog.txt 以允许syslog记录到那个文件, 并赋予它和pflog文件同样的权限。
代码: 全选
# touch /var/log/pflog.txt
# chmod 600 /var/log/pflog.txt
重新启动syslogd以使其应用新配置:
代码: 全选
# kill -HUP $(cat /var/run/syslog.pid)
所有记录的数据包现在被发送到 /var/log/pflog.txt。如果增加了第二行(译者注:这里应该是指 "local0.info @syslogger" 这行), 它们也会被发送到远程的日志主机 syslogger 上。
脚本 /etc/pflogrotate 现在运行, 然后删除 /var/log/pflog, 所以通过 newsyslog(8) 对pflog进行归档转储也就不再有必要了, 应禁用。 然而, 因为 /var/log/pflog.txt 代替/var/log/pflog 存贮记录的日志, 所以对 /var/log/pflog.txt 的归档转储应该被激活。像这样更改 /etc/newsyslog.conf:
代码: 全选
#/var/log/pflog 600 3 250 * ZB /var/run/pflogd.pid <------禁用对pflog的归档转储
/var/log/pflog.txt 600 7 * 24 <------启用对pflog.txt的归档转储
PF将日志以ASCII格式记录到 /var/log/pflog.txt 文件。如果在 /etc/syslog.conf 内也做了这样的配置, 日志也将被记录到一台远程的日志服务器上。记录不会马上开始, 当开始记录后约5-6分钟 (定时任务间隔) 被记录的数据包才会出现在日志文件中。