> For the complete documentation index, see [llms.txt](https://fnil.gitbook.io/computer-networking/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fnil.gitbook.io/computer-networking/shi-yan/lab-2-ying-yong-ceng-xie-yi-mo-ni-yu-guan-cha.md).

# Lab 2：应用层协议模拟与观察

## 一、实验目的

1. 掌握 Telnet、Netcat、Dig 等网络工具的基本使用方法；
2. 通过逐步模拟 HTTP、SMTP 等常见应用层协议的通信过程，理解应用层协议的工作原理；
3. 观察和分析 DNS 解析过程，体会 DNS 服务在网络连接中的重要性；
4. 培养网络故障排除和调试能力，学会使用工具来诊断和解决网络通信中可能出现的问题。

## 二、实验原理

### 2.1 Telnet

Telnet 是一种用于远程登录到计算机或设备的网络协议。它允许用户通过网络连接到远程主机，并在远程主机上执行命令。Telnet 客户端通过建立到目标主机的 TCP 连接来连接到远程主机的 Telnet 服务器。一旦连接建立，用户可以在远程主机上执行命令，就好像直接在该主机上操作一样。

Telnet 是一种基于文本的协议，它传输的数据是明文的，不提供加密或安全性保护。SSH（Secure Shell）是 Telnet 的安全替代品，提供了加密的连接，确保通信的安全性，并且提供了身份验证机制，防止中间人攻击等安全问题。因此 SSH 是企业和个人更常用的远程登录方式，Telnet 则主要用于教学、测试和一些内部网络中。

在本实验中，我们将使用 Telnet 来模拟网络浏览器和邮件服务器的行为，也即手动进行 HTTP（Hyper-Text Transfer Protocol 超文本传输协议）和 SMTP（Simple Mail Transfer Protocol 简单邮件传输协议）的交互。这两个协议的原理和内容已经在课本和课件中介绍过，因此在实验部分不再赘述。

### 2.2 Netcat

Netcat，也称为 nc，是一个网络工具，可以在计算机网络中建立 TCP 或 UDP 连接，并允许用户进行数据传输。Netcat 可以用于创建简单的服务器和客户端，进行端口扫描、数据传输等操作。它是一种强大的网络工具，常用于网络调试和安全测试。

### 2.3 Dig

Dig 是一个用于 DNS （Domain Name System 域名系统）查询的命令行工具。通过 Dig，用户可以查询域名的 DNS 记录，如域名对应的 IP 地址、邮件服务器记录等。Dig 可以用于诊断网络问题、验证 DNS 配置以及观察 DNS 解析过程。

## 三、实验任务

尽管本实验使用的网络工具都有 Windows 版本，但是由于 Linux 环境下配置更简便、运行更稳定、可用性更高，强烈建议同学们使用 Linux 环境的命令行进行实验。

实验 3.2 和 3.4 会涉及到 Wireshark 抓包，为了捕获虚拟机的分组，你可以选择直接在虚拟机内安装 Wireshark ，使用一些网络服务后观察应该选择哪个网络接口。也可以选择在主系统抓包，使用虚拟机对应的网络接口，例如“VMware Network Adapter VMnet8”等。

### 3.1 使用 Telnet 发送 HTTP 请求

在终端中运行 `telnet www.example.com http` ，这将告诉 telnet 程序在你的计算机和另一台名为 [www.example.com](http://www.example.com) 的计算机之间建立连接，并在该计算机上运行 http 服务。

如果你的计算机正确连接到互联网，你将看到：

```sh
srs@srs-virtual-machine:~/Desktop$ telnet www.example.com http
Trying 93.184.215.14...
Connected to www.example.com.
Escape character is '^]'.
```

输入`GET / HTTP/1.0` <mark style="background-color:blue;">回车</mark>，这是 HTTP 请求行，表示使用HTTP GET方法，请求路径为根路径，协议版本为HTTP/1.0。请求路径是 URL 中第三个斜线之后的部分，此例中我们请求服务器的根目录下的资源。

输入`Host: www.example.com` <mark style="background-color:blue;">回车</mark>，这是向服务器提供主机部分的 URL，也即 http\:// 和第三个斜线之间的部分。

再次 <mark style="background-color:blue;">回车</mark>，这将发送一个空行，告知服务器你的 HTTP 请求已经结束。

正确的返回结果应该以 `HTTP/1.0 200 OK` 开始，表示服务器正常地应答了你的请求。

**提交内容1**：进行以上操作和获取到的应答的命令行截图，并与直接使用浏览器访问该网页的内容进行对比。

如果要退出连接，输入`ctrl` 加 `]`，再输入`close`后 <mark style="background-color:blue;">回车</mark>。如果太长时间没有发送请求，连接也可能因为超时自动中断。

### 3.2 使用 Telnet 登陆 SMTP 服务器发送邮件

为了完成这个实验，你需要一个支持非 SSL 的 SMTP 服务的邮箱，已知可用的有网易邮箱；腾讯企业邮（复旦学邮）和QQ邮箱疑似仅支持使用 SSL 的 SMTP。在邮箱设置中打开 SMTP 服务，并获取 SMTP 服务器地址等信息。

#### 3.2.1 邮箱登陆

下文每条指令输入完成后都需要<mark style="background-color:blue;">回车</mark>。

在终端中执行`telnet smtp.163.com 25`，表示使用 Telnet 登陆邮件服务器，中间的 SMTP 服务器地址因服务提供商而异，25 是 SMTP 服务的默认端口，如果遇到问题则检查服务提供商是否自定义了端口。如果运行正常，终端会显示类似这样的一条欢迎信息：`220 163.com Anti-spam GT for Coremail System (163com[20141201])`。

输入`helo 163`向服务器表明身份，helo 后可以为任意内容。服务器应该返回 `250 OK`。

输入`auth login`开始身份认证，服务器会返回`334 dXNlcm5hbWU6`。

输入base64编码的邮箱地址，例如`U1JTX1RhbmdzaGFuMjAxMUAxNjMuY29t`，服务器会返回`334 UGFzc3dvcmQ6`。提供在线base64编码解码的网站有很多，可以参考这个[链接](https://www.toolhelper.cn/EncodeDecode/Base64)。

输入base64编码的邮箱密码，例如`TmV0d29yazIwMjM=`，若密码正确服务器会返回`235 Authentication successful`。注意有些服务提供商允许直接使用账号密码登陆 SMTP 服务器，有些则要求使用在开启 SMTP 服务时获取的登陆授权码，请根据自己邮箱情况进行操作。

#### 3.2.2 发送邮件

在以上终端中继续操作。

输入 `mail from:<sender@163.com>`，这里要输入真实的发件地址，即本邮箱地址。服务器会返回`250 Mail OK`。

输入 `rcpt to:<receiver@qq.com>`，这里要输入一个能接收到邮件的地址，建议使用你的另一个邮箱。服务器仍旧返回`250 Mail OK`。

输入 `data`，表示开始输入邮件内容，服务器会返回`354 End data with <CR><LF>.<CR><LF>`，提示你在邮件结尾如何标示结束。

输入 `subject: Prepare for mail`，表示邮件标题。标题为空会大大增加被判定为垃圾邮件的概率，本实验不要求同学们的邮件不被判定为垃圾邮件，但邮件服务提供商可能会直接丢弃极端垃圾邮件，导致无法观察到实验效果。

输入 `from:lex@163.com`，表示邮件中的发件人。你可能注意到，我们之前已经输入过mail from了，所以这里的发件人并不一定是真实的发件人，可以随意捏造，而且不是所有邮箱客户端都能识别这种诡计。

输入 `to:parser@fudan.edu.cn`，表示邮件中的收件人，同样不一定是真实的。

此处<mark style="background-color:blue;">回车</mark>，也即空一行，然后开始写邮件正文。

输入任意邮件内容，例如：`Hello, this email is to prepare for the lab class this Friday!` 邮件内容太短同样有可能被判定为垃圾邮件。

<mark style="background-color:blue;">回车</mark>后输入`.`再<mark style="background-color:blue;">回车</mark>，单独占一行的 “.” 标示邮件结束，服务器会返回`250 Mail OK queued as zwqz-smtp-mta-g0-1,_____wAnYj3DGhFlXhX2BA--.19627S2 1695620410`。

此时你应当可以在收件邮箱的收件箱或垃圾邮箱找到你刚刚发送的邮件，如下图：

<figure><img src="https://4116762772-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiTMk5wMcvy5JOiK7dkqh%2Fuploads%2F7RoGlAgkxq4y83EDppWr%2Fimage.png?alt=media&amp;token=f55a1974-b23e-4f58-9c94-eb30b0dd714c" alt=""><figcaption></figcaption></figure>

如果要退出邮件服务器，输入 `quit`，服务器会返回`221 Bye`。

**提交内容2**：使用 telnet 发送邮件的过程截图，以及网页客户端中对方收到的邮件的截图。

**提交内容3：**&#x5728;发送邮件的过程中，通过 Wireshark 抓包，截图并分析 SMTP 发送邮件的过程。

报文和命令行均使用明文或可解码的base64传递密码，请在报告中给邮箱密码打码，并建议在实验开始前和完成后均修改邮箱密码以防止泄露。

SMTP 还支持发送附件等功能。除了使用 Telnet 命令行，Python 也内置了对 SMTP 的支持。另外，旧版本的课本还包含对接收邮件的 POP3 协议的介绍，使用 Telnet 手动执行 POP3 的操作流程与 SMTP 基本相同，但是 POP3 由于功能受限和安全问题已经逐步被 IMAP 取代。感兴趣的同学可以自己探索。

### 3.3 使用 Telnet 和 Netcat 模拟客户端/服务器模型

在一个终端中执行 `netcat -v -l -p 9090`，这表示启动 netcat 监听9090端口，-v表示详细模式，-l表示监听模式。如果运行正常，你会看到`Listening on 0.0.0.0 9090`，此时这个终端相当于一个等待客户端发起连接的服务器。

让上一个终端保持运行，在另一个终端窗口运行`telnet localhost 9090`，这个新终端会作为客户端向服务器端发起连接请求。如果运行正常，客户端会出现`Connected to localhost.`，而服务器端会出现`Connection received on localhost xxxxx`。

此时继续向客户端终端中输入任意字符串，字符串会被传输到服务器端；类似地，在服务器端终端输入的内容也会被传输到客户端，我们的客户端和服务器之间已经建立了双向的可靠数据传输连接。如果在服务器端`Ctrl+C` 终止当前进程，客户端进程也会被自动关闭。

**提交内容4**：使用 Telnet 和 Netcat 模拟客户端和服务器进行信息传输的截图。

### 3.4 使用 Dig 观察 DNS 请求过程

执行 `dig +trace www.baidu.com` ，表示使用 dig 查询域名 [www.baidu.com](http://www.baidu.com) 的 IP 地址。当使用 `+trace` 选项时，`dig` 命令将从根域名服务器开始逐步追踪域名的解析过程，显示每个步骤中涉及的域名服务器和相应的 IP 地址，帮助你了解 DNS 解析是如何在不同级别的域名服务器之间进行的。

**提交内容5**：观察并分析 DNS 查询过程，判断查询采用的是递归查询还是迭代查询，并说明理由。

**提交内容6**：在 DNS 查询过程中使用 Wireshark 抓包，任选一对 DNS 请求与应答分组，解释 DNS 报文中各个字段的含义，以及标志（flag）字段中各个 flag 位的含义。
