网络协议

作者 Claymore 日期 2017-04-04
网络协议

http协议

分为两部分:

浏览器向服务器的请求request:

请求行request line,请求头部header,空行blank,请求数据body

\

eg:

get请求例子:

GET /562f25980001b1b106000338.jpg HTTP/1.1
Host img.mukewang.com
User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Accept image/webp,image/*,*/*;q=0.8
Referer http://www.imooc.com/
Accept-Encoding gzip, deflate, sdch
Accept-Language zh-CN,zh;q=0.8
  • 第一行为请求行。

  • 第二行到最后都是请求头部。

    ​ host指出请求目的地。

    ​ User-Agent,用户代理,浏览器和服务器都能访问,是一种向访问网站提供你所使用的浏览器类型、操作系统及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。

  • 这里请求数据为空,这样的话也要有请求数据上面的空行

post请求例子:

POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley

这里比上面多了第四部分请求数据,注意上面的空行

服务器的响应消息 response

状态行response line, header,空行,body

eg:

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
  • 第一行,状态协议,状态码,状态消息

  • 第二,三行 指定客户端使用的一些附加消息。

    Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8

  • 第三部分,空行,跟在消息报头的后面是必须的。

  • 第四部分,响应正文,服务器返回给客户端的文本信息。

状态码

  • 成功2×× 成功处理了请求的状态码。
    • 200 服务器已成功处理了请求并提供了请求的网页。
    • 201 请求成功,一个新的资源已经在服务端创建。
    • 204 服务器成功处理了请求,但没有返回任何内容。
  • 重定向3×× 每次请求中使用重定向不要超过 5 次。
    • 301 请求的网页已永久移动到新位置。当URLs发生变化时,使用301代码。搜索引擎索引中保存新的URL。
    • 302 请求的网页临时移动到新位置。搜索引擎索引中保存原来的URL。
    • 304 如果网页自请求者上次请求后没有更新,则用304代码告诉搜索引擎机器人,可节省带宽和开销。
  • 客户端错误4×× 表示请求可能出错,妨碍了服务器的处理。
    • 400 服务器不理解请求的语法。
    • 401 未授权,客户端没有被认证,请求资源前先认证。
    • 403 服务器拒绝请求,客户端没有权限访问资源,但是客户端已经认证。
    • 404 服务器找不到请求的网页。服务器上不存在的网页经常会返回此代码。
    • 405 所使用的http请求方法在该URL不可用。
    • 410 请求的资源永久删除后,服务器返回此响应。该代码
    • 404(未找到)代码相似,但在资源以前存在而现在不存在的情况下,有时用来替代404 代码。如果资源已永久删除,应当使用 301 指定资源的新位置。
  • 服务器错误5×× 表示服务器在处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
    • 500 服务器遇到错误,无法完成请求。
    • 503 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。

tcp/ip协议

tcp/ip协议是一个集合,统称为TCP/IP。

tcp/ip协议族中有个重要的概念就是分层,tcp/ip按照层次分为四层:(注意http):

如果说IP协议是找到对方的详细地址。那么TCP协议就是把安全的把东西带给对方。

三次握手,四次挥手

三次握手指的是建立连接过程:

TCP报文中有几个字段:

seq:随机码,用来确认

ack:32位,确认序号,ACK为1时有效。

ACK:确认序号有效,标志位

SYN:发起新连接。

FIN:释放连接。

  • 客户端发起连接,发送报文,SYN置为1,并发送了一个随机码seq
  • 服务器接收后返回报文,SYN,ACK都为1,让ack码有效,返回ack=x+1,并附加自己的随机吗seq=y
  • 客户端收到,并返回ack,建立连接完成。

四次挥手指的是释放连接过程:

  • 双发都可以主动发起连接
  • 客户端发送FIN,和一随机数告诉服务器,我要关闭了。
  • 服务器收到后返回ack,告诉客户端,你先等会,等我发送剩余数据你再关闭。
  • 这是客户端进入等待状态,服务器发送完后发送一个FIN和seq,告诉客户端我发送完了。
  • 客户端收到后返回,告诉服务器我收到了,再见。

问题

为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

SYN攻击

在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.

Syn攻击就是 攻击客户端 在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直 至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

Syn攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击

netstat -n -p TCP | grep SYN_RECV

一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.

但是不能完全防范syn攻击。

打开一个url发生了什么

总体来说分为以下几个过程:

  1. DNS解析
  2. TCP连接
  3. 发送HTTP请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 连接结束

DNS 解析

DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

  • 在你的chrome浏览器中输入:chrome://dns/,你可以看到chrome浏览器的DNS缓存。
  • 系统缓存主要存在/etc/hosts(Linux系统)中:

如果本地没有相关缓存,会到服务器上查找,通过.->.com->google.com->www.google.com 这样从顶级域名递归查找。

DNS负载均衡

DNS每次返回都一个ip,说明访问的是一个服务器,那上万的请求服务器怎么办,其实大型网站都有上百台服务器。

这样,DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。

CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。比如我用的七牛作为图床。

HTTPS协议

HTTP报文是包裹在TCP报文中发送的,服务器端收到TCP报文时会解包提取出HTTP报文。

但是这个过程中存在一定的风险,HTTP报文是明文,如果中间被截取的话会存在一些信息泄露的风险。那么在进入TCP报文之前对HTTP做一次加密就可以解决这个问题了。

HTTPS协议的本质就是HTTP + SSL(or TLS)。在HTTP报文进入TCP报文之前,先使用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间。

关于SSL和TLS,请看:http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html