【博客579】netfilter network flow 和 routing decision的网络流处理交互关系

news/2024/12/28 3:54:00/

netfilter网络流转(network flow)与路由决策(routing decision)的网络流处理交互关系

1、场景:

我们可以通过iptables来基于netfilter机制下发我们的hook处理函数,那么我们平时iptables的四表五链与报文的路由决策之间存在什么样的依赖关系和先后关系呢

2、Traversing of packets

Receive:

某个interface收到数据包 -> PREROUTING (manage, nat) -> routing ->
是发送给本机的数据包? -> INPUT (manage, filter) -> app
不是 -> FORWARD (manage, filter) -> POSTROUTING (manage, nat) -> 某个interface发出

Send:

app发送数据包 -> routing -> OUTPUT (manage, nat, filter) -> (re)routing -> POSTROUTING (manage, nat) -> 某个interface发出

nat 表与会话管理(nf_conntrack): 每个连接只有第一个包会经过 nat 表,后面的包会直接按照之前包同样方式处理。

3、routing and rerouting

对于本机 app 发出(outcoming)的流量,netfilter 有2次 routing 过程,称为 routing 和 (re)routing。

流转如下:routing —> output —> rerouting

OUTPUT 链在 第一次 routing 之后:

对于本机 app 发出的流量,第一次 routing 除了确定下一跳之外,对于没有指定源IP的数据包,还将会为其选择源IP地址。当数据包经过了iptables OUTPUT链,某条rule为其打上了fwmark或者改变了其目标地址后,由于数据包属性已经改变,需要第二次路由,即 (re)routing。

OUTPUT 链之后的 rerouting :

Linux内核协议栈在实现第一次路由和第二次路由时,其逻辑是一样的。但请注意由于第一次路由时会为skb选择source地址,那么第二次路由时的命中路由条目的source属性将永远不会生效,所以多个网口设备策略路由时常常需要用 MASQUERADE 重写 outcoming 数据包的 src IP 以保证正确,这是一种 workaround。

注意:

第一次 routing 时如果未找到匹配的路由条目,会直接失败(“Network is unreachable”),不会再继续经过 iptables 各个链。配置错误时会出现这种情况,用 ip route get 有时无法检测出来,例如对于 “ip route get 8.8.8.8 mark 0x2” 这种指定 mark 的流量,由于第一次 routing 时还没有 MARK (打 mark 在 -t mangle PREROUTING / OUTPUT 阶段),如果对于无 MARK 的流量 ip rule / ip route 找不到路由条目,则实际上网络访问会失败。这种情况解决方法是添加一个 dummy 的默认路由专用于第一阶段 routing,只要语法正确即可,即使实际上路由项不合法(比如下一跳IP地址没有对应的机器)亦可,因为这个路由项的目的只是让流量继续在 netfilter flow 里走下去,真正使用的路由条目会在第二次 routing 时被选择。

4、Flow graph

简化流程图:

(注:此图有个小问题,filter FORWAED 后面应该直接是 mangle POSTROUTING, 没有 route decision)

在这里插入图片描述

完整流程图:
在这里插入图片描述

“netfilter network flow and routing decision” Tips

  • RAW table 只与 conntrack 有关。When one drops a packet in raw table, the packet never reaches the conntrack module. This means that no connection tracking entry is created / consulted during packet’s flow in the blocked direction. 而在 RAW 被 DROP 的包仍然继续进入 mangle / filter / nat, 并且最终可以正常被本机(INPUT)的应用程序接收。在实际使用中,iptables -t raw -A PREROUTING -p tcp --dport 1081 -j DROP 常常用于配合反向代理程序(例如convey(设计文档)),阻止 kernel 自动对接收到的包创建并维护 TCP 连接(TCP passthrough)。参考资料。
  • 上面的图中画出了两个 “route decision” 阶段,但对于 receive / send 而言,其各自实际上应该主要使用了1个 route 阶段: receive 的 route 在 PREROUTING 之后;send 的 route 在 OUTPUT 之后。
  • Receive时判断是否是发送给本机的数据包的方法是:收到数据包的destination IP是否与本机某个interface的IP相同。
  • Send的OUTPUT chain除了manage和filter以外nat表里也有。nat的OUTPUT位于filter的之前,用于对从本机(app)发出的(而不是收到并FORWARD的)请求做DNAT或REDIRECT。
    Send的route阶段确定了数据包的source ip和source port。source ip和source port由app发送数据包时决定。如果app没有bind某个interface并且没有设置source ip/port,则source ip时为route使用的interface ip。
  • filter表的INPUT, OUTPUT和FORWARD用来过滤数据包 -j ACCEPT /DROP
  • nat表的PREROUTING / OUTPUT用来做DNAT(或REDIRECT), POSTROUTING用来做SNAT(或MASQUERADE)
  • FORWARD (以及所有 FORWARD 之后的 chain) 需要设置内核参数 “net.ipv4.ip_forward=1”。(否则内核网络栈会直接丢弃网卡收到的 dst 非本机的数据包)
  • nat 表的 PREROUTING / POSTROUTING 链有些时候会被跳过。主要是指对于有连接的会话 (conn),只有初始发送的数据包会经过 PREROUTING / POSTROUTING,之后发送的数据包以及收到的来自对方的数据包都会根据内核维护的 conn 连接表而被直接处理。
  • conntrack (Connection tracking) 工作在 PREROUTING / OUTPUT 链(分别对于收到的/本机发出的数据包)。

参考文档:

  • netfilter network flow
  • Traversing of tables and chains

http://www.ppmy.cn/news/10659.html

相关文章

yarn包管理器

快速、可靠、安全的依赖管理工具。和 npm 类似, 都是包管理工具, 可以用于下载包, 就是比npm快 中文官网地址: Yarn 中文文档 1、下载yarn 使用node下载 npm install --global yarn 官方推荐下载:地址 2、使用yarn 与npm类似, 可以试试, 新建一个空白文件夹, …

python初级教程十二 uWSGI 安装配置

uWSGI 安装配置 本文主要介绍如何部署简单的 WSGI 应用和常见的 Web 框架。 以 Ubuntu/Debian 为例,先安装依赖包: apt-get install build-essential python-dev Python 安装 uWSGI 1、通过 pip 命令: pip install uwsgi 2、下载安装脚本&…

网易云MUSIC年终奖0.5?听到消息我扔了耳机

一、百度 1.MEG开始突然抓考勤,多个团队口头通知,要求早上10点之前到公司。同时工作日下班免费打车的时间将从9点改成10点,预计本周开始实行,这意味着“早十晚十”成为了公司倡导的主旋律。没错,为什么要有下班呢&…

基于K8s的DevOps平台实践(三)

文章目录前言1. Jenkins与k8s集成🍑 插件安装及配置🍑 演示动态slave pod🍑 Pod-Template中容器镜像的制作🍑 实践通过Jenkinsfile实现demo项目自动发布到kubenetes环境2. Jenkins集成Sonarqube🍑 sonarqube架构简介&a…

基于Promethus+Grafana搭建监控系统

简介 ● 监测数据类型&#xff1a;JVM数据、在线人数、消息时延等 ● 接入Prometheus性能监测工具&#xff0c;暴露服务器性能监测数据 ○ 模式&#xff1a;pull/push ● 接入Grafana可视化数据 搭建流程 准备环境 Java客户端配置 <!-- The client --> <depende…

模拟实现list和vector反向迭代器

学习这部分知识&#xff0c;需要你了解vector和list的正向迭代器知识以及容器适配器知识&#xff0c;可以阅读我写的另外三篇vector、list、容器适配器 知识的博客&#xff01;其中list知识内容尤其重要且难度要求很高&#xff01; 反向迭代器&#xff0c;顾名思义是与正向迭代…

【Python】基于高德地图API的坐标转换函数

【Python】基于高德地图API的坐标转换函数 API申请&#xff1a; lbs.amap.com/api/webservice/guide/api/convert/产品介绍 坐标转换是一类简单的HTTP接口&#xff0c;能够将用户输入的非高德坐标&#xff08;GPS坐标、mapbar坐标、baidu坐标&#xff09;转换成高德坐标。 …

[Linux]Linux调试器-gdb

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文…