xiaohanliang
OS
OS
  • hi
  • PROCESS
    • 0. 你的程序是怎么用内存的
    • 1. 为什么内存要区分堆与栈
    • 2. 什么叫你的程序
    • 3. 搞玄学?看看进程切换
    • 4. 进程是怎样调度的
    • 5. 理解进程线程有啥用
    • 6. 没有人真正见过的进程通信
    • 7. [WIP]mutex的起源CAS
    • 8. [WIP]mutex的下一步信号量
    • 9. [WIP]如何人为制造死锁
    • 10. 怎么什么东西都是fd
    • 11. IO各种模型
    • 12. Epoll内部是怎么工作的
  • NETWORK DEVICES
    • 1. 一个新的namesapce
    • 2. veth对讲机
    • 3. 如何靠网桥连接对讲机
    • 4. 左耳进右耳出的tun设备
    • 5. 如何用iptables改包头
    • 6. 在ip报头上再包个头
    • 7.如何用vxlan隧道分割局域网
    • 8. 通过多播组的方式获取mac
    • 9. 自动维护的fdb/arp表
    • 10. [WIP]macvlan网卡
Powered by GitBook
On this page
  • introduction
  • xxx_filter
  • 协议栈之旅(钩子之旅)
  • iptable
  • 某个iptable规则
  • 玩一玩

Was this helpful?

  1. NETWORK DEVICES

5. 如何用iptables改包头

introduction

iptables 这个东西在容器生态中使用的非常广, 比如举个例子, 容器端口的映射, K8s-service的实现中, 多多少少都参与了一些. 这一节不会说的特别深, 主要是想让你意识到世界上有这样一种工具存在

xxx_filter

iptable的底层实现是netfilter, 这个工具作用于协议栈(补充一些协议栈相关的知识, 协议栈控制"网络流程", 也就是收包, 发包, 转发控制等等操作), 这个工具负责往各个节点上挂钩子, 比如作用于转发流程的钩子等等.一共有5个位置可以挂钩子:

  • pre/post-routing

  • in/out-put

  • forward

协议栈之旅(钩子之旅)

现在我们把思路拓宽一些, 这些钩子能帮你做到: 包过滤, 地址伪装, 地址转换, 代理, 现在假设有一个包被送到了协议栈, 那么接下来会发生什么呢? 我们会:

  • 先经过prerouting链, 如果确实有用户在这里挂了函数, 那么内核将对这个包做目的地址转换(DNAT), 做完以后根据目的地址, 内核检查本地路由表, 来确定这个包是发给本机上的某个进程, 还是转发给其他机器

    • 如果转发给其他机器

      • 那么前往forward链(此时这台机器相当于一个路由器), 并遍历forward链上的所有函数

      • 目前我们还在协议栈里, 因为我们即将把这个包转发给别的机器, 因此马上就要出协议栈了, 所有出协议栈的包都会经过postrouting链, 在这个场景下, 几种可能的玩法是做源地址转换(SNAT)或地址伪装(Masq)

    • 如果不转发, 就是本机上的某个进程

      • 那么此时会经过input链, 并到达这个进程手上, 本地的响应报文会先经过output链, 一次路由决策后(想想上一节里协议栈是怎么把包发给tun0的), 最终经由postrouting链离开协议栈

iptable

现在我们已经知道了链与钩子这种东西了, ipfilter这种工具就是帮你往钩子上挂函数的, 想想netfilter的特点, 一个最大的可能似乎是拿来搭防火墙用的(非法包过滤掉), 但再想想拿来做负载均衡似乎也是有可能的.

五条链, 作用于协议栈里的五个时间点上, 钩子函数呢? 函数是什么样的, 所有的函数可以拿来归类成以下五类函数, 分别存在五张表里, 我们只介绍三个最直观最常用的:

  • filter表: (这个表里的函数) 用于控制包要不要了, 是放行还是拒绝

  • nat表: 可以修改包的源/目的地址

  • mangle表: 可以改包的IP头信息

某个iptable规则

拿到包, 前往链, 遍历函数, 然后呢? 一个规则是否要执行分成两部分: 匹配条件+动作

  • 匹配条件包含: 协议类型, 源IP/端口, 目的IP/端口, 你可以从这些内容里挑出一些组合成一个条件, 用于筛选出你想要的包

  • 动作包含:

    • DROP直接丢, 什么都不做, 当做无事发生过

    • REJECT拒: 给对端返回一个connection refused

    • QUEUE存: 放到一个用户空间的队列里, 等待某用户程序处理

    • ....

玩一玩

Previous4. 左耳进右耳出的tun设备Next6. 在ip报头上再包个头

Last updated 4 years ago

Was this helpful?