《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

简介: 《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

netfilter框架是Linux操作系统中内置的,通过向内核模块提供对协议栈中的网络数据包进行修改和操作的能力,来实现流量过滤,网络地址转换等高级功能。

 

1) netfilter如何工作

对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照Linux内核定义的网络设备驱动规范,以sk_buff结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元skb。

 

内核通过将网络设备缓冲区环形队列中skb取出,并按照以太网层,网络层,传输层顺序处理后,将报文数据放置到对应Socket缓冲区中,通知用户程序进行读取,从而完成收包

内核为Socket缓冲区待发送数据封装为skb,经过传输层,网络层和以太网层依次填充对应报头后,调用网络设备驱动方法将skb发送到网络上,从而完成发包

 

netfilter工作的核心原理则是在网络层,通过在五个不同的内核处理skb数据包的位置,执行注册到netfilter框架中的回调函数,并根据回调函数的返回来选择下一步的处理,实现复杂的功能。

 

netfilter触发时机

 

netfilter在内核网络数据包的处理流程中,注册了5个可以触发的时机,详情如下:

/* IP Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP_PRE_ROUTING0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING4
#define NF_IP_NUMHOOKS5
#endif /* ! __KERNEL__ */

 

根据源代码中的定义,我们可以参考下图:

 image.png

 从上面的代码定义和示意图中可以知道,在以下几个地方会调用netfilter定义好的方法对数据包进行处理:

 

数据包从网卡进入协议栈后,所有报文都会走到NF_IP_PRE_ROUTING

数据包经过入向路由选择后,确认是由本机传输层进行处理,会进入到NF_IP_LOCAL_IN

数据包经过入向路由选择后,不是由本机处理,需要转发给其他机器,会进入到NF_IP_FORWARD

由本机传输层发出报文,都会经过NF_IP_LOCAL_OUT

经过出向路由选择后报文,会经过NF_IP_POST_ROUTING,包括从本机发出和需要本机转发的。

 

在以上五个时机,当数据包skb到达时,netfilter框架定义的回调方法就会被内核执行。

 

netfilter如何操作网络数据

使用netfilter框架的模块,需要按照netfilter定义的结构体来实现自己的行为,才能正确注册到netfilter框架中,并被内核调用,netfilter约束的注册结构体的定义如下:

struct nf_hook_ops {
    // 这是真正被内核执行的函数,会对skb进行读取和修改
    nf_hookfn*hook;
    struct net_device*dev;
    void*priv;
    u_int8_tpf;
    // hooknum定义了回调函数生效的位置,从上文可知有五个位置可以选择
    unsigned inthooknum;
    // priority定义了回调函数的优先级,通过每个hook时机都会有多个回调函数需要生效
    intpriority;
};

以ipvlan模块为例:

static const struct nf_hook_ops ipvl_nfops[] = {
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV4,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#if IS_ENABLED(CONFIG_IPV6)
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV6,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#endif
};

 

我们可以看到,ipvlan模块根据IP协议的版本定义了两个hook结构体,其中:

hookfn是核心处理逻辑,ipvlan模块注册了ipvlan_nf_input方法

pf是netfilter协议版本,ipvlan模块分别注册了IPv6和IPv4对应方法

hooknum定义了这个hook在netfilter中生效位置,ipvlan模块将自己回调方法注册到了NF_INET_LOCAL_IN,也就是完成路由之后,进入传输层之前

priotity定义了hook优先级

 

那么,hookfn作为真正核心的处理逻辑,他是如何工作的呢?

 

以ipvlan注册在NF_INET_LOCAL_IN上的hook方法ipvlan_nf_input为例:

 

unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
           const struct nf_hook_state *state)
{
    // 参数中可以看到,有前一个生效的hook结构体,当前处理的skb报文本身以及当前netfilter框架的上下文信息
  struct ipvl_addr *addr;
  unsigned int len;
  addr = ipvlan_skb_to_addr(skb, skb->dev);
  if (!addr)
    goto out;
  skb->dev = addr->master->dev;
  len = skb->len + ETH_HLEN;
  ipvlan_count_rx(addr->master, len, true, false);
out:
    // 这里返回了netfilter框架规定的返回码
  return NF_ACCEPT;
}

 从ipvlan_nf_input可以看到,注册到netfilter中的回调函数的核心在于两个约束:

● 回调函数的入参定义,可以接受协议栈中真正的报文结构体skb以及netfilter的上下文状态为参数。

● 回调函数的返回值,需要是netfilter规定好的返回值,他们的定义如下:

/* Responses from hook functions. */
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5/* Deprecated, for userspace nf_queue compatibility. */
#define NF_MAX_VERDICT NF_STOP

从以上的分析不难看出,只要满足netfilter的注册条件,就可以在回调函数中直接对数据报文skb内容进行读取和修改操作,而通过返回值的定义,则可以借助netfilter框架完成对数据包的处理,比如丢弃,接收或者传递到用户态进行处理。

 

netfilter的内核实现

在负责对所有hook方法进行遍历处理的函数中,可以看到,netfilter核心的工作流程就是在相应的触发时机调用这个时机上注册的所有方法,按照优先级进行处理,并根据每一次处理的结果进行操作,包括丢弃,传输给用户态等等:

int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
     const struct nf_hook_entries *e, unsigned int s)
{
  unsigned int verdict;
  int ret;
  for (; s < e->num_hook_entries; s++) {
        // 在这里调用对应的hook时机上的所有注册的hook回调方法,然后根据结果选择是不是继续循环
    verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state);
    switch (verdict & NF_VERDICT_MASK) {
    case NF_ACCEPT:
      break;
    case NF_DROP:
      kfree_skb(skb);
      ret = NF_DROP_GETERR(verdict);
      if (ret == 0)
        ret = -EPERM;
      return ret;
    case NF_QUEUE:
      ret = nf_queue(skb, state, e, s, verdict);
      if (ret == 1)
        continue;
      return ret;
    default:
      /* Implicit handling for NF_STOLEN, as well as any other
       * non conventional verdicts.
       */
      return 0;
    }
  }
  return 1;

 

更多精彩内容,欢迎观看:

《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(下):https://developer.aliyun.com/article/1221729?spm=a2c6h.13148508.setting.16.15f94f0e18Oqpt

相关文章
|
2月前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
24天前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
3天前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
21 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
4天前
|
人工智能 运维 监控
容器服务Kubernetes场景下可观测体系生产级最佳实践
阿里云容器服务团队在2024年继续蝉联Gartner亚洲唯一全球领导者象限,其可观测体系是运维的核心能力之一。该体系涵盖重保运维、大规模集群稳定性、业务异常诊断等场景,特别是在AI和GPU场景下提供了全面的观测解决方案。通过Tracing、Metric和Log等技术,阿里云增强了对容器网络、存储及多集群架构的监控能力,帮助客户实现高效运维和成本优化。未来,结合AI助手,将进一步提升问题定位和解决效率,缩短MTTR,助力构建智能运维体系。
|
11天前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
11天前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统
|
11天前
|
存储 JSON 缓存
【网络原理】——HTTP请求头中的属性
HTTP请求头,HOST、Content-Agent、Content-Type、User-Agent、Referer、Cookie。
|
9天前
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
11天前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
11天前
|
XML JSON 网络协议
【网络原理】——拥塞控制,延时/捎带应答,面向字节流,异常情况
拥塞控制,延时应答,捎带应答,面向字节流(粘包问题),异常情况(心跳包)