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
  • 描述一下实验环境
  • 配置一下ipip隧道(的一端)
  • 配置对端
  • 所以实际发生的事是这样的:

Was this helpful?

  1. NETWORK DEVICES

6. 在ip报头上再包个头

introduction

ipip指的是ip in ip, 意思是在ip报文的基础上再封装一个ip报头. 我们讨论这种东西叫"L3 隧道网络", 指的是消息的维度是 IP 级别的, 同时它也是一个隧道网络, 这也是为什么我们需要在IP报文外面再封装一个IP头.

Linux原生支持的几种(包括ipip在内)隧道网络方案, 都是基于tun实现的, 因此这一篇也可以认为就是tun的拓展篇

描述一下实验环境

(有点像两个容器间的通信过程) 假设你现在有两个ns, 都通过veth与主机相连, 我们叫它v1&v1p, v2与v2p 好了, 那么这两个ns之间怎么通信? 长话短说:

  1. 假设v1/v2的ip分别是10.10.10.1与10.10.20.1

  2. 在/etc/sysctl.conf, net.ipv4.ip_forward=1 开启Linux的路由模式

  3. 然后配置一下主机路由, 让他知道10.10.20.1应该转发到v2去

配置一下ipip隧道(的一端)

接下来我们在这个的基础上开始配置ipip隧道:

ip netns exec ns1 /bin/sh
ip tunnel add tun1 mode ipip remote 10.10.20.1 \
                            local 10.10.10.1
ip link set tun1 up
ip addr add 10.10.100.10 peer 10.10.200.10 dev tun1

在上面, 我们先切换到ns1里去, 然后在ns1里创建了工作模式为ipip的tun设备, 并声明出了这个隧道的两端, 思考一下, ipip本质是在ip报文的基础上, 再封装一个ip头, 其中内部的ip头是"你以为的IP", 外部的ip头是"真正用于寻址的IP"

那么命令里的local/remote, 意思就是说, 任何发到我这儿来的消息, 我会封装出一个外部ip头, 这个ip头会写对端ip是10.10.20.1, 来自10.10.10.1, 这就是我这个ipip隧道要封装出来的东西

那么什么样的消息, 会进你这条隧道呢? 所有目标ip为10.10.200.10的ip消息都会进这条隧道, 经过这样一番操作与配置, 所有前往200.10的消息会先前往ipip隧道, 包装出一个20.1的IP头以后发到v2里去.

配置对端

如果我们配置到这里就结束, 那么接下来会发生什么? 我们的报文现在有两个IP报头, 发到10.10.20.1, 他拆开第一个头以后, 发现消息报文是一个IP报头, 毛病了

ip netns exec ns2 /bin/sh
ip tunnel add tun2 mode ipip remote 10.10.10.1 \
                            local 10.10.20.1
ip link set tun2 up
ip addr add 10.10.200.10 peer 10.10.100.10 dev tun2

于是我们开始配置另一条ipip隧道, 让这个发给10.10.20.1的消息先经过这条隧道, 让它把第二个头拆开, 这样就能拿到IP报文的正文部分了

所以实际发生的事是这样的:

ip netns ns1 exec \
     ping 10.10.200.10
  • 在ns1里发出一条到200.10的消息, ns1里的路由认为应该从tun1发出这条消息, 进入ipip隧道, 封装上一个10.10.20.1的头

  • ipip隧道修改了路由表, 任何前往10.10.20.1的报文会走v1, 于是这条消息从tun1出来去了v1, 并到达v1p, 停留在宿主机上

  • 宿主机已开启路由转发模式, 将20.1的包转发给v2p, 并到达v2, 拆掉20.1的头, 并查看剩下来的消息, 剩下来的消息说明要去200.10, 这正是tun2的地址, 发给tun2完成一次通信

Previous5. 如何用iptables改包头Next7.如何用vxlan隧道分割局域网

Last updated 4 years ago

Was this helpful?