IP协议-简介 - 弦外之音

/ 0评 / 0

本书 《网络协议栈入门》 采用的代码是 基于 linux 内核 4.4.4 版本的。linux 内核源码下载地址: mirrors.edge.kernel.org


IP数据包的格式如下图:

如上图所示,IP header 是20个字节,IP body 部分数据是可变长度,最多 65515字节。这里的着重讲解一下,所有的协议都是这样的,一个header 接一个body。然后 body 里面的数据再套一层协议数据,就像 json 那样不断套下去。

然后,加密,也只是加密了 body 的部分,不会把 header 也加密,如果加密了header 就无法解析。举个例子,如果一个加密套件是用在 TCP 层的,那这个加密套件只会加密 TCP body 里面的数据,中间的路由器窃取流量,还是能看到 TCP 的header,知道双方通信的端口号。

如果一个加密套件是用在 IP 层,那就会加密 IP body 的数据,IP header 还是明文,能被中间路由看到。但是 TCP 整个数据包都会加密,因为 TCP 的数据是在 IP body里面。中间路由器就看不到 双方通信的端口。

再举个我们比较常见的 HTTPS 协议,HTTPS 是用在 TLS 协议,作用在 TCP 层,所以HTTPS 会对 TCP body进行加密,但是TCP header 不加密。加密 TCP body有什么好处,我们知道 HTTP 协议是在 TCP 层上面的,也就是说 cookie 等信息是放在 TCP body 里面的,加密之后,中间路由就无法看到 cookie 明文。 这里 HTTPS 加密是在发送端就加密,是指 TCP 包从本机发出去之前,就把 TCP body 加密了。加密再发送,中间路由器搞不了事情。



这里再扩展一个知识点,我们知道,在国内云厂商搭建网站需要备案。不备案就无法访问,如果访问了未备案的域名,云厂商的网关就会返回一个 301 之类的跳转。这个是怎么实现的呢?

这整一个访问路径是这样的,我们买了腾讯云服务器之后,就会有一个公网IP。再买了域名之后,就可以控制域名解析到哪个IP。这两步,腾讯云是无法干涉你的,DNS的解析控制不归某一个组织管,不能实现未备案的域名,我就控制DNS服务器不让他解析返回IP,这个功能在现有的DNS规范中无法实现。

买了服务器,域名,搭建好nginx之后,我们用浏览器打开这个 域名,就会发送一个 HTTP 请求,如下:

从上图可以看到,HTTP 包里面有个内容Host: www.xianwaizhiyin.net,这个未加密的HTTP数据包 会经过 腾讯云的硬件防火墙。一般是 金盾,或者傲盾。

拓扑图如下:

如上,由于 HTTP 数据未加密,腾讯的硬件防火墙会检测 HTTP 里面的域名信息,判断域名是否已经通过备案。这个一般是硬件防火墙里面有个域名的白名单,会定期从管局的系统同步信息,把未在管局备案的域名从白名单删除。

如果 HTTP 包的域名不在白名单,硬件防火墙就会返回一个 301 跳转,不把流量传递给 后面的云服务器。这就是云厂商的备案拦截实现。

但是 因为 HTTPS 是在 TCP 层的加密套件,如果网站启用了 HTTPS,硬件防火墙就看不到 HTTP 包数据了,那此时,云厂商又是如何实现HTTPS 的备案拦截的呢?

虽然 TLS 把 HTTP 包加密了,但是 TLS 协议本身,是设计了一个字段来存域名的,也就是 Client Hello 包里面的 server_name,如图:

硬件防火墙在 处理 HTTPS 请求的时候只需要判断这个 Server Name 字段即可。这个没有加密。


加密扩展知识讲解完毕,继续回到本文主题,分析 IP协议。

IP 头部里面的 协议(8位)代表 IP body 里面是哪个协议的数据,如果是 06 ,IP body 里面就是 TCP 的数据,如下图:

上图这个字段如果是 17,那IP body 里面的就是 UDP 的数据。所有协议都是这样搞的,在header里面插个 type 类型,表示 body 里面是什么数据,一个协议套一个协议地套下去。


IP 格式里面还有一个 TTL 字段,这个字段非常有趣,IP包在传输的时候,每进过一层路由转发,IP包里面的 TTL 就会减一,初始值一般是 64,也就是说 IP 包最多经过 64 层转发。如果TTL 变成0 ,还没到达目的地,中间的 路由器(称为P) 发现IP包到我这里TTL已经是0了,路由器P就会发一个 ICMP 数据包返回给 最开始的发送端。

因为这个机制,我们可以用这个 TTL 来跟踪 IP 包经过了多少次路由转发。

linux 下可使用 traceroute 124.223.94.246,Windows下可使用 tracert 124.223.94.246 ,如图:

从上图可以看到,我的电脑发出的 IP 包,到达 公网的 124.223.94.246,需要经过 16 层转发。

下面分析 tracert 这个软件是如何实现的,wireshark 可以输入 icmp ,过滤 icmp 的数据包,如下:

从上图可以看出,tracert 就是发一个 ICMP (ping) 包,把IP层的TTL 设置成 1,这样在第一层路由 192.168.0.1 的时候,TTL 就会变成 0,192.168.0.1 的路由器就会发一个 ICMP 回来,说TTL 过期了,这个回来的ICMP 里面还嵌套了一个原始的IP数据包。


这里的路由转发我重点讲解一下,路由器转发 IP 数据包是如何操作的。首先 从电脑发出的 IP包 为什么会到 192.168.0.1,而不是 192.168.0.2,而且我们的IP包里面的目标地址明明是 124.223.94.246。

IP包里面的目的IP确实是 124.223.94.246,但是是因为 IP包 要经过转发才能到达目的IP,这个转发是MAC 层的事情,首先,本地电脑要把 IP包封装进去 MAC 层,MAC 层也有一个 源地址跟目的地址,MAC 层的目的地址如何获取,就是通过查 路由表,子网掩码,网关之类的操作,拿到这个IP包对应的MAC层目标地址。在上图中,是TP-link的一个MAC 地址,我的路由器是 TP-link。

注意,这里转发IP包,不会修改 IP 包里面的目的IP地址,也就是不会把 124.223.94.246 改成 192.168.0.1。数据包到达 Tplink 路由器之后,TP-link 用同样的讨套路,子网掩码,网关,路由表,ARP表,查这些东西,然后拿到下一站的 MAC 地址,再封装好 MAC 数据包,转成比特流,发给下一站。


由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注