如下limit匹配的帮助信息。

# iptables -m limit -hlimit match options:
--limit avg                     max average match rate: default 3/hour[Packets per second unless followed by /sec /minute /hour /day postfixes]
--limit-burst number            number to match in a burst, default 5

首先新建一个链,将连接跟踪新建状态的报文,导到RATE-LIMIT链中。

# iptables --new-chain RATE-LIMIT
# iptables --append INPUT --match conntrack --ctstate NEW --jump RATE-LIMIT

以下在RATE-LIMIT链配置规则,使用limit将报文速率控制在每秒50个以下,由于此链中的报文都是连接新建报文,即将连接新建速率限制在每秒50个。超过此速率的报文,执行丢弃DROP。

# iptables --append RATE-LIMIT --match limit --limit 50/sec --limit-burst 20 --jump ACCEPT
# iptables --append RATE-LIMIT --jump DROP

limit匹配

由函数xt_register_matches注册匹配结构limit_mt_reg。

static struct xt_match limit_mt_reg __read_mostly = {.name             = "limit",.revision         = 0,.family           = NFPROTO_UNSPEC,.match            = limit_mt,.checkentry       = limit_mt_check,.destroy          = limit_mt_destroy,.matchsize        = sizeof(struct xt_rateinfo),
#ifdef CONFIG_COMPAT.compatsize       = sizeof(struct compat_xt_rateinfo),.compat_from_user = limit_mt_compat_from_user,.compat_to_user   = limit_mt_compat_to_user,
#endif.usersize         = offsetof(struct xt_rateinfo, prev),.me               = THIS_MODULE,
};
static int __init limit_mt_init(void)
{return xt_register_match(&limit_mt_reg);

配置检测函数如下,突发burst的值不能为零,平均值avg和突发burst的乘积不能小于平均值avg,即burst大于等于1。

static int limit_mt_check(const struct xt_mtchk_param *par)
{   struct xt_rateinfo *r = par->matchinfo;struct xt_limit_priv *priv;/* Check for overflow. */if (r->burst == 0|| user2credits(r->avg * r->burst) < user2credits(r->avg)) {pr_info_ratelimited("Overflow, try lower: %u/%u\n", r->avg, r->burst);return -ERANGE;}

规则配置的avg与burst的乘积转换为最大的可用信用值。如果cost为空,将credit_cap初始化为最大信用值,将cost初始化为平均信用值。

    priv = kmalloc(sizeof(*priv), GFP_KERNEL);if (priv == NULL)return -ENOMEM;/* For SMP, we only want to use one set of state. */r->master = priv;/* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * 128. */ priv->prev = jiffies;priv->credit = user2credits(r->avg * r->burst); /* Credits full. */if (r->cost == 0) { r->credit_cap = priv->credit; /* Credits full. */r->cost = user2credits(r->avg);}

函数user2credits将用户配置值转换为内核使用的信用值,应用层下发的均值avg,单位使用的是:(seconds * XT_LIMIT_SCALE),换算为对应秒值需要执行除法操作:avg/XT_LIMIT_SCALE。所以将用户配置的均值avg转换为信用值credits,需要再次乘以每秒对应的credits数量,即HZ*CREDITS_PER_JIFFY。

在转换之前,检查溢出情况,如果三者(user * HZ * CREDITS_PER_JIFFY)乘积大于32bit的最大值,先除后乘;否则,先乘后除。

/* Precision saver. */
static u32 user2credits(u32 user)
{/* If multiplying would overflow... */if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))/* Divide first. */return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
}

limit匹配处理

信用值使用32位存储,最大值0xFFFFFFFF。如下计算每个jiffy所对应的信用量值,内核将标准定义为最低速率一天一次。此时每个jiffy对应的信用值为(MAX_CPJ),满足最低速率要求。

#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))

为了函数中的乘法能够被GCC在编译的时候使用左移实现,宏POW2_BELOW32将MAX_CPJ转换为2的幂值。首先宏_POW2_BELOW32将参数值x,通过右移位(>>)和或(|)操作将其有效位都设置为1(最高不为零的位到最低位都设置为1);之后,将结果右移移位,再加1。此值即为小于MAX_CPJ的最大的2的幂值,作为每个jiffy的信用值。

/* Repeated shift and or gives us all 1s, final shift and add 1 gives* us the power of 2 below the theoretical max, so GCC simply does a* shift. */
#define _POW2_BELOW2(x) ((x)|((x)>>1))                               b1000000000 | b100000000
#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))       b1100000000 | b11000000
#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))       b1111000000 | b111100
#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))      b1111111100 | b11
#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))   b1111111111 | b0
#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)                  b1111111111 >> 1 + 1#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)

如下匹配函数limit_mt,信用值credit按照时间进行回填,根据前一次时间信用计算的时间(prev)与当前时间的jiffies差值,增加新的信用值,如果新的信用值大于最大值(credit_cap),重新设定为credit_cap的值。如果当前的信用值大于消耗(cost - 每个报文的消耗),表明还有余量,信用值减去消耗,返回真。否则,返回false,当前的报文速率过快,信用值不足。

static bool
limit_mt(const struct sk_buff *skb, struct xt_action_param *par)
{const struct xt_rateinfo *r = par->matchinfo;struct xt_limit_priv *priv = r->master;unsigned long now = jiffies;spin_lock_bh(&priv->lock);priv->credit += (now - xchg(&priv->prev, now)) * CREDITS_PER_JIFFY;if (priv->credit > r->credit_cap)priv->credit = r->credit_cap;if (priv->credit >= r->cost) {/* We're not limited. */priv->credit -= r->cost;spin_unlock_bh(&priv->lock);return true;}spin_unlock_bh(&priv->lock);return false;

iptables应用层处理limit

速率值在下发到内核前,扩大了XT_LIMIT_SCALE倍数。

static int parse_rate(const char *rate, uint32_t *val)
{   const char *delim;uint32_t mult = 1;  /* Seconds by default. */delim = strchr(rate, '/');if (delim) {if (strlen(delim+1) == 0)return 0;if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0)mult = 1;else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0)mult = 60;else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0)mult = 60*60;else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0)mult = 24*60*60;elsereturn 0;} r = atoi(rate);if (!r) return 0;*val = XT_LIMIT_SCALE * mult / r;

内核版本 5.10

iptables使用limit控制新建连接速率相关推荐

  1. xp系统无法创建宽带连接服务器地址,XP下无法建立宽带拨号连接修复一例(新建连接向导选项为灰色)...

    在建立宽带拨号时,在选择"新建连接向导"来新建宽带连接,点击下一步后,页面上的"用拨号调制解调器连接"和"用要求用户名和密码的宽带连接来连接" ...

  2. python连接wifi_Python3控制win10连接wifi热点

    一.基础知识 1.netsh简介: netsh(Network Shell) 是一个windows系统本身提供的功能强大的网络配置命令行工具,netsh支持指令如下: 本篇主要讲述如何通过netsh命 ...

  3. 计算机网口速率修改,win7系统修改无线网卡连接速率的操作方法

    今天和大家分享一下关于对win7系统win7系统修改无线网卡连接速率的操作方法设置的方法,在使用win7系统的过程中经常不知道如何去对win7系统win7系统修改无线网卡连接速率的操作方法进行设置,有 ...

  4. Windows下控制网络连接的常用命令

    1.ipconfig ipconfig 是微软操作系统的计算机上用来控制网络连接的一个命令行工具.它的主要用来显示当前网络连接的配置信息(/all 参数) 实作一 使用 ipconfig/all 查看 ...

  5. Windows 通过向日葵控制 Ubuntu 连接不上问题

    Windows 通过向日葵控制 Ubuntu 连接不上问题 Windows和Ubuntu均安装向日葵.结果Ubuntu能够控制window,但是Windows连接不上Ubuntu,并且一直显示正在连接 ...

  6. srsLTE-UE连接速率测试

    srsLTE简介: "srsLTE is a free and open-source LTE software suite developed by SRS (www.softwarera ...

  7. arduino UNO通过AT指令控制esp8266连接WiFi及onenet云平台

    写下这篇文章是为了记录我学习使用esp8266的过程.在本文中我们会使用AT指令通过MQTT协议连接onenet云平台 开篇必看 1)关于onenet MQTT设备创建 在设备连接onenet平台中, ...

  8. mysql新建连接1045_Navicat for Mysql 1045错误

    在使用图形用户工具Navicat for MySQL新建连接时,会报一个1045,某用户访问拒绝的错误. 一般的解决办法是需要重新修改Mysql的密码,操作步骤如下: 1 net stop mysql ...

  9. 小米6的无线网连接到服务器,解锁小米6的2.4GWIFI连接速率 小米6WIFI连接速率解锁...

    小米6采用了双天线的设计,但实际使用中2.4G的WiFi速率却很低,一般速率为144/172M,甚至更低的72/86M,有人说5G的WIFI速度更快,但实际使用穿墙后稳定性并不如2.4G,那么我们就要 ...

最新文章

  1. java 类中构造函数的讲解
  2. 树莓派python编程小车_python3实现网页版raspberry pi(树莓派)小车控制
  3. 吴恩达深度学习笔记9-Course3-Week2【机器学习策略(ML Strategy)2】
  4. risc-v 编译 linux,linux - 如何为RISC-V编译Linux Kernel 4.20 - 堆栈内存溢出
  5. Java 代码块:静态代码块、构造代码块、构造函数块
  6. 面向对象7:package、MVC设计模式、import
  7. 云桌面计算机被锁定如何解决,桌面布局已锁定怎么解除?电脑桌面便签布局锁定后怎么解除?...
  8. PropertyUtils.copyProperties 属性值复制失败
  9. Windows系统密码破解全攻略(hash破解)
  10. 如何删除计算机中常用列表,清除右键多余菜单,鼠标右键菜单清理的方法(一) -电脑资料...
  11. Java版Quest Soft Player
  12. Unity 中 创建 TextMeshPro 中文字体(含常见汉字 TXT 文件)
  13. JS 对象直接量方法创建对象
  14. 易语言编程乱码解决方案
  15. android最强论坛,Android开发论坛
  16. maven项目查询jar依赖的网址
  17. 实现游戏后处理6大常用模糊算法
  18. BugKu CTF(杂项篇MISC)---细心的大象
  19. C语言入门part6--函数
  20. Using insecure protocols with repositories, without explicit opt-in, is unsupported. Switch Maven...

热门文章

  1. 程序员和黑客的十大本质区别
  2. 常用python模块及安装
  3. 网易云信携手神州信息,共同打造广东华兴银行线上视频平台
  4. could not locate named parameter [***]; nested exception is org.hibernate.QueryParameterException: c
  5. 如何用代码让钉钉报警-开发公司内部的钉钉报警系统
  6. R在市场调查中的应用--主成分分析
  7. 江苏移动CM101s-MV100-EMMC- M8233_强刷固件包
  8. 【教3妹学mysql】一条慢sql如何排查优化
  9. 电脑开机黑屏提示:ERROR 0199:System Security-Security password retry count exceeded(by 星空武哥)
  10. LeetCode#2379. 得到 K 个黑块的最少涂色次数