栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Netfilter ARP日志

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netfilter ARP日志

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

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数组中。

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)。

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开关。

# 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函数中打印缓存中的信息,释放分配的日志缓存。

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;

    
    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信息和协议。

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地址。

    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 (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。

# modprobe nf_log_arp
#
# sysctl net.netfilter.nf_log.3=nf_log_arp
net.netfilter.nf_log.3 = nf_log_arp

加载的模块:

$ lsmod | grep arp        
nf_log_arp             16384  0
nf_log_common          16384  2 nf_log_ipv4,nf_log_arp

nftables规则配置如下:

# 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报文日志,如下:

# 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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/746724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号