网络这东西就是一个靠实践的东西,只靠看书是不行的。当年在学校还上过史美林教授/张公忠教授所讲的计算机网络体系结构课,用的是Tanabaum写的那本,考试还得了九十多分,可实际还是连TCP和UDP有什么区别都分不清,就是死记背,到毕业的时候基本上是忘光了,工作后等于重新来过。上班了要在Linux做一些底层的网络处理,不得不从头来学Linux和网络,编程部分主要看Richard Stevens的那几本书:APUE、UNP、TCP/IP Illustraion等,学Linux则看得很杂,市面上各种Linux入门书大都翻了一遍,俺是习惯在书店里看书,爱看书而不爱买书,汗,,然后就是去各大BBS、论坛把他们的精华区都下载下来狂看,边看边实践,基本上在一个月内熟悉了Linux的操作。
学网络协议刚开始也是看书,但看了之后没多少印象,那些东西靠死记真是没法记的,后来找到一个好办法,就是自己写个sniffer,自己写个协议分析器,先学怎么抓包,就看tcpdump的源码,然后看libpcap的源码,知道了什么是网卡的混杂模式,很快就能抓到网卡上包的。接下来就是对包进行分析,就看作TCP/IP Illustraion,从以太头、ARP/IP、ICMP/IGMP/TCP/UDP、HTTP/FTP/TELNET/SMTP等这么一点一点、一个字段一个字段分析下来,很快就明白了所谓TCP/IP到底是怎么回事。 另外为了学TCP状态转换表,根据所抓的包的TCP标志分析通信双方当前是什么状态,刚开始还只能从头一方发SYN包开始分析,到后来是可从连接中间包如手就能逐渐判断双方的TCP状态,基本上是彻底搞清楚了TCP的状态转移是怎么回事,后来再理解防火墙的状态检测原理就很容易了。另外在分析过程中,为彻底掌握IP碎片,还特地ping大包来抓,把抓上来的包自己重组,搞明白了IP头的碎片offset字段是怎么用的。
能抓包后进而又开始学如何自己构造包来“干扰”正常通信了,开始是学怎么发TCP的RST包来切断一个正常的TCP连接,就的学会如何计算IP头校验和,TCP校验和,知道了算TCP校验和时必须加IP伪头数据,然后是正确计算序列号和确认号,知道了原来SYN和FIN标志也是算一位的,最重要的是理解了什么是网络序什么是主机序,现在基本把ntohs(l),htons(l)处理都成了一种编程的本能意识了。 学会用RST切断TCP后,进一步实现了直接发一个页面信息告诉客户端访问了非法信息,也就是以后实现URL过滤时客户端显示的拒绝画面。
后来也学发ARP信息胡乱通告MAC地址,也就是以前写的那篇ARP攻击的由来。 后来俺写的这个协议分析器逐步完善,能解析的就解析,不能解析的就打印出16进制数,可打印字符也打印出来,对HTTP、FTP、POP3、SMTP这些文本协议几乎就一下看明白了,对于非文本协议,如DNS,也根据协议解析了出来,而且解析DNS时不得不用了我一向不爱用的递归方法来编程。 随着网络应用的增加,在用到前都先作协议解析,除了各种TCP、UDP的协议,还增加了BPDU、PPPOE、OSPF、ESP、AH、IKE等的解析处理,现在俺的协议分析器也可以分析上百种协议,平时抓包就只用俺这个,TCPDUMP基本不再用了,毕竟自己写的自己更清楚,如果有不能解析的再现加进去。
现在学新协议时,往往先抓包看看协议的基本数据格式,再看RFC了解细节。 学协议刚开始是看书,到后来要更深入了解或追询最新发展情况就只能看RFC了,毕竟网络的东西变化太快,书的东西只能算入门,说不定很快就出新的了,到现在也看了数百篇的RFC了。 通过编程分析来学协议,慢是慢了点,花了一个多月的时间,但感觉学得扎实,正所谓磨刀不误砍柴功,而且一通百通。到现在虽然已经好几年了,IP头,TCP头有哪些字段还是一下就可以说得出来,对理解各种网络攻击原理从而进行防范更是有帮助,我觉得对我来说这种方法是很有效,如果哪位觉得有更有效的学习方法,可以共同交流一下。