使用iptables进行速率限制会产生错误

使用iptables进行速率限制会产生错误,iptables,Iptables,由于大量机器人每秒访问我的web服务器的次数过多,我进入我的服务器并发出以下命令,试图在5秒内将连接限制在最多25次。我可能需要更严格,但我不是因为我有一个页面很少被访问,需要50张图片,可能需要51个连接,我不希望用户永远等待剩下的26张图片 iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set iptables -I INPUT -p tcp --dport 80 -i eth0 -m

由于大量机器人每秒访问我的web服务器的次数过多,我进入我的服务器并发出以下命令,试图在5秒内将连接限制在最多25次。我可能需要更严格,但我不是因为我有一个页面很少被访问,需要50张图片,可能需要51个连接,我不希望用户永远等待剩下的26张图片

iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 5 --hitcount 26 -j DROP
第一个命令在使用iptables-nL进行验证后工作,但第二个命令立即返回以下消息:“iptables:无效参数。有关详细信息,请运行'dmesg'

一旦我执行了它,我会在它结束时收到以下信息:

Call Trace:
<IRQ>  [<ffffffff8112f7ba>] ? __alloc_pages_nodemask+0x74a/0x8d0
[<ffffffff81299270>] ? swiotlb_map_page+0x0/0x100
[<ffffffff8116e282>] ? kmem_getpages+0x62/0x170
[<ffffffff8116ee9a>] ? fallback_alloc+0x1ba/0x270
[<ffffffff8116e8ef>] ? cache_grow+0x2cf/0x320
[<ffffffff8116ec19>] ? ____cache_alloc_node+0x99/0x160
[<ffffffff8116fb9b>] ? kmem_cache_alloc+0x11b/0x190
[<ffffffff8144d058>] ? sk_prot_alloc+0x48/0x1c0
[<ffffffff8144e262>] ? sk_clone+0x22/0x2e0
[<ffffffff8149ff16>] ? inet_csk_clone+0x16/0xd0
[<ffffffff814b97d3>] ? tcp_create_openreq_child+0x23/0x470
[<ffffffff814b6f8d>] ? tcp_v4_syn_recv_sock+0x4d/0x310
[<ffffffff814b9576>] ? tcp_check_req+0x226/0x460
[<ffffffff814b69cb>] ? tcp_v4_do_rcv+0x35b/0x490
[<ffffffffa0322557>] ? ipv4_confirm+0x87/0x1d0 [nf_conntrack_ipv4]
[<ffffffff814b825a>] ? tcp_v4_rcv+0x51a/0x900
[<ffffffff81495270>] ? ip_local_deliver_finish+0x0/0x2d0
[<ffffffff8149534d>] ? ip_local_deliver_finish+0xdd/0x2d0
[<ffffffff814955d8>] ? ip_local_deliver+0x98/0xa0
[<ffffffff81494a9d>] ? ip_rcv_finish+0x12d/0x440
[<ffffffff81495025>] ? ip_rcv+0x275/0x350
[<ffffffff8145c3eb>] ? __netif_receive_skb+0x4ab/0x750
[<ffffffff81460058>] ? netif_receive_skb+0x58/0x60
[<ffffffff81460160>] ? napi_skb_finish+0x50/0x70
[<ffffffff814618c9>] ? napi_gro_receive+0x39/0x50
[<ffffffffa024e267>] ? e1000_receive_skb+0x67/0x110 [e1000e]
[<ffffffffa0250e6f>] ? e1000_clean_rx_irq+0x37f/0x580 [e1000e]
[<ffffffffa025397d>] ? e1000e_poll+0x8d/0x2d0 [e1000e]
[<ffffffff814619e3>] ? net_rx_action+0x103/0x2f0
[<ffffffff8107a5f1>] ? __do_softirq+0xc1/0x1e0
[<ffffffff810e6c60>] ? handle_IRQ_event+0x60/0x170
[<ffffffff8107a64f>] ? __do_softirq+0x11f/0x1e0
[<ffffffff8100c30c>] ? call_softirq+0x1c/0x30
[<ffffffff8100fa75>] ? do_softirq+0x65/0xa0
[<ffffffff8107a4a5>] ? irq_exit+0x85/0x90
[<ffffffff81532525>] ? do_IRQ+0x75/0xf0
[<ffffffff8100b9d3>] ? ret_from_intr+0x0/0x11
<EOI>
呼叫跟踪:
[] ? __alloc_pages_nodemask+0x74a/0x8d0
[] ? swiotlb_地图_页面+0x0/0x100
[] ? kmem_getpages+0x62/0x170
[] ? 后备分配+0x1ba/0x270
[] ? 缓存增长+0x2cf/0x320
[] ? ____缓存分配节点+0x99/0x160
[] ? kmem_缓存_分配+0x11b/0x190
[] ? sk_prot_alloc+0x48/0x1c0
[] ? sk_克隆+0x22/0x2e0
[] ? inet\u csk\u克隆+0x16/0xd0
[] ? tcp_创建_openreq_子级+0x23/0x470
[] ? tcp_v4_syn_recv_sock+0x4d/0x310
[] ? tcp检查请求+0x226/0x460
[] ? tcp_v4_do_rcv+0x35b/0x490
[] ? ipv4\u确认+0x87/0x1d0[nf\u连接\u ipv4]
[] ? tcp_v4_rcv+0x51a/0x900
[] ? ip_本地_交付_完成+0x0/0x2d0
[] ? ip_本地_交付_完成+0xdd/0x2d0
[] ? ip_本地_交付+0x98/0xa0
[] ? ip_rcv_饰面+0x12d/0x440
[] ? ip_rcv+0x275/0x350
[] ? __netif_接收skb+0x4ab/0x750
[] ? netif_接收skb+0x58/0x60
[] ? napi_skb_饰面+0x50/0x70
[] ? napi_gro_接收+0x39/0x50
[] ? e1000接收skb+0x67/0x110[e1000e]
[] ? e1000清洁接收irq+0x37f/0x580[e1000e]
[] ? e1000e_轮询+0x8d/0x2d0[e1000e]
[] ? 净接收动作+0x103/0x2f0
[] ? __do_软件IRQ+0xc1/0x1e0
[] ? 处理IRQ事件+0x60/0x170
[] ? __do_softirq+0x11f/0x1e0
[] ? 呼叫软件IRQ+0x1c/0x30
[] ? do_softirq+0x65/0xa0
[] ? irq_出口+0x85/0x90
[] ? do_IRQ+0x75/0xf0
[] ? 从\u intr+0x0/0x11返回

之前的内容涉及usb设备和其他系统设备。有人能告诉我如何在不发生随机错误的情况下成功限制传入连接的速率吗?

执行
dmesg
可以揭示错误的原因:

[78482.351825]xt_最近:命中率(26)大于要记住的数据包(20)

这意味着
iptables
recent
模块仅限于记忆20个数据包。为了解决此问题,您可以执行以下任一操作:

  • iptables
    规则中的
    hitcount
    参数的值从26减少到20或更少。
  • 通过设置
    xt\u recent
    内核模块的选项
    ip\u pkt\u list\u tot
    ,将
    hitcount
    参数的最大可能值从其默认值20增加。这可以通过在
    /etc/modprobe.d/
    中创建一个
    ip\u pkt\u list\u tot.conf
    文件来实现,该文件包含:

    选项xt\u最近的ip\u pkt\u列表\u tot=26

    创建文件后,通过
    modprobe-r xt_recent&&modprobe xt_recent
    重新加载
    xt_recent
    内核模块或重新启动系统

  • 检查
    iptables
    的手册页会得出相同的结论:

       --hitcount hits
              This option must be used in conjunction with one of --rcheck or --update. When used, this will narrow the match to only happen  when
              the  address  is  in  the list and packets had been received greater than or equal to the given value. This option may be used along
              with --seconds to create an even narrower match requiring a certain number of hits within a specific time frame. The  maximum  value
              for  the  hitcount parameter is given by the "ip_pkt_list_tot" parameter of the xt_recent kernel module. Exceeding this value on the
              command line will cause the rule to be rejected.
    

    请注意,
    xt\u-recent
    在某些系统上被称为
    ipt\u-recent

    只是为了添加一个警告,即当有一个(或多个)iptables规则使用
    -m-recent
    模块时,您不能
    modprobe-r
    。首先使用
    iptables save | grep recent
    进行检查。在这种情况下,要么暂时删除这些规则,要么重新启动。我使用Debian,文件夹名为
    /etc/modprobe.d
    (不带“e”),内核模块名为
    ipt\u recent
    @lihume good suggestion。在CentOS中,相同的文件夹可用。我在那里放了一个名为ipt.conf的文件,文件内容为:ipt\u最近的ip\u pkt\u list\u tot=250 ip\u list\u tot=2000