iptables实现IPMAC绑定

22 篇文章 0 订阅

主机192.168.1.201的MAC地址如下:

$ ip address
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:38:40:6b brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.201/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

在另外一台主机上配置如下的规则,如果检测到192.168.1.201的MAC地址不等于00:0c:29:38:40:6b,表明为假冒的主机192.168.1.201,将报文丢弃。

# iptables -A INPUT -s 192.168.1.201 -m mac ! --mac-source 00:0c:29:38:40:6b -j DROP 
#
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  192.168.1.201        anywhere             MAC ! 00:0C:29:38:40:6B

将第三台主机的接口IP地址设置为192.168.1.201,ping以上配置了IPMAC绑定的主机,没有响应。查看规则信息,如下丢弃了6个报文:

# iptables -L -v -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   504 DROP       all  --  *      *       192.168.1.201        0.0.0.0/0            MAC ! 00:0C:29:38:40:6B

注意,以上规则配置于INPUT点,对于ARP请求是不生效的。另外,IPMAC绑定也可以配置在FORWARD点,用于检测转发的流量。不支持配置在OUTPUT点。

# iptables -A FORWARD -s 192.168.1.201 -m mac ! --mac-source 00:0c:29:38:40:6b -j DROP 

MAC扩展

函数mac_mt_init注册了匹配结构mac_mt_reg。可知以上iptables命令中的mac选项(-m mac)可应用在PREROUTING,LOCAL_IN和FORWARD三个hook中。

static struct xt_match mac_mt_reg __read_mostly = {
    .name      = "mac",
    .revision  = 0,
    .family    = NFPROTO_UNSPEC,
    .match     = mac_mt,
    .matchsize = sizeof(struct xt_mac_info),
    .hooks     = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
                 (1 << NF_INET_FORWARD),
    .me        = THIS_MODULE,
};
static int __init mac_mt_init(void)
{
    return xt_register_match(&mac_mt_reg);
}

匹配处理函数mac_mt如下,对于以太网设备,在MAC头部合法的情况下,判断其中源MAC地址是否与配置的MAC相等,考虑取反的情况(如以上的取反符号 !),返回匹配结果。

注意,不能对目的MAC地址进行匹配(路由情况下,目的MAC通常为路由器自身地址)。

static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
    const struct xt_mac_info *info = par->matchinfo;
    bool ret;

    if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
        return false;
    if (skb_mac_header(skb) < skb->head)
        return false;
    if (skb_mac_header(skb) + ETH_HLEN > skb->data)
        return false;
    ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
    ret ^= info->invert;
    return ret;

内核版本 5.10

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于 java开发 的学习思路及方向。从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。

由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的 点击我的Gitee获取
还有 高级java全套视频教程 java进阶架构师 视频+资料+代码+面试题!

全方面的java进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值