应用层协议
应用层协议(application layer protocol)定义了运行在不同端系统上的应用程序进程如何相互传递报文。接下来我们就来学习应用层上的一些协议。
在传输层之上,便是应用层。传输层的 UDP 报文和 TCP 报文段的数据部分就是应用层交付的数据。
不同类型的网络应用有不同的通信规则,因此应用层协议是多种多样的,比如 DNS、FTP、Telnet、SMTP、HTTP、RIP、NFS 等协议都是用于解决其各自的一类问题。
DNS 协议
DNS(Domain Name Service 域名服务)协议基于 UDP,使用端口号 53。
由数字组成的 IP 地址很难记忆,所以我们上网使用网站 IP 地址的别名——域名。实际使用中,域名与 IP 地址是对应的,这种对应关系保存在DNS 服务器之中。
在浏览器中输入一个域名后,会有 DNS 服务器将域名解析为对应的 IP 地址。注意这和网络层的 ARP 协议的不同之处:DNS 提供的是域名与 IP 地址的对应关系,而 ARP 提供的是 IP 地址和 MAC 地址的对应关系。
DNS 服务器
DNS 服务器是个分层次的系统:
根 DNS 服务器 :全世界共有 13 台根域名服务器,编号 A 到 M,其中大部分位于美国。
顶级(TLD)DNS 服务器 :负责如 com、org、edu 等顶级域名和所有国家的顶级域名(如 cn 、uk 、jp)。
权威 DNS 服务器 :大型组织、大学、企业的域名解析服务。
本地 DNS 服务器 :通常与我们主机最近的 DNS 服务器。
而域名解析的过程,有迭代查询和递归查询两种方式:
host 命令
在 linux 系统中,可以用 host 命令进行 DNS 查询,查看一个指定域名的 IP,比如要查询 mirrors.aliyuncs.com 的 IP 地址:
host mirrors.aliyuncs.com
下图示例查询 www.shiyanlou.com 的操作,由于实验楼网络限制(非会员用户),只有 mirrors.aliyuncs.com 域名可以查询。
DNS 报文
主机向 DNS 服务器发出的查询叫做DNS 报文,问答报文的内容,都是 IP 和域名的对应信息,问题中包含域名,类型,类信息,回答中包含指针,类型,类,TTL,长度,IP 地址信息。
DNS 缓存和 hosts 文件
之前 DNS 解析查询过程的图中,共发出了 8 份 DNS 报文,这是非常消耗时间的,所以实际应用上使用 DNS 缓存 :当一个 DNS 服务器接收到一个 DNS 回答后,会将其信息缓存一段时间,当再有一个对相同域名的查询时,便可直接回复。
通过 DNS 缓存,其实很多查询都只需要本地 DNS 服务器便可完成。
我们可以用 dig 命令进行域名查询:
# 查询 www.lanqiao.cn 的 ip 地址,+noedns 是不显示 edns 信息
dig www.lanqiao.cn +noedns
输出信息解析:
# 这一部分为应答的统计信息
# - QUERY:查询任务个数,这里为 1 个
# - ANSWER:查询到几条 A 记录(IP 地址),这里为 1 条
# - AUTHORITY:几个权威域名服务器,这里为 0 个
# - ADDITIONAL:几个附加信息,这里为 0 个
; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> www.lanqiao.cn +noedns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28554
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
# 这一部分为问题片段,意思是查询 www.lanqiao.cn 的 A 记录
;; QUESTION SECTION:
;www.shiyanlou.com. IN A
# 这一部分为应答片段,意为查询到的 IP 为 115.29.233.149
;; ANSWER SECTION:
www.shiyanlou.com. 43200 IN A 115.29.233.149
# 这一部分为查询的任务统计信息,比如查询花了多少时间,执行查询的时间等
;; Query time: 8 msec
;; SERVER: 100.100.2.138#53(100.100.2.138)
;; WHEN: Sun Feb 03 17:37:46 CST 2019
;; MSG SIZE rcvd: 51
我们下面用 tcpdump 来捕获 DNS。首先执行命令:
sudo tcpdump -nt udp port 53
53 端口是 DNS 服务器所开放的端口
这个时候并没有什么捕获信息,因为我们还没有开始 DNS 查询。可以使用 host 命令进行域名查询,我们新开一个终端标签执行:
$ host www.shiyanlou.com
回到之前的标签,可以看到 tcpdump 命令的输出:
我们来看第一个数据包,是由本机向首选 DNS 服务器 8.8.8.8 的 53 端口发送的 DNS 查询报文。1943 是查询报文的标识值。+ 代表启用递归查询标志。A? 表示使用 A 类型的查询方式。www.shiyanlou.com 为查询的域名。35 代表 DNS 查询报文的长度为 35 字节。
第二个数据包为应答报文,可以看出标识值和第一个报文的标识值是一样的,1/0/0 表示报文包含 1 个应答资源记录,0 个授权资源记录,0 个额外信息记录。51 代表应答报文的长度为 51 字节。
同理可得出后续报文所代表的含义。
我们还可以使用如下命令查看以十六进制输出的报文内容:
sudo tcpdump -nn -vvv -X udp port 53
注意:要新开一个终端使用 host www.shiyanlou.com 查询域名 IP 后才可见输出。
我们来看第一个数据报,呈现的报文内容实际上是 IP 数据报,包含了 IP 首部,UDP 首部和 DNS 报文,根据之前的学习我们知道 IP 首部是 20 字节,也就是 4500 到 0808 的部分,UDP 首部是 8 字节,也就是 b4e9 到 faf8 的部分。剩下的也就是 DNS 请求报文,一共 35 字节,与括号中的 35 是吻合的。同理可解析其他报文信息。
FTP 协议
FTP(File Transfer Protocol 文件传输协议)基于 TCP,使用端口号 20(数据)和 21(控制)。
它的主要功能是减少或消除在不同操作系统下处理文件的不兼容性,以达到便捷高效的文件传输效果。
FTP 只提供文件传输的基本服务,它采用 客户端—服务器 的方式,一个 FTP 服务器可同时为多个客户端提供服务。
在进行文件传输时,FTP 的客户端和服务器之间会建立两个 TCP 连接:21 号端口建立控制连接,20 号端口建立数据连接。
FTP 的传输有两种方式:ASCII 传输模式和二进制数据传输模式。
我们直接下载一个 FTP 报文信息示例包 ftp.pcap,然后用 tcpdump 解析。
# 下载 ftp.pcap 文件
wget https://labfile.oss.aliyuncs.com/courses/98/ftp.pcap
# 用 tcpdump 命令解析
sudo tcpdump -r ftp.pcap
前面三帧是客户端与服务器的三次握手,连接服务端的 ftp 端口(21),客户端 ip 是 192.168.0.114,服务端 ip 是 192.168.0.193:
01:24:40.499548 IP 192.168.0.114.1137 > 192.168.0.193.ftp: Flags [S], seq 3753095934, win 16384, options [mss 1460,nop,nop,sackOK], length 0
01:24:40.501867 IP 192.168.0.193.ftp > 192.168.0.114.1137: Flags [S.], seq 3334930753, ack 3753095935, win 16384, options [mss 1452,nop,nop,sackOK], length 0
01:24:40.501886 IP 192.168.0.114.1137 > 192.168.0.193.ftp: Flags [.], ack 1, win 17424, length 0
第四帧是服务器向客户端发送相关信息:
01:24:40.503947 IP 192.168.0.193.ftp > 192.168.0.114.1137: Flags [P.], seq 1:31, ack 1, win 65535, length 30
此时控制连接建立完成。再下面的部分就是客户端向服务器端发送请求,然后服务器端响应客户端的过程,比如登录,输出所在路径等操作。
在后面的输出中,还能找到客户端与服务器端建立数据连接时三次握手的过程。
我们这里看到服务器端开放端口号不是 20 是因为 FTP 的工作模式是被动模式(PASV),被动模式中,服务端会创建一个新的随机的非特权端口 P(P> = 1023)与客户端建立数据通道连接。
HTTP 协议
HTTP (HyperText Transfer Protocol 超文本传输协议) 基于 TCP,使用端口号 80 或 8080。
每当你在浏览器里输入一个网址或点击一个链接时,浏览器就通过 HTTP 协议将网页信息从服务器提取再显示出来,这是现在使用频率最大的应用层协议。
这个原理很简单:
点击一个链接后,浏览器向服务器发起 TCP 连接;
连接建立后浏览器发送 HTTP 请求报文,然后服务器回复响应报文;
浏览器将收到的响应报文内容显示在网页上;
报文收发结束,关闭 TCP 连接。
HTTP 报文会被传输层封装为 TCP 报文段,然后再被 IP 层封装为 IP 数据报。
HTTP 请求报文结构:
HTTP 响应报文结构:
可见报文分为 3 部分:
开始行:用于区分是请求报文还是响应报文,请求报文中开始行叫做请求行,而响应报文中,开始行叫做状态行。在开始行的三个字段之间都用空格分开,结尾处 CRLF 表示回车和换行。
首部行:用于说明浏览器、服务器或报文主体的一些信息。
实体主体:请求报文中通常不用实体主体。
请求报文的方法字段是对所请求对象进行的操作,而响应报文的状态码是一个 3 位数字,分为 5 类 33 种:
1xx:通知信息,如收到或正在处理。
2xx:成功接收。
3xx:重定向。
4xx:客户的差错,如 404 表示网页未找到。
5xx:服务器的差错,如常见的 502 Bad Gateway。
我们可以通过浏览器的开发者工具来查看状态码,首先使用浏览器访问 www.lanqiao.cn ,然后通过如下图所示打开浏览器控制台,然后刷新页面,在网络标签里我们可以看到对应资源的获取状态码。
我们随意点击一个记录,然后点击消息头即可看到消息头的信息:
开发者工具对消息做了一些处理,使输出更为易读,如果我们想查看原始头的信息,可以点击原始头按钮。
可以看到消息的请求头和响应头,请求头里包含请求的网址,请求方法,协议版本等。响应头里包含了消息类型,编码,时间等信息。
Telnet 协议
Telnet 简介
Telnet 协议是 TCP/IP 协议族中的一员,是 Internet 远程登录服务的标准协议和主要方式,它基于 TCP 协议,使用端口 23。
终端使用者在本地电脑上使用 telnet 程序,用它连接到服务器,终端使用者可以在 telnet 程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。
Telnet 工作过程
使用 Telnet 协议进行远程登录时必须满足以下条件:
在本地计算机上必须装有包含 Telnet 协议的客户程序;
必须知道远程主机的 IP 地址或域名;
必须知道登录标识与口令。
Telnet 远程登录服务分为以下 4 个过程:
本地与远程主机建立连接。该过程实际上是建立一个 TCP 连接,用户必须知道远程主机的 IP 地址或域名;
将本地终端上输入的用户名和口令及以后输入的任何命令或字符以 NVT ( Net Virtual Terminal ) 格式传送到远程主机。该过程实际上是从本地主机向远程主机发送一个 IP 数据包;
将远程主机输出的 NVT 格式的数据转化为本地所接受的格式送回本地终端,包括输入命令回显和命令执行结果;
最后,本地终端对远程主机进行撤消连接。该过程是撤销一个 TCP 连接。
Telnet 连接远程主机
telnet 使用语法:telnet IP 端口(可选)。
shiyanlou:~/ $ telnet 127.0.0.1 22
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.8
Telnet 测试主机端口
telnet 可以测试目标机器的 TCP 端口是否开放。
例如 telnet IP地址 3389 是用来测试目标机器的 3389 端口是否开放,如果连接失败,可能是以下原因:
防火墙屏蔽
目标机器没有启用相关远程桌面服务(windows)
修改了默认占用 3389 端口。
下图示例使用 telnet 127.0.0.1 端口 测试本地环境端口开放性:
说明本地环境 3389 端口未开放 ,22 端口开放。
下图示例使用 netstat -pantu 验证以上结果(LISTEN 说明为开放状态):
TFTP 协议
TFTP 简介
TFTP( Trivial File Transfer Protocol )是 TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务,它基于 UDP 协议,使用端口 69 。
此协议设计的时候是进行小文件传输的,与 FTP 相比少了许多功能,它只能从文件服务器上获得或写入文件,不能列出目录,不进行认证。
TFTP 也有着它自身的优点:
TFTP 可用于 UDP 环境;比如当需要将程序或者文件同时向许多机器下载时就往往需要使用到 TFTP 协议。
TFTP 代码所占的内存较小,这对于小型计算机或者某些特殊用途的设备来说是很重要的,TFTP 具有更多的灵活性,也减少了开销。
TFTP 报文格式
TFTP 数据报文有 5 种操作码,对应了 5 种报文格式(1、2 报文格式相同):
操作码为 RRQ :读文件请求,客户端请求读取位于服务器上的文件;
操作码为 WRQ :写文件请求,客户端请求写入位于服务器上的文件;
操作码为 DATA :数据包,用于传输数据文件;
操作码为 ACK :确认包,回应确认信息;
操作码为 ERROR :错误包,它用于服务器不能处理读请求或者写请求的情况。
SMTP 协议和 POP3 协议
SMTP 简介
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,它使用 TCP 协议,使用端口 25。
SMTP 存在两个端:
在发信人的邮件服务器上执行的客户端;
在收信人的邮件服务器上执行的服务器端。
SMTP 的客户端和服务器端同时运行在每个邮件服务器上。当一个邮件服务器在向其它邮件服务器发送邮件消息时,它是作为 SMTP 客户在运行。
SMTP 的连接和发送过程
建立 TCP 连接
客户端向服务器发送 HELO 命令以标识发件人自己的身份,然后客户端发送 MAIL 命令
服务器端以 OK 作为响应,表示准备接收
客户端发送 RCPT 命令
服务器端表示是否愿意为收件人接收邮件
协商结束,发送邮件,用命令 DATA 发送输入内容
结束此次发送,用 QUIT 命令退出
SMTP 协议详解及工作过程
POP3 简介
POP3(Post Office Protocol Version 3 )即邮局协议版本 3,是 TCP/IP 协议族中的一员 ,主要用于支持使用客户端远程管理在服务器上的电子邮件,使用 TCP 协议,使用端口 110 。
POP3 邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的 POP3 协议。
POP3 工作过程
用户运行用户代理(如 Foxmail, Outlook Express)
用户代理(以下简称客户端)与邮件服务器(以下简称服务器端)的 110 端口建立 TCP 连接
客户端向服务器端发出各种命令,来请求各种服务(如查询邮箱信息,下载某封邮件等)
服务端解析用户的命令,做出相应动作并返回给客户端一个响应
上述的两个步骤交替进行,直到接收完所有邮件转到下一步,或两者的连接被意外中断而直接退出
用户代理解析从服务器端获得的邮件,以适当地形式(如可读)的形式呈现给用户
(参考邮件服务器之 POP3 协议分析)
POP3 和 SMTP 协同工作
一封邮件的发送过程:
通过 smtp 协议连接到 smtp 服务器,然后发一封邮件给 sohu 的 smtp 服务器;
通过 smtp 协议将邮件转投给 sina 的 smtp 服务器(邮件发送服务器);
将接收到的邮件存储到 gacl@sina.com 这个邮件账号分配的存储空间中;
通过 POP3 协议连接到 POP3 服务器收取邮件;
从 gacl@sina.com 账号的存储空间当中取出邮件;
POP3 服务器将取出来的邮件回送给 gacl@sina.com 账户。
作业
使用 host 命令查看常见网站的 IP 地址,用 tcpdump 抓取 DNS 报文做解读,并截图。参考:tcpdump 抓取命令:sudo tcpdump -vvv -X udp port 53
查看 Linux 的 hosts 文件,并截图。
使用 tcpdump 抓取 HTTP 报文做解读,并截图。参考:浏览器输入一个不存在的网址,抓取状态码为 404 报文。
使用 telnet 命令测试本地端口开放情况,并用 netstat -pantu 命令验证