我为某台计算机设置了配额:
- iptables -A FORWARD -d 192.168.1.10 -m quota --quota 500000000 -j ACCEPT
- iptables -A FORWARD -d 192.168.1.10 -j DROP
这按预期工作.达到限制(500MB)时,此特定计算机的所有数据包都将被丢弃.
但是,如果我保存计数器(iptables-save -c> /home/iptables.counters),重新启动iptables,并恢复计数器(iptables-restore -c /home/iptables.counters),那么无论保存什么计数器,该计算机仍然可以下载500 MB,所以计算机失去互联网访问之前的总计数器大小将是X 500MB,其中X是保存的计数器大小.
我必须做错事,因为这是保存/恢复计数器的重点:从该字节计数恢复直到达到限制.任何类型的提示将不胜感激……
解决方法
问题是内核错误.
- quota_mt(const struct sk_buff *skb,const struct xt_match_param *par)
- {
- struct xt_quota_info *q = (void *)par->matchinfo;
- struct xt_quota_priv *priv = q->master;
- bool ret = q->flags & XT_QUOTA_INVERT;
- spin_lock_bh("a_lock);
- if (priv->quota >= skb->len) {
- priv->quota -= skb->len;
- ret = !ret;
- } else {
- /* we do not allow even small packets from now on */
- priv->quota = 0;
- }
- /* Copy quota back to matchinfo so that iptables can display it */
- q->quota = priv->quota;
- spin_unlock_bh("a_lock);
- return ret;
在F20中它显示了这个:
- static bool
- quota_mt(const struct sk_buff *skb,struct xt_action_param *par)
- {
- struct xt_quota_info *q = (void *)par->matchinfo;
- struct xt_quota_priv *priv = q->master;
- bool ret = q->flags & XT_QUOTA_INVERT;
- spin_lock_bh(&priv->lock);
- if (priv->quota >= skb->len) {
- priv->quota -= skb->len;
- ret = !ret;
- } else {
- /* we do not allow even small packets from now on */
- priv->quota = 0;
- }
- spin_unlock_bh(&priv->lock);
- return ret;
- }
它与一条线基本相同(减去间距变化);
- /* Copy quota back to matchinfo so that iptables can display it */
- q->quota = priv->quota;
这意味着作为显示参数.
所以在EL6中,如果你设置了配额,传递一些数据包,然后执行iptables -vnL SOMECHAIN,你会发现配额值会减少.
在F20做同样的事情,价值不会减少.我想设计师认为,确保人们知道配额是什么而不是配额的真实情况可能是更好的事情(因为数据包计数清楚地说明剩下的是什么).
但是,这会产生意想不到的效果.当你运行iptables-save时,你可以通过iptables保存配额值.在EL6中,如果此值达到0,则显示0到iptables.因此,在还原时,将0还原为iptables链.
随着它们删除它,这个值永远不会减少,因此你永远不会实际保存配额.
真正需要发生的是模块需要重新设计.应该有配额条目和剩余条目.剩余应该像EL6一样递减,并且用于强制执行配额,而“quota”应该是F20中的实际设定值.这样你就可以获得两全其美.已保存的配额状态以及设置的配额的实际描述.
您应该向netfilter团队报告此事.