资讯详情

iptables匹配connlimit限制并发连接数量

每一个都会有以下规则IP最大并发连接数控制在5个,使用connlimit-above或者connlimit-upto都可实现。

# iptables -I INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 5 -j DROP  #  # iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes)  pkts bytes target     prot opt in     out     source               destination              0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 flags:0x17/0x02 #conn src/32 > 5 # # # iptables -I INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-upto 5 -j ACCEPT #  # iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes)  pkts bytes target     prot opt in     out     source               destination              0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 flags:0x17/0x02 #conn src/32 <= 5 

每个C网段的所有地址连接总数控制在5个。

# iptables -I INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 5 --connlimit-mask 24 -j DROP  #  # iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes)  pkts bytes target     prot opt in     out     source               destination              0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 flags:0x17/0x02 #conn src/24 > 5 

默认情况下–connlimit-saddr以下指定生效–connlimit-daddr,连接到每个目的地址的数量不超过5个。

# iptables -I INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 5 --connlimit-daddr -j DROP         #  # iptables -L -n -v Chain INPUT (policy ACCEPT 0 packets, 0 bytes)  pkts bytes target     prot opt in     out     source               destination              0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 flags:0x17/0x02 #conn dst/32 > 5 

connlimit匹配

内核函数connlimit_mt_init注册了connlimit_mt_reg匹配结构。

static struct xt_match connlimit_mt_reg __read_mostly = {     .name       = "connlimit",     .revision   = 1,     .family     = NFPROTO_UNSPEC,     .checkentry = connlimit_mt_check,     .match      = connlimit_mt,     .matchsize  = sizeof(struct xt_connlimit_info),     .usersize   = offsetof(struct xt_connlimit_info, data),     .destroy    = connlimit_mt_destroy,     .me         = THIS_MODULE, }; static int __init connlimit_mt_init(void) {     return xt_register_match(&connlimit_mt_reg); } 

检查函数的配置connlimit_mt_check以下是这里的初始化conncount相关结构,keylen包括zone区ID以及相应协议组的地址长度。

static int connlimit_mt_check(const struct xt_mtchk_param *par) {     struct xt_connlimit_info *info = par->matchinfo;     unsigned int keylen;      keylen = sizeof(u32);     if (par->family == NFPROTO_IPV6)         keylen  = sizeof(struct in6_addr);     else         keylen  = sizeof(struct in_addr);      /* init private data */     info->data = nf_conncount_init(par->net, par->family, keylen);      return PTR_ERR_OR_ZERO(info->data); 

匹配函数connlimit_mt,如果报纸有连接跟踪结构,请取出原始方向tuple,否则,分析报文tuple,分析失败,返回false,未能匹配。

static bool connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) {     const struct xt_connlimit_info *info = par->matchinfo;     struct nf_conntrack_tuple tuple;     const struct nf_conntrack_tuple *tuple_ptr = &tuple;     const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt;     const struct nf_conn *ct;     u32 key[5];      ct = nf_ct_get(skb, &ctinfo);     if (ct != NULL) {         tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;         zone = nf_ct_zone(ct);     } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),                       xt_family(par), net, &tuple)) {         goto hotdrop;     } 

否则,成功获得报文的tuple信息,对于IPv6.如果设置XT_CONNLIMIT_DADDR标志(–connlimit-daddr),key选择报纸的目的地地址,否则,选择源地址。

    if (xt_family(par) == NFPROTO_IPV6) {         const struct ipv6hdr *iph = ipv6_hdr(skb);         union nf_inet_addr addr;          memcpy(&addr.ip6, (info->flags & XT_CONNLIMIT_DADDR) ?                &iph->daddr : &iph->saddr, sizeof(addr.ip6));          for (i = 0; i < ARRAY_SIZE(addr.ip6);   i)             addr.ip6[i] &= info->mask.ip6[i];         memcpy(key, &addr, sizeof(addr.ip6));         key[4] = zone->id;     } else {         const struct iphdr *iph = ip_hdr(skb);         key[0] = (info->flags & XT_CONNLIMIT_DADDR) ?               iph->daddr : iph->saddr;         key[0] &= info->mask.ip;         key[1] = zone->id;     }

对于IPv4协议,处理与以上相同,另外,key值中的地址部分需要与配置的掩码进行与操作(&)。之后,由key值和tuple值来获取连接的数量,最后,检查是否满足限制条件。

   connections = nf_conncount_count(net, info->data, key, tuple_ptr, zone);
   if (connections == 0)
       /* kmalloc failed, drop it entirely */
       goto hotdrop;

   return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT);

hotdrop:
   par->hotdrop = true;
   return false;

内核版本 5.10

标签: 压差传感器dpt0100u1二极管dflt48a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台