#freebsd #pf #networking #packet-filter

pf-rs

FreeBSD库,通过/dev/pf直接访问OpenBSD的PF(包过滤器)实现

3个版本

13.2.1 2023年8月22日
13.0.4 2022年4月22日
13.0.2 2021年8月6日
0.2.4 2024年2月6日
0.2.3 2023年12月4日

#3 in #pf

Download history 21/week @ 2024-03-29

每月下载量 53

BSD-2-Clause

100KB
2K SLoC

#pf-rs

V 0.2.2 - 更新以支持FREEBSD 14.0-RELEASE。

一个提供用户空间接口的crate,允许用户直接控制PF(包过滤器),而无需每次需要阻止网络主机或检查列表时都执行pfctl(8)

这是一个实验性crate,并在"logdaemon"项目中使用。

目前支持以下功能

  • 在表格(目前为IP/IPv6/DNS的IP列表)上添加、删除、测试命令
  • 从文件中添加、删除、测试表格命令(目前为IP/IPv6/DNS的IP列表)
  • 通过源IP或源IP和目标IP杀死状态
  • 刷新表格

优先级待办事项列表

  • 添加表格重新加载命令(需要配置解析器)
  • 添加完整重新加载命令(需要配置解析器)
  • 添加配置测试命令(需要配置解析器)
  • 考虑使用安全的列表类型进行c链接列表,如果它不是以这种方式传递给PF内核模块。

代码安全性。

由于它使用了许多C结构,此crate使用了大量的unsafe代码。

可能有些方法,如std::mem::zeroed()可能会出现问题,但只有在某些情况下才成立。

因此,以下列出了使用的代码方法以及为什么认为它足够安全。

结构初始化中使用std::mem::zeroed()

在大多数情况下,所有结构都需要用零初始化。这也很有用,因为它可能包含固定字符串缓冲区,在C中字符串始终以null终止,以及在某些情况下需要指向NULL的指针。
此方法可以用于不包含引用的结构!

指针操作

在处理原始指针时,最好跟踪任何C代码在何处初始化内存并在适当的时候通过free()或专门提供的函数释放它。

填充

在某些情况下,Rust可能会将结构填充到不是n^2,而是例如44,而C会将其填充到48。

示例


fn test()
{
  let pf = Pf::new(false).unwrap();

  let res = pf.pfctl_table("table_test", PfCmd::Add{ hosts: vec!["192.168.2.44".to_string()] }).unrap();

  if res == 1
  {
    println!("added!");
  }
  else
  {
    println!("was not added, but no error generated");
  }
}

依赖项

~1.5MB
~35K SLoC