Linux 的防火墙与流量控制
一. Linux 网络总览
1.1 流量的路径
在 Linux 中无论是跨机流量还是本机内部的流量收发均需要一条完整的链路:
Tips:Linux 内核知道所有的本机的 IP 地址,只要发现目的地址是本机的 IP 地址,均会走 Loopback 回环设备。
1.2 路径中控制
tc 的控制与接口的 qdisc 相关,netfilter 的控制贯穿了整个协议栈:
二. iptables/netfilter
2.1 简介
iptables 与 netfilter 构成了 linux 下的有状态包过滤防火墙,实现了基于流的包过滤、重定向与 DNAT/SNAT 转换:
- netfilter 存在于 Linux 内核中,实际对流量做控制;
- iptables 实际上是 netfilter 的管理工具,帮助用户与 netfilter 交互。
2.2 概念
2.2.1 链-chain
在 Linux 协议栈中存在 5 个 Hook 点,每个点可以执行一串"链"的操作:
- PREROUTING - NF_IP_PRE_ROUTING
- FORWARD - NF_IP_FORWARD
- POSTROUTING - NF_IP_POST_ROUTING
- INPUT - NF_IP_LOCAL_IN
- OUTPUT - NF_IP_LOCAL_OUT
Tips: 用户可以自定义chain,在系统的 Hook 点将包放入 chain, 然后处理完毕使用 return 返回主链。
2.2.2 表-table
iptables 对于各种类型的控制做了分类形成表:
- Filter_table: 用于包过滤,适用链:
- INPUT FORWARD OUTPUT
- Nat_table: 修改源目地址并保存 session 用于处理流的返回包,适用链:
- DNAT - PREROUTING OUTPUT
- SNAT - INPUT OUTPUT POSTROUTING
- Mangle_table: 更自由的修改包,适用链:
- INPUT PREROUTING FORWARD POSTROUTING OUTPUT
- Raw_table: 让包跳过 ip_conntrack 的追踪,适用链:
- PREROUTING OUPUT
2.2.3 优先级
2.2.4 状态追踪
包进入协议栈后,检查 raw 和完整性后,会基于连接的上下文而非单个包来做出规则判断,而上下文由 ip_conntrack 生成:
- NEW: 包合法且没有匹配的连接,则创建新连接;
- ESTABLISHED: NEW 在收到连接反方向的包后,迁移至 ESTABLISHED 状态;
- RELATED: 包不属于已有连接,但和已有连接有一定关系,是 helper connection,比如 FTP 的数据传输连接;
- INVALID: 包不属于已有连接,且因一些原因无法用来创建新连接,如无法识别、无法路由等;
- UNTRACKED: 在 Raw 中标记为 UNTRACKED 的包;
- SNAT: 包的源地址被 NAT 修改后会进入的虚拟状态,连接跟踪系统会据此在收到反向包时对地址做转换;
- DNAT: 包的目的地址被 NAT 会进入的虚拟状态,连接跟踪系统具体做反向转换.
tips: ip_conntrack 是有代价的,过多的 track 会造成新 session 无法建立从而造成丢包。
2.3 配置
2.3.1 命令与说明
2.3.2 配置持久化
三. traffic control
3.1 简介
TC 是一个工作在 Linux 内核中的,基于(队列与规则抽象(queueing discipline)的流量控制框架:
- TC 主要实现了对 egress 的流量的控制,可以实现复杂控制;
- 在 ingress 上仅实现了简单的 police 和重定向;
tips: ingress 方向 tc 虽然没有冗余实现,但是可以结合 ifb 实现对 ingress 的复杂控制。
3.2 概念
3.2.1 队列
Classless 的队列 - 对需要使用网卡处理的数据流不做区分按照统一的规则放入队列,在基于一定的算法从队列取出:
- [p|b]fifo: 先入先出;
- pfifo_fast: 根据 TOS 将队列划分到 3 个 band,每个 band 内部先入先出;
- red: Random Early Detection:随机早期探测,带宽接近限制时随机丢包;
- sfq: Stochastic Fairness Queuing 随机公平队列,按照 session 对流量排序,并循环发送每个 session 的数据包;
- tbf: Token Bucket Filter 令牌桶过滤器,使用令牌桶算法限速且允许一定的突发;
- netem: Network emulator 网络仿真,可以模拟网络的带宽/延迟/丢包/抖动这些特征。
Classfull 的队列 - 内部很多子抽象队列,用 filter 对流量区分的放入各个抽象队列,然后再基于一定的的算法从队列中取出:
- cbq: Class Based Qeueing 基于类别排队,基于时间估算,有缺陷,被 htb 取代;
- htb: Hierarchy Token Bucket 分层令牌桶,基于类别排队,基于分层令牌桶相关算法出队。
3.2.2 入队
对 Classless 的队列-直接入队,对 Classfull 的队列,有多种方式:
-
cgroup: 基于资源组对流做分类, 例子戳这里;
-
iptables: 使用 iptables 对流量分类;
-
tc filter: 可以基于多种特征对流量做过滤,常用的比如 u32 来匹配包头特征, 更多举例;
3.2.3 出队
htb 单个 QUEUE 的状态机有三个:
- CAN_SEND: 自身 token 充足,发送的量小于定义的 rate;
- MAY_BORROW: 自身没有 token,但可借用父 Queue 的 Token,发送的量大于 rate 但小于 ceil;
- CANT_SEND: 不可发包,发送的量大于 ceil。
htb 算法步骤,详细:
- tree 中自 leaf 向 root 逐层查找 CAN_SEND 状态的且有包的 Queue ;
- 如该层有多个 Queue 处于 CAN_SEND 状态,那先发优先级小的,相同则轮询,单次最小发送字节数由 Quantum 参数决定;
- 如处于 CAN_SEND 状态的是非 leaf Queue,那 Queue 会按照上两条规则,查找处于 MAY_BORROW 的子 QUEUE,并借 token 给它们。
3.2.4 ingress
tc 主要实现了 exgress 方向的流控细节,在 ingress 没有重复的实现,但可以配合 ifb 实现:
tips: ifb 除了可以用于辅助 tc 实现对 ingress 流量的控制外,还可以使 tc 的规则可以同时在多个接口上生效。
3.3 配置
详细举例:戳这里
参考:
本机网络通信:https://mp.weixin.qq.com/s/J5igDYTE6sFa2NU7kc4yYw
流量控制与排队规则:https://blog.csdn.net/qq_44577070/article/details/123967699
iptables 规则持久化:https://www.jianshu.com/p/34a858a3c675
Cgroup 流量控制:https://www.jianshu.com/p/37937c6c0a82
Linux网络流控-htb算法解析:https://www.cnblogs.com/acool/p/7779159.html
Linux 下 TC 命令详解:https://blog.csdn.net/hexf9632/article/details/118635257
TC Howto:https://tldp.org/HOWTO/Traffic-Control-HOWTO/
__EOF__

本文链接:https://www.cnblogs.com/FcBlog11/p/16782233.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗