一、套接字
1、Socket简介
应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字 (Socket)的接口,区分不同应用程序进程间的网络通信和连接。
生成套接字,主要有3个参数:通信的目的IP地址、使用的传输 层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输 层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
要通过互联网进行通信,至少需要一对套接字,一个运行于客户机端,称之为ClientSocket,另一个运行于服务器端,称之为serverSocket。
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
- 服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
- 客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
- 连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客 户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
2、UNIX Domain Socket IPC
socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
3、套接字的分类
常用的TCP/IP协议的3种套接字类型如下所示。
- 流套接字(SOCK_STREAM):流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。
- 数据报套接字(SOCK_DGRAM):数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP(User Datagram Protocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。
- 原始套接字(SOCK_RAW):原始套接字(SOCKET_RAW)允许对较低层次的协议直接访问,比如IP、 ICMP协议,它常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为RAW SOCKET可以自如地控制Windows下的多种协议,能够对网络底层的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。比如,我们可以通过RAW SOCKET来接收发向本机的ICMP、IGMP协议包,或者接收TCP/IP栈不能够处理的IP包,也可以用来发送一些自定包头或自定协议的IP包。网络监听技术很大程度上依赖于SOCKET_RAW。
原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。
二、HTTP协议
1、OSI 与TCP/IP 协议
2、什么是HTTP协议
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
3、HTTP协议特点
- 支持客户/服务器模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
4、HTTP协议之URL
http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。
HTTP URL (URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:
http://host[":"port][something_path]
说明:http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;something_path指定请求资源的URI;如果URL中没有给出something_path,那么当它作为请求URI时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。
举例:
- 输入:www.example.edu.cn
浏览器自动转换成:http://www.example.edu.cn/
- http:192.168.0.116:8080/index.jsp
5、HTTP协议之请求篇
http请求由三部分组成,分别是:请求行、请求头部、请求数据。
5.1、请求行
- 请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:
<Method> <Request-URI> <HTTP-Version> CRLF
其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET 请求获取Request-URI所标识的资源 。
POST 在Request-URI所标识的资源后附加新的数据 。
HEAD 请求获取由Request-URI所标识的资源的响应消息报头 。
PUT 请求服务器存储一个资源,并用Request-URI作为其标识 。
DELETE 请求服务器删除Request-URI所标识的资源 。
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断 。
CONNECT 保留将来使用 。
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求 。
- 资源名称:URI (Uniform Resource Idnentifier)
URL :描述一个特定服务器上某资源的特定位置 ,可以是相对路径,也可以绝对路径
例如:http://www.example.com/download/index.html 可分为三部分:
scheme(方案):http://
服务器:www.example.com
特定服务器上的资源:/download/index.html
5.2、请求头部
Client-IP:客户端IP 。
Referer: 指明了请求当前资源原始资源的URL。
Host(发送请求时,该报头域是必需的):请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。
User-Agent:我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就无法得知我们的信息了。
Accept式首部:
Accept:请求报头域用于指定客户端接受哪些类型的信息。
Accept-Charset:请求报头域用于指定客户端接受的字符集。
Accept-Encoding:请求报头域类似于Accept,但是它是用于指定可接受的内容编码。
Accept-Language:请求报头域类似于Accept,但是它是用于指定一种自然语言。
条件式请求:
Expect::告诉服务器能够发送哪些媒体类型 。
If-Modified-Since: 是否在指定时间内修改过此资源 。
If-None-Match:如果提供的实体标记与当前文档的实体标记不符,就获取此文档 。
跟安全相关请求:
Authorization:请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。
Cookie: 客户端发送给服务器身份标识。
5.3、实体
实体内包含客户端请求服务器的数据。
6、HTTP协议之响应篇
在接收和解释请求消息后,服务器返回一个HTTP响应消息。 HTTP响应也是由三个部分组成,分别是:状态行、消息头部、响应数据。
6.1、状态行格式如下:
<HTTP-Version> <Status-Code> <Reason-Phrase> CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
6.2、状态码
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
200:OK,客户端请求成功 。
201:CREATED,请求已被实现。
3xx:重定向--要完成请求必须进行更进一步的操作。
301: Moved Permanently, 永久重定向 。
302: Found, 临时重定向,会在响应报文中使用“Location: 新位置” 。
304: Not Modified,条件式请求中使用。
4xx:客户端错误--请求有语法错误或请求无法实现。
403:Forbidden,请求被服务器拒绝 。
404: Not Found,服务器无法找到请求的URL 。
405: Method Not Allowed,不允许使用此方法请求相应的URL。
5xx:服务器端错误--服务器未能实现合法的请求。
500:Internal Server Error, 服务器内部错误 。
502:Bad Gateway, 代理服务器从上游服务器收到一条伪响应 。
503:Service Unavailable, 服务暂时不可用 。
505:HTTP Version Not Supported,服务器不支持。
6.3、响应头部
Age:响应持续时间 。
Server: 响应报头域包含了服务器用来处理请求的软件信息。与User-Agent请求报头域是相对应的。
协商首部:
Vary: 首部列表,服务器会根据列表中的内容挑一个最适用的版本发送给客户端 。
Accept-Ranges: 对当前资源来讲,服务器所能够接受的范围类型 。
跟安全相关:
WWW-Authentication:响应报头域必须被包含在401(未授权的)响应消息中,客户端收到401响应消息时候,并发送Authorization报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。
Set-Cookie:服务器端在某客户端第一次请求时发送令牌。
6.4、响应正文就是服务器返回的资源的内容。
7、HTTP协议之HTTP首部
HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。
HTTP消息报头包括普通报头、请求报头、响应报头、实体报头、扩展首部。 每一个报头域都是由名字+“:”+空格+值 组成,消息报头域的名字是大小写无关的。
通用首部:在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,只用于传输的消息。
请求首部:请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
响应首部:允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识的资源进行下一步访问的信息。
实体首部:请求和响应消息都可以传送一个实体。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。
扩展首部:非标准首部,可由程序开发者创建的。
7.1、通用首部:
Connection: 定义C/S之间关于请求、响应的有关选项 。
Connection: keep-alive
Cache-Control: 缓存控制
Via: 显示了报文经过的中间节点
Date:普通报头域表示消息产生的日期和时间
Cache-Control :用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0使用的类似的报头域为Pragma。
请求时的缓存指令包括:no-cache(用于指示请求或响应消息不能缓存)、no-store、max-age、max-stale、min-fresh、only-if-cached;
响应时的缓存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage.
7.2、实体首部:
Location: 资源的新位置
Allow:允许对此资源使用的请求方法
内容相关的首部:
Content-Encoding: 实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
Content-Language:实体报头域描述了资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言阅读者。
Content-Length:实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
Content-Location:资源所在位置
Content-Type:实体报头域用语指明发送给接收者的实体正文的媒体类型。
Content-Range:在整个资源中此实体表示的字节范围
缓存相关:
ETag:实体标签
Expires:实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires实体报头域指定页面过期的时间。
Last-Modified: 实体报头域用于指示资源的最后修改日期和时间。
8、历史版本
0.9 已过时。只接受 GET 一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持 POST 方法,所以客户端无法向服务器传递太多信息。
HTTP/1.0 这是第一个在通讯中指定版本号的HTTP 协议版本,至今仍被广泛采用,特别是在代理服务器中。
HTTP/1.1 当前版本。持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
HTTP/1.1相较于 HTTP/1.0 协议的区别主要体现在:
- 缓存处理
- 带宽优化及网络连接的使用
- 错误通知的管理
- 消息在网络中的发送
- 互联网地址的维护
- 安全性及完整性
9、使用telnet进行http请求
[[email protected] ~]# telnet 192.168.1.8 80
Trying 192.168.1.8...
Connected to 192.168.1.8.
Escape character is '^]'.
GET /index.html http/1.1
Host: 192.168.1.8
HTTP/1.1 200 OK
Date: Sun, 02 Aug 2015 08:40:05 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sun, 02 Aug 2015 08:37:05 GMT
ETag: "22ec0-19-51c4ff52fa1f8"
Accept-Ranges: bytes
Content-Length: 25
Connection: close
Content-Type: text/html; charset=UTF-8
<h1>www.example.com</h1>
Connection closed by foreign host.
三、资源请求过程
一次Web资源请求的具体过程(服务器的角度):
- 建立连接
- 接收请求
- 处理请求
- 访问资源
- 构建响应
- 发送响应
- 记录日志
由于HTTP协议的请求是无状态的连接,故为了提升性能可以使用下面两种方法:并行连接、持久连接。然而两种提升性能的方法都有其优缺点,下面关于两种方法进行比较。
并行连接缺点:
- 每个连接,TCP得在客户端和服务端分配TCP缓冲区,并维持TCP变量。 对于同时为来自数百个不同客户的请求提供服务的web服务器来说,这会严重增加其负担。
- 每个对象都有2个RTT的延迟。
- 每个对象都遭受TCP缓启动,因为每个TCP连接都起始于缓启动阶段。
持久连接缺点:
- 不带流水线(with pipelining):客户只在收到前一个请求的响应后,才发出新的请求。
与非持久连接2个RTT的延迟相比,不带流水线的持久连接已有所改善。
- 带流水线(with pipelining):HTTP客户没碰到一个引用就立即发送一个请求,即HTTP客户可以一个接一个挨着发送各个引用对象的请求。服务器收到这些请求后,也可以一个接一个的发送各个对象的响应。
带流水线,所有引用到的对象一共只经历1个RTT的延时,而不带流水线,每个引用到的对象各有1个RTT的延迟。
带流水线的持久连接中服务器空等请求的时间较少。
四、HTTP协议相关技术补充
1、基础:
高层协议有:文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和HTTP协议等
中介由三种:代理(Proxy)、网关(Gateway)和通道(Tunnel),一个代理根据URI的绝对格式来接受请求,重写全部或部分消息,通过 URI的标识把已格式化过的请求发送到服务器。网关是一个接收代理,作为一些其它服务器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。一 个通道作为不改变消息的两个连接之间的中继点。当通讯需要通过一个中介(例如:防火墙等)或者是中介不能识别消息的内容时,通道经常被使用。
代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的 服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处 理没有被用户代理完成的请求。
网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继 的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
2、协议分析的优势—HTTP分析器检测网络攻击
以模块化的方式对高层协议进行分析处理,将是未来入侵检测的方向。
HTTP及其代理的常用端口80、3128和8080在network部分用port标签进行了规定
3、HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
使用POST方法时,可以设置ContentLenth来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完成前,内 存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。这种攻击方法基本不会留下痕迹。
http://www.cnpaf.net/Class/HTTP/0532918532667330.html
4、利用HTTP协议的特性进行拒绝服务攻击的一些构思
服务器端忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYNFlood攻击(SYN洪水攻击)。
而Smurf、TearDrop等是利用ICMP报文来Flood和IP碎片攻击的。本文用“正常连接”的方法来产生拒绝服务攻击。
19端口在早期已经有人用来做Chargen攻击了,即Chargen_Denial_of_Service,但是!他们用的方法是在两台Chargen 服务器之间产生UDP连接,让服务器处理过多信息而DOWN掉,那么,干掉一台WEB服务器的条件就必须有2个:1.有Chargen服务2.有HTTP 服务
方法:攻击者伪造源IP给N台Chargen发送连接请求(Connect),Chargen接收到连接后就会返回每秒72字节的字符流(实际上根据网络实际情况,这个速度更快)给服务器。
5、Http指纹识别技术
Http指纹识别的原理大致上也是相同的:记录不同服务器对Http协议执行中的微小差别进行识别.Http指纹识别比TCP/IP堆栈指纹识别复杂许 多,理由是定制Http服务器的配置文件、增加插件或组件使得更改Http的响应信息变的很容易,这样使得识别变的困难;然而定制TCP/IP堆栈的行为 需要对核心层进行修改,所以就容易识别.
要让服务器返回不同的Banner信息的设置是很简单的,象Apache这样的开放源代码的Http服务器,用户可以在源代码里修改Banner信息,然 后重起Http服务就生效了;对于没有公开源代码的Http服务器比如微软的IIS或者是Netscape,可以在存放Banner信息的Dll文件中修 改,相关的文章有讨论的,这里不再赘述,当然这样的修改的效果还是不错的.另外一种模糊Banner信息的方法是使用插件。
常用测试请求:
1:HEAD/Http/1.0发送基本的Http请求
2:DELETE/Http/1.0发送那些不被允许的请求,比如Delete请求
3:GET/Http/3.0发送一个非法版本的Http协议请求
4:GET/JUNK/1.0发送一个不正确规格的Http协议请求
Http指纹识别工具Httprint,它通过运用统计学原理,组合模糊的逻辑学技术,能很有效的确定Http服务器的类型.它可以被用来收集和分析不同Http服务器产生的签名。