学习计算机网络的一点点记录。
不能称得上系统全面,仅仅是一些实践中碰到的豆知识
曾经在老爸的力荐下看了《图解 TCP/IP》这本书。虽然这本书的讲解和例子确实通俗易懂,但是面对网络这种看不见摸不着的神秘力量 ,看了大半以后还是感觉一知半解。直到经过 CTF 短学期的历练以后,通过实际抓包网络流量并且分析,了解前后端的语言、逻辑,才算是对她有一些感觉。对我来说,在真正动手做以后才能更全面立体地了解一个新的知识或是领域。
The best way to learn something is to implement it by yourself!
概述
DNS: 以www.baidu.com为例
- IP 地址:就像一栋房子的门牌号,它是唯一的,可以用来找到具体的位置。在网络中,IP 地址用于唯一标识一台设备,使得其他设备可以找到并与其通信。
- DNS:类似于电话簿,它将域名(比如 www.example.com)映射到IP地址(比如 192.0.2.1)。就像你在电话簿中查找某个人的名字以找到他们的电话号码一样,DNS 用于将人类易读的域名转换为机器易读的 IP 地址。
人们如果要记住各个网站的 IP 地址再去访问就太麻烦了,于是直接输入一个域名(www.baidu.com)让DNS服务器去找它对应的IP地址再去访问就好了
指令
可以查询某个域名的 IP 地址 也可以通过 IP 地址反向查询域名
例如
www.baidu.com
是www.a.shifen.com的别名(*Aliases*)
其 IPv4 与 IPv6 地址为……
1 2 3 4
| 2409:8c20:6:1135:0:ff:b027:210c 2409:8c20:6:1d55:0:ff:b09c:7d77 36.155.132.76 36.155.132.3
|
非权威应答:来自缓存解析器的响应。DNS 解析器会缓存之前查询过的 DNS 记录,以提高后续查询的速度和减少网络负载。这种缓存数据可能不是最新的,但通常在有效期内是可靠的
可能 IP 地址已经更新了,但是 DNS 缓存中依然是旧的,有不正确的可能。
如何获得最权威的应答(准确无误的 IP 地址)
从最根部的服务器开始询问,一层一层递归询问
Step1
查找 `.`域名的 DNS 服务器
根 DNS 服务器是 DNS 层次结构的顶层,它们知道所有顶级域(如 `.com`, `.org`, `.net`)的权威 DNS 服务器
Step2
1
| nslookup -qt=NS com. d.root-servers.net
|
在上面的服务器列表中选一个 向他询问com.
的服务器

结果中的这些服务器中存着xxx.com.
的 DNS 记录
Step3
1
| nslookup -qt=NS baidu.com. a.gtld-servers.net
|
再向其中一个服务器询问下一级域名的 NS 记录

又得到了这一级的名称服务器地址与 IP 地址
Step4
如此递归查找,就能找到最准确的 IP 地址
整个流程分别查询了:
- 根域名服务器:根域名服务器提供顶级域名(TLD,如 .com, .org)服务器的地址。
- 顶级域名服务器:顶级域名服务器提供负责该域名的权威域名服务器的地址。
- 权威域名服务器:最终,权威域名服务器回答具体的 DNS 查询,返回域名对应的 IP 地址或其他记录。
注意:在有缓存的情况下可能不会这样递归查找,而是直接返回一个缓存中的 IP 地址(非权威应答),以提升效率。而在无缓存的情况下只能通过这样递归找到最准确的 IP
例 2:cubicy.icu
最终发现`sam.ns.cloudflare.com` 和 `itzel.ns.cloudflare.com` 是 `cubicy.icu` 的权威域名服务器(authoritative nameservers)。也就是说这两个 cloudflare 服务器最终将这个域名翻译成 IP 地址(IPv4:`212.18.248.108` IPv6:`2a04:2b00:13ee::108`)
多次查询,却返回不同的 IP 地址
在刷新 DNS 缓存以后重新查询相同域名的 IPv4 地址,发现返回的结果可能会不一样。也就是说,虽然用户都输入了相同的域名来访问网站,但是 DNS 却解析出了不同的 IP 地址,这样有助于分散用户的流量,减少服务器的负荷
DNS 作为电话簿 记录了什么东西
- A 记录(Address Record):将域名解析为 IPv4 地址。
- AAAA 记录(IPv6 Address Record):将域名解析为 IPv6 地址。
- CNAME 记录(Canonical Name Record):将一个域名指向另一个域名,实现域名的别名。
- MX 记录(Mail Exchange Record):指定邮件服务器的地址,用于电子邮件传递。
- TXT 记录(Text Record):用于存储任意文本信息,常用于验证域名所有权或存储其他信息。
- NS 记录(Name Server Record):指定域名服务器的地址,用于指示哪些服务器负责解析该域名。
- SOA 记录(Start of Authority Record):包含有关区域的权威信息,如主机名、电子邮件地址等。
以 yedou37.top 为例
可以看出解析记录中设置了
1
| CNAME : yedou37.github.io
|
将yedou37.top
和blog.yedou37.top
都指向了另一个域名yedou37.github.io
相当于这些域名都是该域名的别名
可以储存任何文本信息整活
也可以用来进行一些验证
1
| A : 185.199.109.153 !!已经废弃
|
直接把这个域名解析成 IPv4 地址,进行访问
1
| AAAA: ____:____:____:____
|
同理,直接把这个域名解析成 IPv6 地址,进行访问
指定域名服务器的地址,用于指示哪些服务器负责解析该域名
实际查询方法
1
| nslookup -qt=<要查询的DNS记录类型> <要查询的域名>
|
例如:





HTTP :以学在浙大的登录过程为例
step1 请求
GET 请求这个网站的资源

本条是客户端向服务端发送的第一条请求报文
1 2
| GET / HTTP/1.1 Host: courses.zju.edu.cn
|
请求行
请求方法:GET
指的是获取资源
协议版本:HTTP/1.1
URL:courses.zju.edu.cn/
即为学在浙大域名(其实是/
资源相对路径 + Host 主机信息)
请求首部:(GPT)
Host: courses.zju.edu.cn
: 指定了请求的目标主机。
Cookie: _ga=GA1.3.734803494.1720150632
: 包含了客户端的 Cookie 信息,用于跟踪用户状态。
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126"
: 指定了浏览器和平台的信息。
Sec-Ch-Ua-Mobile: ?0
: 指示请求是否来自移动设备。
Sec-Ch-Ua-Platform: "Windows"
: 指定了请求的平台。
Accept-Language: zh-CN
: 指定了客户端接受的语言。
Upgrade-Insecure-Requests: 1
: 指示客户端愿意接受不安全的 HTTP 请求。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36
: 包含了客户端的用户代理信息,用于标识客户端的浏览器和操作系统等信息。
Accept
: 指定了客户端可以接受的响应内容类型及优先级。
Sec-Fetch-Site
, Sec-Fetch-Mode
, Sec-Fetch-User
, Sec-Fetch-Dest
: 这些头部信息用于指示请求的来源、模式、用户状态和目标。
Accept-Encoding
: 指定了客户端可以接受的内容编码方式。
Priority
: 指定了请求的优先级。
Connection: keep-alive
: 指定了连接保持活动状态,以便在同一连接上发送多个请求。
请求体:这里没有。因为请求行和请求首部已经包括了足够的信息
Step2 响应
OK 但是你先重定向到登录界面再说

响应行:
HTTP/1.1 302 FOUND
: 这是响应行
HTTP 协议版本: HTTP/1.1
状态码: 302 FOUND
表示临时重定向
响应首部
Date: Sun, 07 Jul 2024 02:47:45 GMT
: 指示了响应生成的日期和时间。
Content-Type: text/html; charset=utf-8
: 指示了响应体的内容类型和字符集。
Content-Length: 219
: 指示了响应体的长度。
Location: https://courses.zju.edu.cn/login
: 指示了重定向的目标 URL。
Set-Cookie: session=V2-91116175-d......
: 设置了一个 Cookie,用于在客户端保持会话状态。
X-SESSION-ID: V2-91116175-d....
: 提供了一个Session ID 这部分存储在服务器中
响应体
是一个HTML
文件,用于展示重定向临时界面
Step3
通过一连串的`GET`请求报文向阿里巴巴 CDN 请求资源以及向钉钉请求二维码登录的资源。经过层层跳转,最终成功到达统一身份认证平台
Step4
用户名是密码是发送
请求报文:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| POST /cas/login?service=https%3A%2F%2Fidentity.zju.edu.cn%2Faut...... HTTP/1.1 Host: zjuam.zju.edu.cn Cookie: JSESSIONID=843823A78E5F7...._ga=GA1.3.734803494.1720150632; _csrf=S8mwplVi9KWoF2WQ0T.....; _pv0=a%2BbPpo48werJLjOn........QcKI5hri4enKlcIc%2FFznPd9......5KHwU4Zh19eVGv78iF6n6g1%2FtuyiSCPj....RKeyOqWhmSXKSWE%3D Content-Length: 7359 Cache-Control: max-age=0 Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Accept-Language: zh-CN Upgrade-Insecure-Requests: 1 Origin: https://zjuam.zju.edu.cn Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://zjuam.zju.edu.cn/cas/login?service=https%3A%2F%2Fidentity.zju.edu.cn%2Fauth%........MKATudSBwgKUE3Kj44.82Lx1GWEwX0.TronClass Accept-Encoding: gzip, deflate, br Priority: u=0, i Connection: keep-alive
username <学号>&password=<加密后的密码>&authcode=&execution=a244....PZFdKb2FWVlFTVkpKY......TlVWb1FqTlBOWG......VVNEWTNkblJ6UVRZd1pHZFZVakJpVkV.....ldVSTBRVWhEYVdKQ1NuRlJ......yTTFvemQyUkxkbkpwU0V......RalpNZEhsclNURmtjWGRYYVd
|
请求行
请求方法:POST
用于传输实体主体:在这里是我登录用的账号和密码
请求头部
。。。
请求体
在这里包括我的学号和密码+一些操作和信息
Step5
认证成功,以后用这个东西认证就好了,不用再输入账号密码
响应报文 1 转到identity.zju.edu.cn
同时给你一个state
一个ticket
证明你的身份
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| HTTP/1.1 302 Server: nginx/1.20.1 Date: Sun, 07 Jul 2024 03:23:11 GMT Content-Length: 0 Connection: keep-alive Cache-Control: no-store Set-Cookie: CASPRIVACY=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/cas/; Secure Set-Cookie: _pf0=Y0c0PLqewS%2FkUNV...sgeV0WSCcRYwD0fc%3D; Max-Age=86400; Expires=Mon, 08-Jul-2024 03:23:11 GMT; Domain=zju.edu.cn; Path=/; HttpOnly Set-Cookie: _pm0=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Domain=zju.edu.cn; Path=/ Set-Cookie: _pc0=VSzeZuiCEE....vYso7u1TUEtUn8ZBve8iN96HwVdpEUMPukGm4N8Nm2Yjki2I; Domain=zju.edu.cn; Path=/; HttpOnly Set-Cookie: iPlanetDirectoryPro=x8afj....vlCFiArVT700JxST0%2BTG%2FVEGYmB32PRsNNZ1z%2Bic31sctZbPRox7SAfcPufHBXfrya8hXIRjdzOj38emM1s6e%2FsjfBmoSHYfr%2BfPKfFOiExeKc7UfjhDMy%2FQmFThQtxu4TbccRlNdaKxuNulQ2Nb......; Domain=zju.edu.cn; Path=/ Location: https://identity.zju.edu.cn/auth/realms/zju/broker/cas-client/endpoint?state=5A9GipBkotb...&ticket=ST-532998-xn //state 和 ticket 在这里
|
请求报文 2 + 响应报文 2
向identity.zju.edu.cn
发送一堆 cookie 证明可以登录了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| GET /auth/realms/zju/broker/cas-client/endpoint?state=5A9GipBkotbjm..............FBm3bXWT7Ghfh9UMU.glQy8ZGwcWc.TronClass&ticket=ST-532998-xnrcb5Z.......Y6-zju.edu.cn HTTP/1.1 Host: identity.zju.edu.cn Cookie: AUTH_SESSION_ID=ea3335eb-.....80-9201......mFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7fX0.kQAKOWjQDST5zu55PZ4Q0oFKpy31sTi2lmmmm-sy7AM; _ga=GA1.3.734803494.1720150632; CLIENT_URL=; SERVICE="https://identity.zju.edu.cn/auth/realms/zju/broker/cas-client/endpoint?state=5A9GipBkotb.......c.TronClass"; _csrf=S8mwplVi9KWoF2WQ.......eHdU2OQsZQdVk7sXs........vkgqY%3D; _pv0=FAgHPPofat87wLQ.............mVUVWNmw%2BpuOn0ggN9I%2FvmlM2wsCFYMiR%2B6AeE4Wm67AG2OTMkGkr51UftgaVez5......I3moASZOM63lxNLdZkUJsLVFeqicWDMQPBjuGGSoStFIlGsJA4nvwzQ0qBcgJ6faZD4X8PUQN7QCX........k%3D; _pf0=Y0c0PLqewS%2FkNQ48Fi............5S9UNVEzvsgeV.......D0fc%3D; _pc0=VSzeZuiCEEa29jZuv............MPukGm4N8Nm2Yjki2I; iPlanetDirectoryPro=x8afjSQDXWvlCFiAr..................hcuLGUDqgk1%2BdnAnKyB9vibKCLEpZ9D4CJ.......X%2Fe0iElaRHbQ...........%2FnDvaZ62lgiOcIUJ5HFjQNXBC%2F4%3D Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-site Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Accept-Language: zh-CN Referer: https://zjuam.zju.edu.cn/ Accept-Encoding: gzip, deflate, br Priority: u=0, i Connection: keep-alive
|
回应:好的,再设置一堆 cookie 并重定向一下
1 2 3 4 5 6 7
| HTTP/1.1 302 Found Date: Sun, 07 Jul 2024 03:23:12 GMT Content-Length: 0 Connection: keep-alive X-Powered-By: Undertow/1 Set-Cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/zju/; Secure; HttpOnly Set-Cookie:.........
|
请求报文 3 + 响应报文 3
这里的请求报文 cookie 中出现了 session ID 作为会话的唯一标识,从此刻开始,客户端与服务端进行通讯就是在相互交换这个 session ID 来证明彼此的身份了,只要这个 session 仍然在这样维持着,就维持了这个客户端的登录状态,不需要重复输入用户名和密码来证明身份了
1
| session=V2-22215...a8-f474-43a2-ae3f-14f3ef36d78a.MA.1720....40602.7r_GernKC8laNTavpx9W6cjiqgU
|
1 2 3 4
| GET /user/index?ticket=ST-d30043c2-0c13-4f49-a27d-6c127cbfb709.ea3335eb-9469-4e80-9201-14dec28fed32.818132fc-7f3a-49de-b1dd-3fe43bff7371 HTTP/1.1 Host: courses.zju.edu.cn Cookie: _ga=GA1.3.734803.....50632; session=V2-222..8-f474-43a2-ae3f-14f3ef36d78a.MA.17.....0602.7r_GernKC8laNTavpx9W6cjiqgU; _csrf=S8mwplVi9KWoF2WQ0TlCeH.....XspvkgqY%3D; _pv0=FAgHPPofat87wLQmcBGBz.....VUVWNmw%2BpuOn0ggN9I%2FvmlM2wsCFYMiR%2B6AeE4 <!-- omitted -->
|
回应: 再重定向(302 FOUND
)一下,并且设置一个新的 session ID
1
| Set-Cookie: session=V2-1-c6b8...2-6af1-4214-b6a9-ad9bdd5653cf.MjQzNDU2.172....2963.PZl62CoVc4i0gaY6mGl-gDJibjU;
|
1 2 3 4 5 6 7 8 9
| HTTP/1.1 302 FOUND Date: Sun, 07 Jul 2024 03:23:12 GMT Content-Type: text/html; charset=utf-8 Content-Length: 281 Connection: keep-alive Location: https://courses.zju.edu.cn/user/index Access-Control-Expose-Headers: X-SESSION-ID Set-Cookie: session=V2-1-c6b.5....-6af1-4214-b6a9-ad9bdd5653cf.MjQzNDU2.17....92963.PZl62CoVc4i0gaY6mGl-gDJibjU; <!-- omitted -->
|
Step6
到达指定的界面 开始请求资源:通过 session ID 作为标识,维持登陆状态
请求报文 1+响应报文 1
请求course.zju.edu.cn/user/index
即学在浙大用户首页的资源
注意到:这时的 session ID 正好就是上一条响应报文所设置的 session ID(....-gDjbjU
) 说明此时客户端与服务端之间已经再用 session ID 作为相互认证的凭证了
1 2 3 4 5 6
| GET /user/index HTTP/1.1 Host: courses.zju.edu.cn Cookie: _ga=...; _csrf=...; _pv0=...; _pf0=...; _pc0=...; iPlanetDirectoryPro=...; session=V2-1-c6b85.....4i0gaY6mGl-gDJibjU Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 <!-- omitted -->
|
回应:状态码终于不是302
重定向 而是200 OK
成功处理请求。同时,又下达了设置新的 session ID 的命令:
1
| Set-Cookie: session=V2-1-c.....55G9Alo730aNlO4t2lc;
|
可以预见,下一个客户端的请求报文就会使用这个新的 session ID 作为 cookie 的一部分,以证明自己的身份并维持这个会话
在响应体中,服务器也发送了主页面的 HTML 文件用于显示这个网页
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| HTTP/1.1 200 OK ..... Access-Control-Expose-Headers: X-SESSION-ID Set-Cookie: session=V2-1-c.....55G9Alo730aNlO4t2lc; .... Content-Length: 692742
<!doctype html> <html lang="zh-CN" version="1.64.51141-hotfix-v1-64-32af818d" host="https://courses.zju.edu.cn:443/" delivery-org="ZJU"> <head> <script> var sentryClientKey = "None"; sentryClientKey
|
Step7
请求更多资源并维持会话

可以看到:客户端接着向服务器请求了更多资源(GET
),但是似乎只有一些重要或是涉及隐私的资源被请求以后,服务端才会要求设置新的 session ID Set-Cookie: session=...
比如“最近访问的课程”、“课程图片”等,例如上图的 214 条 GET 请求就返回了离散数学课程的封面图并且马上要求更换了 session ID。其他一些 js 脚本的请求都暂时使用同一个 ID。
最终成功进入并加载完成了主页面
请求报文结构:
- 第一行是包含了请求方法、URL、协议版本;
- 接下来的多行都是请求首部 Header,每个首部都有一个首部名称,以及对应的值。
- 一个空行用来分隔首部和内容主体 Body
- 最后是请求的内容主体(可以没有这部分)
1 2 3 4 5 6 7 8 9 10 11 12 13
| GET http://www.example.com/ HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cache-Control: max-age=0 Host: www.example.com If-Modified-Since: Thu, 17 Oct 2019 07:18:26 GMT If-None-Match: "3147526947+gzip" Proxy-Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 xxx
param1=1¶m2=2
|
响应报文结构:
- 第一行包含协议版本、状态码以及描述,最常见的是 200 OK 表示请求成功了
- 接下来多行也是首部内容
- 一个空行分隔首部和内容主体
- 最后是响应的内容主体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| HTTP/1.1 200 OK Age: 529651 Cache-Control: max-age=604800 Connection: keep-alive Content-Encoding: gzip Content-Length: 648 Content-Type: text/html; charset=UTF-8 Date: Mon, 02 Nov 2020 17:53:39 GMT Etag: "3147526947+ident+gzip" Expires: Mon, 09 Nov 2020 17:53:39 GMT Keep-Alive: timeout=4 Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Proxy-Connection: keep-alive Server: ECS (sjc/16DF) Vary: Accept-Encoding X-Cache: HIT
<!doctype html> <html> <head> <title>Example Domain</title> // 省略... </body> </html>
|
请求报文->请求行->方法字段中规定的方法
- GET:从服务器获取资源。GET 请求通常用于请求服务器发送某个资源,而不会对服务器上的资源产生任何影响。
- POST:向服务器提交数据。POST 请求通常用于向服务器发送数据,比如提交表单或上传文件。
- PUT:在服务器上创建或更新资源。PUT 请求通常用于将数据存储到服务器上的指定位置。
- DELETE:从服务器删除资源。DELETE 请求用于请求服务器删除指定的资源。
- PATCH:对资源进行部分修改。PATCH 请求用于对资源进行局部更新。
- HEAD:类似于 GET 请求,但服务器只返回头部信息,不返回实际内容。HEAD 请求通常用于获取资源的元数据,比如大小或类型,而不需要获取实际内容。
- OPTIONS:获取目标资源支持的通信选项。OPTIONS 请求用于获取服务器支持的 HTTP 方法列表,或者查看服务器支持的特定资源的通信选项。
- TRACE:回显服务器收到的请求,用于测试或诊断。TRACE 请求通常用于测试或诊断,客户端可以查看服务器收到的原始请求内容。
其中,DELETE PUT 方法不带有身份验证,比较危险。TRACE 方法同样容易遭受攻击