Linux NFLOG - 文档、C 语言配置

Linux NFLOG - 文档、C 语言配置

几个不同的地方(例如http://wiki.wireshark.org/CaptureSetup/NFLOG)建议使用Linux的“NFLOG”防火墙模块来捕获特定UID生成的数据包,如下所示:

# iptables -A OUTPUT -m owner --uid-owner 1000 -j CONNMARK --set-mark 1
# iptables -A INPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m connmark --mark 1 -j NFLOG --nflog-group 30 
# dumpcap -i nflog:30 -w uid-1000.pcap

我还没有找到任何关于其具体工作原理的文档(特别是,netfilter.org有大量写得很差的库 API 文档,而且据我所知,根本没有关于实际内核级防火墙规则语义的内容),所以我有几个问题:

  1. 有任何该死的文件吗?它藏在哪里?

  2. CONNMARK 真的有必要吗?也就是说,这个也能起到同样的作用吗?

    # iptables -A INPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30 
    # iptables -A OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30
    
  3. 是否必须运行“ulogd”才能实现此功能?

  4. 有没有办法告诉内核为我选择一个未分配的组号并告诉我它是什么?

  5. 有没有办法告诉内核,当进程 X 终止时,这些过滤规则应该被自动删除?(进程 X 将不是以 uid 1000 运行。)

  6. 假设该iptables命令会进行一些特殊ioctl调用或配置防火墙。是否有一个 C 库可用于在程序中执行相同操作(即 Q4 中的“进程 X”)?

答案1

有任何该死的文件吗?它藏在哪里?

netfilter 网站上有一些示例,可以帮助解释该功能。这是我用自己的代码编写的函数,用于设置 netfilter NFLOG。

以下是他们提供的示例:https://www.netfilter.org/projects/libnetfilter_log/doxygen/html/files.html

void setup_netlogger_loop(
    int groupnum,
    queue_t queue)
{
  int sz;
  int fd = -1;
  char buf[BUFSZ];
  /* Setup handle */
  struct nflog_handle *handle = NULL;
  struct nflog_g_handle *group = NULL;

  memset(buf, 0, sizeof(buf));

  /* This opens the relevent netlink socket of the relevent type */
  if ((handle = nflog_open()) == NULL){
    sd_journal_perror("Could not get netlink handle");
    exit(EX_OSERR);
  }

  /* We tell the kernel that we want ipv4 tables not ipv6 */
  if (nflog_bind_pf(handle, AF_INET) < 0) {
    sd_journal_perror("Could not bind netlink handle");
    exit(EX_OSERR);
  }

  /* Setup groups, this binds to the group specified */
  if ((group = nflog_bind_group(handle, groupnum)) == NULL) {
    sd_journal_perror("Could not bind to group");
    exit(EX_OSERR);
  }
  if (nflog_set_mode(group, NFULNL_COPY_PACKET, 0xffff) < 0) {
    sd_journal_perror("Could not set group mode");
    exit(EX_OSERR);
  }
  if (nflog_set_nlbufsiz(group, BUFSZ) < 0) {
    sd_journal_perror("Could not set group buffer size");
    exit(EX_OSERR);
  }
  if (nflog_set_timeout(group, 1500) < 0) {
    sd_journal_perror("Could not set the group timeout");
  }

  /* Register the callback */
  nflog_callback_register(group, &queue_push, (void *)queue);

  /* Get the actual FD for the netlogger entry */
  fd = nflog_fd(handle);

  /* We continually read from the loop and push the contents into
     nflog_handle_packet (which seperates one entry from the other),
     which will eventually invoke our callback (queue_push) */    
  for (;;) {
    sz = recv(fd, buf, BUFSZ, 0);
    if (sz < 0 && errno == EINTR)
      continue;
    else if (sz < 0)
      break;

    nflog_handle_packet(handle, buf, sz);
  }
}

CONNMARK 真的有必要吗?也就是说,这个也能起到同样的作用吗?

这是没有必要的。

是否必须运行“ulogd”才能实现此功能?

不——事实上我没有在这个应用程序中使用它。

有没有办法告诉内核为我选择一个未分配的组号并告诉我它是什么?

据我所知没有。无论如何,如果您为 HTTP 设置了 NFLOG 目标,一个用于记录丢弃的 FTP 数据包,另一个用于扫描 SMTP 字符串,那么这将毫无用处。在这种情况下,您无法确定哪条规则绑定到哪个组,因此应该监听哪个组。

有没有办法告诉内核当进程 X 终止时这些过滤规则应该被自动删除?(进程 X 不会以 uid 1000 运行。)

不会,但内核只会填充缓冲区到最大大小,然后才会丢弃数据。它不会因未遵循规则而占用过多内存而对性能造成影响。

iptables 命令可能进行了一些特殊的 ioctl 调用或其他操作来配置防火墙。是否有一个 C 库可用于在程序中执行相同操作(即 Q4 中的“进程 X”)?

据我所知,没有哪个 netfilter 库可以帮助您操纵规则。不过,有一个内部驱动的库可以代替它。

IPtables 继承了一种与用户空间通信的相当古老的方法——打开一个 SOCK_RAW IP 套接字来与其通信。nftables 将完全删除此方法(因为这样做毫无意义),nftables 将通过 netlink 进行通信以完成相同的操作。

答案2

具体回答这部分:

CONNMARK 真的有必要吗?也就是说,这个也能起到同样的作用吗?

# iptables -A INPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30 
# iptables -A OUTPUT -m owner --uid-owner 1000 -j NFLOG --nflog-group 30

是的,这是必要的。不,您的建议不会匹配任何传入数据包(也许它确实匹配本地计算机上的流量,但肯定不会匹配外部网络流量)。

只有本地传出数据包才有关联的所有者。在 INPUT 链的早期,所有者信息不可用,因为数据包仍在路由。为了匹配与传出流相关的传入数据包,必须在 OUTPUT 链中标记“连接”,随后可以在 INPUT 链上进行匹配。

另请参阅iptables-extensions手册页:

所有者

owner模块仅匹配原始套接字。这意味着

此模块尝试匹配本地生成的数据包的数据包创建者的各种特征。此匹配仅在 OUTPUT 和 POSTROUTING 链中有效。转发的数据包没有与之关联的任何套接字。来自内核线程的数据包确实有套接字,但通常没有所有者。

(同样的警告也适用于 nftables。)

相关内容