`
netcome
  • 浏览: 482087 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

UNIX 网络协议的深度分析

阅读更多

引言

网络已经是无处不在,很多时候我们都会利用网络与不同主机进行通信,包括网络内部和外部的。大多数情况下这不会遇到问题,但是有时您需要仔细检查您的网络以查明问题原因。

仔细检查网络流量内容的原因有很多。其中第一个原因是您可能正在调试一个现有的网络应用,或者您正在开发一个应用,而您想要监控通过您的网络的流量。第二个原因是需要识别可能耗尽网络带宽和资源的流量。对于前一种情况,您可能已经知道协议的内容了,但是您希望能够更深入地了解正在传输的实际数据,例如,在使用 Web 服务时。对于后一种情况,确定数据包的内容需要了解正在使用的协议的一些扩展知识。

在 TCP/IP 和 UDP/IP 的通信中,最主要的元素是用于确定主机和端口号的 IP 地址。端口号用于提供额外的通信通道,这样您才能够在两个主机之间实现多个连接。其中端口定义还有一些标准。例如,端口 25 是专用于电子邮件(SMTP)传输,而大多数网站都是运行在端口 80(HTTP)上的。这些规范可以使程序之间通过一个熟悉的通道进行通信,这与您选择电话或传真号的道理是一样的。

虽然有这样一些规范,但是您实际想使用哪些端口是没有任何限制或约束的。事实上,大多数情况下一些破坏性网络应用和一些安全性方法会故意使用非标准端口。例如,有些应用会通过将一个标准端口用于不同的协议而隐藏内容,如在 端口 25 上使用 HTTP 协议。此外,有时某些应用也会使用与标准不同的端口,这样端口的用途就明显了(如,将端口 99 用于 HTTP),或者将特定的协议流量封装到另一个协议中。最后的方法实际上是网络通道和虚拟私有网络(VPN)所使用的方法。

不管网络流量原因和复杂性,第一个步骤都会开始记录数据。

记录原始数据

如果您希望记录网络原始数据,以便自己检查这些信息,那么您可以使用许多不同的工具。大多数的网络嗅探器也能够解码和解密特定的数据包内容,这能够帮助您研究一个已知协议的内容。

在 Solaris 上,您可以使用 snoop 工具,而在 AIX 上,您可以使用 iptrace 工具。您也可以尝试使用跨平台的 tcpdump 工具,它支持大多数的 UNIX 和 Linux 操作系统。这些工具能够帮您捕捉和解码数据包,通常也能为您执行大多数的协议分析。注意,现代交换机不会将 Ethernet 数据包发送到每一个端口上,这通常会限制您从当前主机获取的信息量。许多现代交换机具有一个管理端口,它通常带有与这种监控完全相同的所有数据包的副本。

解码网络传输最复杂的是网络数据包中信息的级别。此外,大部分信息也会经过二进制编码后再发送,从网络捕捉完全原始的数据包需要进行大量的操作才能捕捉您需要的数据。通过使用实现某些处理的工具,您可以简化解码网络数据的过程。

例如,在一个 Ethernet 上查看一个典型的 TCP/IP 协议,您将会发现网络中传输的数据包括:

  • Ethernet 数据包头,包括 Ethernet 来源和目标地址,数据包大小和 Ethernet 数据包类型。
  • IP 报头,由 IP 寻址(来源和目标),协议标识和 IP 标记。您也会得到关于分片和数据包顺序的信息。
  • TCP 报头,它包含端口上的信息、隐含的协议、标记和顺序编号。

即使有这些信息,我们仍然无法了解实际内容。在 TCP(或 UDP)协议之下还有额外的协议,标准数据协议(包括 HTTP、SMTP 和 FTP),或者封装性协议,如 Remote Procedure Call (RPC) 和 RPC 的子类型,如 NFS。

通常这些工具必须使用协议和/或端口号来确定正在传输的内容。所以,如果流量是通过非标准端口传输的,那么这个些信息可能无法正确解码。

基本的网络分析

本文之前提到的许多网络嗅探工具都提供了不同级别的协议解码,它们是通过检查端口和内容来确定所使用的协议实现的。

例如,snoop 和 tcpdump 都提供了关于 UDP 和 TCP 上不同协议的不同级别的详细信息。例如,在 snoop 中,您可以获得从顶级协议到所传输的单个数据块的关于 NFS 操作的详细信息。例如,您可以通过指定监控 RPC 使用 NFS 协议来实现对 NFS 流量的监控:$ snoop -v rpc nfs

它能输出非常详细的数据包信息,并且它们应该进行更紧密的观察。清单 1 提供了 Ethernet 报头数据。


清单 1. Ethernet 报头数据
				
ETHER:  ----- Ether Header -----
ETHER:  
ETHER:  Packet 64 arrived at 16:14:41.79434
ETHER:  Packet size = 238 bytes
ETHER:  Destination = 0:1a:ee:1:1:c0, 
ETHER:  Source      = 0:21:28:3c:c0:61, 
ETHER:  Ethertype = 0800 (IP)
ETHER:  

这里的输出表明 Ethernet 数据包包含了 IP 数据、全部数据包大小和时间,以及数据包的目标和来源地址。

清单 2 显示的是 IP 报头。其中除了协议和来源/目标地址信息,其余许多 IP 数据是没有用的。


清单 2. IP 报头
				
IP:   ----- IP Header -----
IP:   
IP:   Version = 4
IP:   Header length = 20 bytes
IP:   Type of service = 0x00
IP:         xxx. .... = 0 (precedence)
IP:         ...0 .... = normal delay
IP:         .... 0... = normal throughput
IP:         .... .0.. = normal reliability
IP:         .... ..0. = not ECN capable transport
IP:         .... ...0 = no ECN congestion experienced
IP:   Total length = 224 bytes
IP:   Identification = 27460
IP:   Flags = 0x4
IP:         .1.. .... = do not fragment
IP:         ..0. .... = last fragment
IP:   Fragment offset = 0 bytes
IP:   Time to live = 64 seconds/hops
IP:   Protocol = 6 (TCP)
IP:   Header checksum = 4d11
IP:   Source address = 192.168.0.112, tiger.mcslp.pri
IP:   Destination address = 192.168.0.2, bear.mcslp.pri
IP:   No options
IP:

在 清单 3 中,您可以看到 TCP 报头。同样,这些信息中通常只有来源和目标端口号才是有用的,因为这些信息将可用于确定预期的协议,或者提供给您可用于更进一步观察这个端口所传输流量的信息。


清单 3. TCP 报头
				
TCP:  ----- TCP Header -----
TCP:  
TCP:  Source port = 2049
TCP:  Destination port = 889 (Sun RPC)
TCP:  Sequence number = 2834727685
TCP:  Acknowledgement number = 2654368001
TCP:  Data offset = 32 bytes
TCP:  Flags = 0x18
TCP:        0... .... = No ECN congestion window reduced
TCP:        .0.. .... = No ECN echo
TCP:        ..0. .... = No urgent pointer
TCP:        ...1 .... = Acknowledgement
TCP:        .... 1... = Push
TCP:        .... .0.. = No reset
TCP:        .... ..0. = No Syn
TCP:        .... ...0 = No Fin
TCP:  Window = 32806
TCP:  Checksum = 0x4852
TCP:  Urgent pointer = 0
TCP:  Options: (12 bytes)
TCP:    - No operation
TCP:    - No operation
TCP:    - TS Val = 34449495, TS Echo = 253458642
TCP:

清单 4 的倒数第二部分显示的是 RPC 报头数据。


清单 4. RPC 报头数据
				
RPC:  ----- SUN RPC Header -----
RPC:  
RPC:  Record Mark: last fragment, length = 168
RPC:  Transaction id = 3041181596
RPC:  Type = 1 (Reply)
RPC:  This is a reply to frame 63
RPC:  Status = 0 (Accepted)
RPC:  Verifier   : Flavor = 0 (None), len = 0 bytes
RPC:  Accept status = 0 (Success)
RPC:  

最后,清单 5 提供了 NFS 数据包内容,包括权限(文件模式)、文件大小、拥有者和其他信息。在这里,这个 NFS 操作请求是进行文件系统统计(这等同于 ls 操作结果),因此这就是详细信息。


清单 5. NFS 数据包内容
				
NFS:  ----- Sun NFS -----
NFS:  
NFS:  Proc = 18 (Get filesystem statistics)
NFS:  Status = 0 (OK)
NFS:  Post-operation attributes: 
NFS:    File type = 2 (Directory)
NFS:    Mode = 0777
NFS:     Setuid = 0, Setgid = 0, Sticky = 0
NFS:     Owner's permissions = rwx
NFS:     Group's permissions = rwx
NFS:     Other's permissions = rwx
NFS:    Link count = 24, User ID = 502, Group ID = 10
NFS:    File size = 29, Used = 2560
NFS:    Special: Major = 4294967295, Minor = 4294967295
NFS:    File system id = 781684113418, File id = 4304616
NFS:    Last access time      = 28-Feb-10 15:49:51.042953989 GMT
NFS:    Modification time     = 25-Feb-10 09:39:07.965422590 GMT
NFS:    Attribute change time = 25-Feb-10 09:39:07.965422590 GMT
NFS:  
NFS:  Total space = 759567510016 bytes
NFS:  Available space = 659048374272 bytes
NFS:  Available space - this user = 659048374272 bytes
NFS:  Total file slots = 1288161604
NFS:  Available file slots = 1287203856
NFS:  Available file slots - this user = 1287203856
NFS:  Invariant time = 0 sec
NFS: 

在这里,我们可以看到所查询的文件事实上是一个目录(见文件类型行)。虽然我们没有得到文件的实际路径,但是我们可以通过使用 Find 命令来查询 inode 号对应的文件/路径来查找上面提到的目录(见 清单 6)。


清单 6. 查询 inode 号对应的文件
				
$ find /scratch -xdev -inum 4304616
/scratch/installed/mysql-6.0.11

如果您准备分辨流量,那么使用这些工具的最佳方法是首先运行它们,收集尽可能多的数据,然后手动检查数据内容,找出您的网络本来不应该出现的数据项。

一旦您识别出了可疑流量,您就可以开始在命令行上添加参数以便关注于流量细节。例如,您可以使用 清单 7 所示的命令之一,规定只显示特定主机的流量。


清单 7. 规定只显示一个特定主机的流量
				
$ snoop host 192.168.0.2
$ tcpdump host 192.168.0.2

要进一步限制,您可以限制协议信息的端口:$ snoop host 192.168.0.2 and port 25

解析原始数据以理解数据包内容

处理来自 tcpdump 的另一个方法是将原始网络数据包数据保存到一个文件中,然后处理这个文件以便查找和解码出您想要的信息。

有许多使用不同语言编写的模块具有读取和解码 tcpdump 和 snoop 捕捉的数据的功能。例如,有两个用 Perl 编写的模块:Net::SnoopLog(针对 snoop)和 Net::TcpDumpLog(针对 tcpdump)。它们将读取原始数据内容。这些模块的基本接口是相同的。

要开始处理,您首先需要使用 snoop 或 tcpdump 将数据写到一个文件,而创建一个通过网络的数据包的二进制记录。对于本例,我们将使用 tcpdump 和 Net::TcpDumpLog 模块:$ tcpdump -w packets.raw

收集网络数据完成后,您就可以开始处理网络数据内容以查找您想要的信息。Net::TcpDumpLog 会解析 tcpdump 所保存的原始网络数据。因为这些数据是以原始的二进制格式保存的,解析这些信息就需要处理这个二进制数据。为了方便起见,您可以使用另一组模块 NetPacket::* 来解码原始数据。

例如,清单 8 显示的是一个打印所有数据包的 IP 地址信息的简单脚本。


清单 8. 打印所有数据包的 IP 地址的简单脚本
				
use Net::TcpDumpLog;
    
use NetPacket::Ethernet;
    
use NetPacket::IP;

    
my $log = Net::TcpDumpLog->new();
 
$log->read("packets.raw");
 
 
foreach my $index ($log->indexes)
       
{
    
    my $packet = $log->data($index);
           

    my $ethernet = NetPacket::Ethernet->decode($packet);

  
    if ($ethernet->{type} == 0x0800)
       
    {
    
        my $ip = NetPacket::IP->decode($ethernet->{data});
          

    
        printf("  %s to %s protocol %s \n",
               $ip->{src_ip},$ip->{dest_ip},$ip->{proto});
   }

} 

第一部分是提取每一个数据包。Net::TcpDumpLog 模块会将每一个数据包序列化,这样我们就能够通过数据包 ID 读取每一个数据包。然后 data() 函数就会返回整个数据包的原始数据。

通过 snoop 的输出,我们必须从原始网络数据包信息中提取每一个数据块。所以在本例中,我们首先需要从原始网络数据包中提取 Ethernet 数据包,包括数据有效负载。而 NetPacket::Ethernet 模块能够帮我们执行这个操作。

因为我们寻找的是 IP 数据包,所以我们能通过检查 Ethernet 数据包类型来检查 IP 数据包。IP 数据包的 ID 为 0x0800。

然后,NetPacket::IP 模块会被用于从 Ethernet 数据包的数据负载中提取出 IP 信息。这个模块能提供来源 IP、目标 IP 和协议信息等等,然后我们可以打印出这些信息。

通过使用这个基本的框架,您就能够执行不依赖于 tcpdump 或 snoop 的自动化解决方案的更复杂查询和解码。例如,如果您怀疑 HTTP 流量是通过一个非标准端口传输的(如,不是端口 80),那么您可以使用 清单 9 中的脚本在怀疑的主机 IP 的非 80 端口上检查 HTTP 数据包。


清单 9. 在非 80 端口上检查 HTTP 数据包
				
use Net::TcpDumpLog;
    
use NetPacket::Ethernet;
    
use NetPacket::IP;
    
use NetPacket::TCP;
    

    
my $log = Net::TcpDumpLog->new();
       
$log->read("packets.raw");
       

    
foreach my $index ($log->indexes)
       
{
    
    my $packet = $log->data($index);
       

    
    my $ethernet = NetPacket::Ethernet->decode($packet);
       

    
    if ($ethernet->{type} == 0x0800)
       
    {
    
        my $ip = NetPacket::IP->decode($ethernet->{data});
          

    
        if ($ip->{src_ip} eq '192.168.0.2')
       
        {
    
            if ($ip->{proto} == 6)
       
            {
    
                my $tcp = NetPacket::TCP->decode($ip->{data});
       
                if (($tcp->{src_port} != 80) &&
               
                    ($tcp->{data} =~ m/HTTP/))
       
                {
    
                    print("Found HTTP traffic on non-port 80\n");
    
                    printf("%s (port: %d) to %s (port: %d)\n%s\n",
    
                           $ip->{src_ip},
       
                           $tcp->{src_port},
       
                           $ip->{dest_ip},
       
                           $tcp->{dest_port},
       
                           $tcp->{data});
 
                }
    
            }
    
        }
    
   }
    
}

在一个示例数据包集上运行上面的脚本会返回如 清单 10 所示的结果。


清单 10. 在一个示例数据包集上运行这个脚本
				
$ perl http-non80.pl
Found HTTP traffic on non-port 80
192.168.0.2 (port: 39280) to 168.143.162.100 (port: 80)
GET /statuses/user_timeline.json HTTP/1.1
Found HTTP traffic on non-port 80
192.168.0.2 (port: 39282) to 168.143.162.100 (port: 80)
GET /statuses/friends_timeline.json HTTP/1

在这种特定的情况下,我们发现主机的流量是通向一个外部网站(Twitter)。

显然,在这个例子中我们处理的是原始数据,但是您可以使用相同的基本结构进行解码,也可以使用任何公开或私有协议结构的格式的数据。如果您正在使用这个方法使用或开发一个协议,并且您知道协议格式,您就能够提取和监控正在传输的数据。

使用一个协议分析器

虽然,正如之前提到的,诸如 tcpdump、iptrace 和 snoop 等工具都提供了基本的网络分析和解码功能,但是还有一些基于 GUI 的工具使这个过程更简单。Wireshark 就是其中一个工具,它支持大量的网络协议解码和分析。

Wireshark 的最主要优点之一是您可以捕捉一段时间内的数据包(如 tcpdump 一样),然后基于不同的协议、端口和其他数据交互地分析和过滤内容。Wireshark 也支持大量的协议解码器,这使您能够检查每分钟内数据包和会话的详细内容。

您可以看到 Wireshark 的简单截图显示了所有类型的所有数据包,如 图 1 所示。这个窗口分成三个主要部分:过滤的数据包列表、解码的协议明细和 HEX/ASCII 格式的原始数据包数据。


图 1. Wireshark 界面
Wireshark 界面接口 

作为 Wireshark 工具所提供的一个级别的信息和解码的例子,在撰写本文时我注意网络中的一个 MySQL 服务器返回了一些错误数据包。

为了专注于内容,我首先对输出应用了 MySQL 过滤。您可以通过在 Filter 输入框中输入一个表达式(类似于 tcpdump、snoop 或 iptract)。或者,您可以单击 Expression 按钮,然后从内置的列表的中选择一种过滤。您可以在 图 2 中看到一组示例过滤。一旦您选择了某个过滤,单击 Apply 就可以过滤数据包列表。


图 2. 选择一个 Wireshark 过滤
选择一个 Wireshark 过滤的截图 

通过过滤 MySQL 协议,我能够确定错误的数据包。MySQL 协议会传到一个带有错误信息的特殊数据包类型。在这里,错误 1242 表示查询操作失败,由于子查询有问题。您可以通过展开 Wireshark 窗口的 MySQL 协议部分查看 MySQL 协议的内容,如 图 3 所示。


图 3. 检查一个 MySQL 错误数据包
检查一个 MySQL 错误数据包的截图 

在这里我们可以看到错误的明细。通过跟踪之前的 ‘Request Query’ 数据包,我们就可能确定出导致产生错误响应的查询(图 4)、


图 4. 导致产生错误响应的 MySQL 查询
导致产生错误响应的 MySQL 查询的截图 

通过分析数据包,我能够识别之前并没有注意的错误代码,并且能够指出这个错误及导致发生问题的查询。

Wireshark 支持广泛的协议和过滤器,您可以用它们获得详细的信息。它的另一个常见用途是监控详细协议的确切内容,如 Web 服务。图 5 显示了一个来自 SOAP 请求用于记录状态信息的详细(且结构清晰的)信息。


图 5. 查看 SOAP Web 服务请求的详细信息
SOAP Web 服务请求的详细信息截图 

这些详细信息在调试您使用的任何网络协议时是非常有用的。

Wireshark 的另一个有用的特性是它能够处理即时信息,并且它能够记录信息以备将来过滤和处理。这表示您可以使用它监控某个时期的可疑流量,然后您可以在恰当的时候分析这些信息,以查明您的网络中发生了什么操作。

结束语

对于通过您的 UNIX 网络的信息进行协议分析可能是一个复杂的过程。但是,通过使用一些简单而广泛使用的工具,您可以解码和检查您的流量的详细信息,包括来源和目标等基本信息,以及具体的协议和传输的数据。

如本文所述,通过使用诸如 tcpdump、snoop 或 iptrace 的工具,您可以在命令行上提取大量的数据。通过使用诸如 Wireshark 的工具,您可以更一地步地了解更大范围的协议和内容的更多详细信息。对于自定义的协议和结构,您可以使用 Perl 提取原始数据,并获得您需要的所有信息。


分享到:
评论

相关推荐

    TCP-IP详解卷3:TCP事务协议,HTTP,NNTP和UNIX域协议.rar

    《TCP/IP详解卷3:TCP事务协议,HTTP,NNTP和UNIX域协议》是一本深入解析网络通信协议的专业书籍,其内容涵盖了TCP/IP协议栈中关键的几个层面。本卷主要关注TCP事务协议、HTTP超文本传输协议、NNTP新闻传输协议以及...

    Unix网络编程技术与分析

    总的来说,“Unix网络编程技术与分析”是一门深度和广度兼具的学科,涵盖了从底层网络协议到上层应用开发的方方面面。通过学习和实践,开发者能够构建出高效、稳定的网络服务。书本源码的提供更是为深入理解和实践...

    Unix网络编程源码

    通过深入分析这些源码,读者不仅可以掌握Unix网络编程的基本技能,还能理解高级主题,如性能优化、并发控制和协议实现细节。这不仅有助于提升编程能力,也为解决实际网络问题提供了宝贵的经验。

    unix操作系统源代码分析

    这本书将带你穿越到Unix的内部世界,解析其核心组件,如进程管理、内存管理、文件系统、设备驱动、网络协议栈等关键模块。 首先,进程管理是Unix操作系统中的核心部分。书中会详细介绍如何创建、调度和销毁进程,...

    Unix操作系统源码分析

    《Unix操作系统源码分析》是一本深度探讨Unix操作系统内核的专著,旨在为Unix操作系统编程人员和学术界提供深入的理解和洞见。通过详细分析源代码,本书旨在揭示Unix系统的工作原理,帮助读者掌握其核心机制,从而...

    unix网络编程学习资料

    《Unix网络编程》是一本深度探讨网络编程的经典之作,尤其对于TCP和UDP套接字编程提供了详尽的解析。在Unix系统中,网络编程是构建分布式应用的基础,它涉及到操作系统内核、网络协议栈以及应用层接口等多个层面的...

    昂氏unix源代码分析

    《昂氏Unix源代码分析》是一本深度探讨操作系统内核的专著,主要聚焦于Unix系统,特别是由著名计算机科学家丹尼斯·里奇和肯·汤普逊开发的早期版本。Unix作为现代操作系统的重要基石,对后来的Linux等系统有着深远...

    Cacti for LinuxUnix(网络流量监测图形分析工具) v1.2.24.gz

    Cacti是一款基于Web的网络监控和图形生成工具,专为Linux和Unix系统设计,用于实时监控网络设备的性能和流量。在这个版本v1.2.24.gz中,我们得到了Cacti的源码,这使得用户可以自定义、扩展和深度集成到自己的IT环境...

    Unix网络编程

    "Unix网络编程"是一门深度探讨如何在Unix环境中进行网络通信的学科,它涵盖了网络编程的基本概念、协议、API以及实际应用案例。下面将详细阐述这方面的知识。 一、网络编程基础 网络编程涉及的主要概念是TCP/IP协议...

    unix网络编程.3E

    《Unix网络编程》第三版(Unix Network Programming, 3rd Edition),简称UNPv3,是网络编程领域的一本经典著作。这本书由W. Richard Stevens撰写,深入浅出地介绍了在Unix系统上进行网络通信的各种技术和实践。"EN...

    UNIX网络编程第2卷

    《UNIX网络编程第2卷》以其深度和实用性,为读者揭示了网络编程的奥秘,是学习和提升网络编程技能的宝贵资源。结合PDF文件中的详细内容,读者可以全面掌握UNIX和Linux环境下的网络编程技术,从而开发出高效、稳定的...

    UNIX 网络编程

    本书被誉为经典的UNIX网络编程指南,提供了丰富的实践经验和深度的技术洞察,是网络编程领域的必读之作。 ### 一、重要性与更新内容 随着分布式应用和网络服务的发展,深入理解socket和其他关键网络API变得至关...

    莱昂氏UNIX源代码分析

    4. **网络编程**:讲解了UNIX下的套接字API,如何实现进程间的网络通信,以及TCP/IP协议栈的实现细节。这对于进行网络应用开发具有指导意义。 5. **设备驱动**:描述了如何通过设备驱动程序与硬件交互,以及中断...

    unix 源代码分析

    通过分析socket编程接口和网络协议的源代码,可以理解网络数据传输的过程,这对于网络编程至关重要。 此外,Unix提供了一系列强大的命令行工具,这些工具的源代码往往简洁明了,体现了Unix的“做一件事并做好”的...

    UNIX源代码分析

    这本书以其详尽的分析和深度解读,为读者揭示了UNIX操作系统的内在工作机制,是学习操作系统设计与实现的重要参考。 UNIX系统是现代操作系统的基础,其设计理念和实现技术对后来的Linux、BSD等开源操作系统产生了...

Global site tag (gtag.js) - Google Analytics