我是靠谱客的博主 执着小松鼠,这篇文章主要介绍Netfilter ARP日志,现在分享给大家,希望可以做个参考。

定义ARP协议的日志结构nf_arp_logger,类型为NF_LOG_TYPE_LOG,处理函数为nf_log_arp_packet。目前内核支持的另一日志类型为NF_LOG_TYPE_ULOG。

复制代码
1
2
3
4
5
6
7
static struct nf_logger nf_arp_logger __read_mostly = { .name = "nf_log_arp", .type = NF_LOG_TYPE_LOG, .logfn = nf_log_arp_packet, .me = THIS_MODULE, };

由nf_log_register将以上日志结构添加到全局loggers数组中。对于各个命名空间,由nf_log_set将其添加到命名空间独立的nf_loggers数组中。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static int __net_init nf_log_arp_net_init(struct net *net) { return nf_log_set(net, NFPROTO_ARP, &nf_arp_logger); } static struct pernet_operations nf_log_arp_net_ops = { .init = nf_log_arp_net_init, .exit = nf_log_arp_net_exit, }; static int __init nf_log_arp_init(void) { int ret; ret = register_pernet_subsys(&nf_log_arp_net_ops); if (ret < 0) return ret; ret = nf_log_register(NFPROTO_ARP, &nf_arp_logger);

日志处理

默认的日志类型、级别和标志位NF_LOG_DEFAULT_MASK(0xf)。

复制代码
1
2
3
4
5
6
7
8
9
10
static const struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { .level = LOGLEVEL_NOTICE, .logflags = NF_LOG_DEFAULT_MASK, }, }, };

默认情况下,仅记录init_net命名空间的日志信息,要记录其它的命名空间日志,需打开nf_log_all_netns开关。

复制代码
1
2
3
4
5
6
# sysctl -a | grep nf_log_all_netns net.netfilter.nf_log_all_netns = 0 # # sysctl net.netfilter.nf_log_all_netns=1 net.netfilter.nf_log_all_netns = 1

日志处理函数中,首先分配日志缓存结构nf_log_buf。之后,打印报文的入接口和出接口信息,以及ARP协议的信息。最后,在nf_log_buf_close函数中打印缓存中的信息,释放分配的日志缓存。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static void nf_log_arp_packet(struct net *net, u_int8_t pf, unsigned int hooknum, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct nf_loginfo *loginfo, const char *prefix) { struct nf_log_buf *m; /* FIXME: Disabled from containers until syslog ns is supported */ if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns) return; m = nf_log_buf_open(); if (!loginfo) loginfo = &default_loginfo; nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix); dump_arp_packet(m, loginfo, skb, 0); nf_log_buf_close(m);

对于ARP协议,如果报文长度小于ARP协议的头部的长度,说明报文被截断。如果设置了NF_LOG_MACDECODE,记录报文的源和目的MAC地址,以及VLAN信息和协议。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
static void dump_arp_packet(struct nf_log_buf *m, const struct nf_loginfo *info, const struct sk_buff *skb, unsigned int nhoff) { const struct arppayload *ap; struct arppayload _arpp; const struct arphdr *ah; struct arphdr _arph; ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); if (ah == NULL) { nf_log_buf_add(m, "TRUNCATED"); return; } if (info->type == NF_LOG_TYPE_LOG) logflags = info->u.log.logflags; else logflags = NF_LOG_DEFAULT_MASK; if (logflags & NF_LOG_MACDECODE) { nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ", eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest); nf_log_dump_vlan(m, skb); nf_log_buf_add(m, "MACPROTO=%04x ", ntohs(eth_hdr(skb)->h_proto)); }

记录硬件地址类型(如Ethernet=1),协议地址类型(如IPv4=0x800)和操作码(如Request=1)。如果硬件地址类型等于Ethernet,并且硬件地址长度等于6,协议地址类型等于4,记录ARP协议的载荷信息。

ARP载荷信息包括发送者(sender)的MAC地址和IP地址,以及目标(target)的MAC地址和IP地址。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nf_log_buf_add(m, "ARP HTYPE=%d PTYPE=0x%04x OPCODE=%d", ntohs(ah->ar_hrd), ntohs(ah->ar_pro), ntohs(ah->ar_op)); /* If it's for Ethernet and the lengths are OK, then log the ARP payload. */ if (ah->ar_hrd != htons(ARPHRD_ETHER) || ah->ar_hln != ETH_ALEN || ah->ar_pln != sizeof(__be32)) return; ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); if (ap == NULL) { nf_log_buf_add(m, " INCOMPLETE [%zu bytes]", skb->len - sizeof(_arph)); return; } nf_log_buf_add(m, " MACSRC=%pM IPSRC=%pI4 MACDST=%pM IPDST=%pI4", ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst);

ARP日志显示

加载模块,将ARP协议(NFPROTO_ARP=3)的logger设置为nf_log_arp。

复制代码
1
2
3
4
5
# modprobe nf_log_arp # # sysctl net.netfilter.nf_log.3=nf_log_arp net.netfilter.nf_log.3 = nf_log_arp

加载的模块:

复制代码
1
2
3
4
$ lsmod | grep arp nf_log_arp 16384 0 nf_log_common 16384 2 nf_log_ipv4,nf_log_arp

nftables规则配置如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
# nft add table arp raw # nft add chain arp raw input { type filter hook input priority 0 ; } # nft add rule arp raw input log # # nft list table arp raw table arp raw { chain input { type filter hook input priority filter; policy accept; log } }

查看/var/log/kern.log,其中记录的ARP报文日志,如下:

复制代码
1
2
3
4
# tail -f /var/log/kern.log Feb 13 14:39:42 advanced kernel: [ 8232.798264] IN=ens33 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=54:a7:03:16:55:c2 IPSRC=192.168.3.123 MACDST=00:00:00:00:00:00 IPDST=192.168.3.36 Feb 13 14:39:42 advanced kernel: [ 8232.801235] IN=ens33 OUT= ARP HTYPE=1 PTYPE=0x0800 OPCODE=1 MACSRC=54:a7:03:16:55:c2 IPSRC=192.168.3.123 MACDST=00:00:00:00:00:00 IPDST=192.168.3.1

内核版本 5.10

最后

以上就是执着小松鼠最近收集整理的关于Netfilter ARP日志的全部内容,更多相关Netfilter内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(88)

评论列表共有 0 条评论

立即
投稿
返回
顶部