网络基础TCP/IP 协议
- TCP/IP协议簇自上而下分为4层:应用层,传输层,网络层,数据链路层
-
应用层:决定向用户提供应用服务时的通信活动,HTTP(Hypertext Transfer Protocol),FTP(File Transfer Protocol),DNS(Domain Name System)均在这层;
-
传输层:提供处于网络连接中的两台计算机之间的数据传输,TCP(Transmission Control Protocol),UDP(User Data Protocol)
-
网络层:规定以怎样的路径到达目标计算机,并把数据包传输给对方,IP(Internet Protocol)
-
链路层:链接网络的硬件部分,操作系统,硬件驱动,网卡,光纤
-
协议的数据流:发送端自应用层到链路层,接收端自链路层到应用层。客户端在应用层发出HTTP,传输层TCP协议对HTTP协议进行分割打上标记和端口号,网络层IP协议增加通信目的地的MAC(Media Access Control Address)地址,发给链路层完成通信请求;接收端服务器在链路层接受数据,往上层发送。
-
IP协议:把数据包传送给对方,两个重要条件:IP地址(节点被分配的地址)和MAC地址(网卡所属的固定地址)。通过ARP(Address Resolution Protocol)请求完成解析MAC地址(ARP单播于ARP广播)。
-
路由选择(routing):没有人能够全面掌握互联网中的传输状况,需要在多次中转才能到达目的地,这种中转为路由。
-
TCP协议:作用于传输层,使用字节流服务(Byte Stream Service)将大数据切割成segment为单位的数据包;使用三次握手策略(Three-way Handshaking)SYN - SYN/ACK - ACK传送数据包,四次挥手 FIN - ACK - FIN - ACK 来中断链接。
-
DNS服务:DNS协议提供通过域名查找IP地址,或者逆向IP地址查找域名的服务。
-
URI与URL:URI(Uniform Resource Identifier)与URL(Uniform Resource Locater),URL是URI的子集,也可以说URL是URI的实现。好比名字,身份证号,学号都是一个人的URI,每条单独拿出来就是一个URL(URI与URL的区别)。
简单的HTTP协议
-
一个HTTP通信中必定存在一对客户端与服务端,HTTP协议规定请求从客户端发出,由服务端相应并返回。
-
请求报文由请求方法,请求URI,协议版本,可选请求首部字段,和内容实体构成。
-
响应报文由协议版本,状态码,原因短语,可选的首部响应字段以及响应实体构成。
-
HTTP是一种无状态(stateless)协议。协议对于发送过的请求或响应不做持久化处理。因此发展了Cookie技术用来保存用户态。
-
HTTP请求中指定URI的方式有很多,可以放在请求URI中,也可以将URI中的域名或者IP放在可选首部字段中,也可以用一个*代替URI表示对服务器本体发起请求。
-
HTTP请求方法
-
GET:获取URI指定的资源。如果资源为文本直接返回,如果是CGI(Common Gateway Interface)那样的程序则返回执行后结果。
-
POST:传输实体的主体。POST的目的不在于获取响应的主体内容。比如发送数据给CGI处理获取返回结果。
-
PUT方法:传输文件到指定URI位置。不带验证机制,任何人均可上传存在安全问题,一般web禁止。若干附带严重或者采用REST(RE presentational State Transfer 表征状态转移)标准的网站可能会开放PUT。
-
HEAD方法:与GET相似,但不获取报文主体,仅用来确认URI有效性以及资源更新日期。
-
DELETE方法:删除URI指定的文件,与PUT相反
-
OPTIONS方法:询问支持的方法,例如:OPTIONS * HTTP/1.1 HOST:hackr.jp 来获取HOST指定服务器支持的方法。
-
TRACE方法:追踪路径(请求在中转被篡改的记录)。让服务器将之前的通信环返回给客户端。不常用,且容易引发XST(Cross-Site Tracing)攻击。
-
CONNECT:要求用隧道协议连接代理。与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信,建立成功后通过隧道访问目标服务器。主要用SSL(Secure Sockets Layer)和TLS(Transport Layer Security)协议将内容加密后通过隧道传输。
- 通过持久连接节省通信量。
-
背景:之前传输文本小:TCP三次握手 - HTTP请求与响应 - TCP四次挥手,现在网站内容量大(例如多图片网站)每次请求都会造成TCP连接建立与断开增加通信量消耗
-
持久化连接(HTTP Persistent Connections,HTTP keep-alive或HTTP connection reuse),只要任何一端没有明确提出断开连接则保持TCP连接。减少TCP连接和断开的负载,使得HTTP请求能够更快完成
-
管线化(pipelining):持久化连接保证了发送请求后无需等待响应也可以直接发送下一个请求,发送请求由串行变成并行
- Cookie状态管理
-
HTTP的无状态性减少了服务器CPU及内存资源的消耗
-
Cookie技术:通过在请求和响应报文中写Cookie信息来控制客户端状态(比如,登陆态)
-
客户端发送请求 -> 服务器响应,首部字段包含set-Cookie -> 客户端发送请求,首部字段包含cookie -> 服务端解析cookie认识客户端并从之前服务记录中获得客户端状态信息。
HTTP报文内的HTTP信息
-
HTTP报文分为请求报文与响应报文,内容为:报文首部以及报文主体组成,两者由CR+LF(Carriage Return 回车符0x0d 和Line Feed 换行符0x0a)隔开。
-
请求报文
-
请求行:请求的方法,URI,和HTTP版本,比如:GET / HTTP/1.1
-
首部字段:通用首部,请求首部,实体首部,Cookie
- 响应报文
-
响应行:响应的状态码,原因短语和HTTP版本,比如:HTTP/1.1 200 OK
-
首部字段:通用首部,响应首部,实体首部,Cookie
- 编码提升传输速率
-
报文(Message)和实体(entity)。报文是HTTP通信的基本单位,由8位字节流(octet sequence)组成,通过HTTP传输;实体是响应或者请求的有效载荷,由实体首部和实体主体组成。
-
HTTP报文的主体用来传输请求或响应的实体主体,通常报文主体=实体主体,但为提升传输效率,编码操作后两者不同。好比我们发邮件增加了超大附件,传输时用ZIP压缩一样,压缩文件与原附近不同。
-
内容编码:应用在实体上的编码格式,保持实体信息,客户端接受并解码。常用编码:GUN gzip,UNIX compress,zlib deflate,identity(不编码)。对应首部字段:Content-Encoding。
-
分块传输编码(Chunked Transfer Coding):把实体数据分割成多块,能让浏览器逐步显示页面,不至于数据传输没完成就无法显示页面。每块用一个十六进制数标记块大小,最后一块用“0(CR+LF)”标记。对应首部字段:Transfer-Encoding。
-
发送多数据对象集合:HTTP发送的一份报文主体内可包含多类型实体(图片,视频等等)。包括:multipart/from-data(表单上传),multipart/byteranges(多范围内容)使用“--boundary字符串”来进行分割,响应报文中包含多个范围的内容时使用状态码206 Partial Content。在报文中使用多部分对象集合时需要在首部加上字段Content-type。
-
范围请求(Range Request):使用首部字段Range指定资源的byte范围,如,Range:bytes=5001-10000; Range:bytes=-3000, 5000-;对于多范围请求。响应码为206 Partial Content,响应报文首部字段包含Content-type: multipart/byteranges。如果无法响应则会返回200 OK和完整的内容。应用在:下载的断点续传等。
-
内容协商:客户端与服务端就响应的资源进行交涉,然后给客户端提供最合适的资源。比如中文版本的浏览器访问google会返回中文版本的google主页
-
交涉点包括:语言,字符集,编码方式等等。请求的首部字段中包含:Accept,Accept-Charset,Accept-Encoding,Accept-Language,Content-Language;
-
内容协商技术:服务器驱动协商(Server-driven Negotiation)(服务器参考请求字段来判断响应内容),客户端驱动协商(Agent-driven Negotiation)用户手动切换,透明协商(Transparent Negotiation)两者结合。
HTTP响应状态码
-
状态码:3位数字+原因短语,如200 OK。主要有5种:1XX = informational 接受信息正在处理;2XX = Success 请求正常处理完毕;3XX = Redirection 需要附加操作以完成请求;4XX = Client Error 无法处理请求;5XX = Server Error 服务器处理请求出错。
-
2XX系列:处理成功系列
-
200 OK:正常处理(GET,HEAD请求的响应报文不同,后者无实体)
-
204 No Cotent:处理成功,但无相关内容,返回报文中不含实体,浏览器得到204后不会刷新页面。一般用于客户端往服务端发信息,但服务端无需返回时使用。
-
206 Partial Content:对应Range Request,包含由Content-Range指定的实体
- 3XX系列:浏览器需要执行某些特殊处理以正确处理请求。
-
301 Moved Permanently:永久性重定向,表示访问的URI资源已经被分配了新的URI,如果之前将该资源保存为书签,这时就应该安装Location首部字段提示的URI更新书签。
-
302 Found:请求的资源被临时分配了新的URI,希望用户本次使用新的URI,也就是说将来URI还会改变,如果保存了书签,这时浏览器不会去像301那样去更新书签。
-
303 See Other:请求对应的资源存在另外一个URI,应该使用GET方法定向获取该资源,不像302,303明确要求用户用GET。比如用POST访问Server CGI,Server把处理结果放在某个URI下,返回303通知用户用GET去取,这就是303绝佳应用场景。
-
实际上,301,302,303出现时,几乎所有的浏览器都会把POST改成GET并删除报文主体,然后再次发送;但301,302标准是禁止POST转GET的
-
304 Not Modified 客户端发送附带条件请求时,若未满足条件返回304,且不包含响应主体,与重定向无关。(附带条件请求:首部包含If—Match,If-None-Match,If-Modified—Since,If-Range,If-Unmodified-Since等字段之一的请求)
-
307 Temporary Redirect:与302相同,但307根据标准不会把POST改成GET,但视情况而定。
- 4XX系列:客户端错误
-
400 Bad Request:请求报文出现语法错误,浏览器会像200 OK那样对待400.
-
401 Unauthorized:第一次返回,响应报文中会包含WWW-Authenticate首部询问用户信息,通知用户进行HTTP认证(BASIC,DIGEST认证)同时浏览器会弹出认证对话窗,第二次返回表示认证失败。
-
403 Forbidden:服务器拒绝防问请求资源,可能由于权限原因。可以在响应主体中添加拒绝理由
-
404 Not Found:表示服务器上无法找到请求的资源
-
405 Method Not Allowed:客户端请求中使用了服务器禁用的方法。
- 5XX系列:服务器错误
-
500 Internal Server Error:服务器执行出错,可能是web应用bug导致
-
503 Service Unavailable: 表示服务器暂时处于超负荷或者停机维护,当前无法处理请求,可以通过RetryAfter字段通知客户端重试时间。
与HTTP协作的web服务器
-
Web服务器可以使用虚拟主机(Virtual Host)搭建多个独立域名的Web网站,也可以作为通信路径中的中转服务器提升传输效率。
-
同一台主机上托管了多个域名时,这些域名被DNS解析后均会指向该主机的IP地址,这样会混淆,因此发送HTTP请求时需要在Host首部内完整指明主机域名。
-
HTTP通信中,除了服务器和客户端以外还有其他程序配合服务器工作:
-
代理:中间人角色,接受客户端请求并转发给服务器,接受服务器响应并转发给客户端;
-
网关:转发其他服务器的通信数据,接受客户请求时像源服务器一样对请求进行处理,客户端都无法察觉;
-
隧道:相隔较远的客户端与服务器两者之间进行中转,并保持通信连接的应用程序。
- 代理:代理不会改变访问的URI,每次通过代理转发请求或响应时都会追加Via首部,例如:Via:proxy1,proxy2。使用理由:利用缓存技术减少网络带宽的流量,访问控制,获取访问日志。
-
缓存代理(Caching Proxy):缓存资源副本,接到同样请求时直接返回,反之为非缓存代理;
-
透明代理(Transparent Proxy):不会报文进行任何修改加工的代理,反之为非透明代理。
-
网关:与代理类似,网关可以把HTTP协议转换为非HTTP协议,利用网关能提升通信安全,可以在客户端与网关之间的通信加密。比如:网关连接数据库使用SQL查询(非HTTP系统),网关与信用卡结算系统(非HTTP系统)联动。
-
隧道:确保客户端能与服务器进行安全的通信,隧道不回去解析HTTP请求。
-
缓存: 代理服务器或客户端本地磁盘保存的资源副本。利用缓存可以减少对源服务器的访问。
-
缓存服务器:代理服务器转发请求时会保存一份资源副本,下次遇到同样请求直接返回。
-
缓存时效性:根据缓存有效期,客户端要求,去更新资源
-
客户端缓存:缓存在浏览器中,请求时之前从本地返回,如果缓存过期则会发送请求去服务器更新资源。
HTTP首部
- HTTP/1.1的4种首部字段类型:
-
通用首部字段(General Header Fields):请求和响应报文都会使用的字段
-
请求首部字段(Request Header Fields)
-
响应首部字段(Response Header Fields)
-
实体首部字段(Entity Header Fields):请求与响应报文的实体部分使用的首部,补充与实体相关的信息,比如更新时间。
-
非HTTP/1.1的首部字段:RFC2616规定的47种字段外的字段:Cookie,Set-Cookie,Content-Disposition等等
-
按是否缓存代理的行为划分为:端到端首部(End to end Header)、逐跳首部(Hop by hop Header)。
-
端到端首部(End-to-End Header):转发请求/响应对应的最终目标,且必须保存在由缓存生成的响应中;
-
逐跳首部(Hop-by-Hop Header):只对单次转发有效,会因通过缓存或代理而不再转发,使用逐跳首部需要提供Connection首部。总共只有8个
- 通用字段:
- Cache-Control:控制缓存行为,请求与响应有不同的指令集。是否能缓存:public,private,no-cache
为public时:其他用户也可以利用缓存
为private:指定用户专用,缓存服务器只对特定用户返回缓存,对于其他用户不返回缓存(缓存用户个人资料)
为no-cache:要求中间服务器不返回缓存资源,防止从缓存中返回过期资源,缓存会向源服务器进行有效期确认后处理资源 do not serve from cache without revalidation。请求使用的话表示不接受代理缓存,响应使用的话表示不允许代理缓存。响应中还可以指定no-cache=Location,接收到该参数指定的对应的响应报文后,就不能使用缓存。
为no-store:控制可执行缓存对象的指令。暗示请求或响应中包含机密信息,不允许中间服务器进行缓存。注意区分no-cache,no-cache表示不缓存过期资源、不接受缓存资源,no-store是不允许缓存。
-
max-age:请求中包含max-age时,如果代理的资源缓存时间比max-age小,则直接返回缓存,否则转发给源服务器获取资源。如果设置为0表示需要把请求转发给源服务器;响应中包含max-age时表示缓存服务器不再对缓存有效性进行确认,max-age指定的为最长时间。max-age会覆盖Expires。
-
s-maxage:与max-age相同,不同点是该指令只适合供多用户使用的公共缓存(代理)服务器。使用s-maxage的话会忽略Expires和max-age。
-
min-fresh:请求中表示要求缓存服务器返回至少还未过指定时间的缓存资源。比如,指定为60s,那么超过60sde缓存都无法作为响应。
-
max-stale:请求中表示即使过期,只要在指定范围内则接受。例如Cache-Control: max-stale = 3600,缓存3600s以内的资源无论是否过期都可以作为响应返回。
-
only-if-cached:请求中表示缓存服务器有该缓存时就返回,无论该资源是否有效过期,不去源服务器确认有效性。若没有返回504 Gateway Timeout。
-
must-revalidate:请求中要求代理向源服务器确认缓存是否有效,若代理无法连上源服务器则返回504。must-revalidate会覆盖max-stale。
-
proxy-revalidate:请求中要求缓存服务器返回响应之前必须验证有效性。
-
no-transform:无论是请求还是响应缓存都不能改变实体主体的媒体类型,防止缓存或代理压缩图片等
-
Cache-Control拓展,cache-extension token,仅对理解它的缓存服务器有效,不理解则被忽略。
-
Connection:请求或响应中控制不再发给代理的首部字段,比如Connection: Upgrade,那么Upgrade字段将不会被转发;管理持久连接,HTTP/1.1默认持久连接,如果服务器表示希望中断可以响应Connection:close,HTTP/1.1之前的版本都是默认非持久连接这样,为达到持久连接,请求中加上Connection:keep-alive,响应中添加Connection:keep-alive Keep-alive:timeout=10, max=500
-
Date:HTTP报文生成的日期与时间。
-
Pragma:HTTP/1.1之前的历史遗留,仅为了向后兼容性。唯一形式Pragma:no-cache,与Cache-Control:no-cache并用防止不兼容。
-
Trailer:说明在报文主体中记录了一些首部字段,该字段可以用于分块传输编码。
-
Transfer-Encoding:规定传输报文主体时采用的编码方式。对于HTTP/1.1而已仅有分块传输有效。Transfer-Encoding:chunked
-
Upgrade:检查是否可用更好版本协议通信。例如,Upgrade:TLS 1.0 Connection: Upgrade。服务器可以返回101 Switching Protocols作为响应。
-
Via:追踪客户端与服务器之间的请求与响应报文的传输路径,还可以避免请求回环的发生。Via经常和TRACE一起使用,其中Max-Forwards=0时,代理不在转发,返回自己到Via中返回响应。
-
Warning:警告码+警告主机:端口+内容+日期时间。目前有7种。
- 请求首部字段
-
Accept:通知服务器客户能够处理的媒体类型和优先级,使用type/subtype指定类型。例如:text/html,image/jpeg,video/mpeg等。可以用q指定权重,默认为1.0(最大),可以精确到小数点后3位,例如:Accept: text/plain; q=0.3, application/zip; q=0.5。
-
Accept-Charset:客户端接受的字符集,q表示权重,例如,Accept-Charset:unicode-1-1;q=0.8。
-
Accept-Encoding:客户端支持的内容编码,q表示权重,例如,Accept-Encoding:gzip, deflate。
-
Accept-Language:客户端支持的自然语言集,q表示权重。Accept-Language: zh-cn; q=0.9。
-
Authorization:告知服务器用户的认证信息(证书值)。通常收到401后响应中会包含WWW-Authenticate要求认证,这是用户返回Authorization字段包含认证信息再次请求。
-
Expect:表期待某特定行为。若服务器无法回应期待则返回417 Expectation Failed。目前只有100-continue表示希望服务器对正在等待的客户端响应100 Continue。
-
From:告知服务器使用用户代理的电子邮箱地址。为了显示搜索引擎等用户代理负责人的联系方式。服务器可以通过这个邮箱联系客户端。
-
Host:定位虚拟主机。因为一个IP下可能有多个域名指定的虚拟主机。若服务器为指定主机名那么允许为空。该字段为请求中唯一的必须字段。
-
If-Match: + ETag,告诉服务器匹配所用的实体标记值ETag,这时服务器无法使用弱ETag值,当两值一致时处理请求,否则返回412 Precondition Failed。用“*”表示匹配所有ETag,只要有资源就会处理。
-
If-Modified-Since:如果在指定日期之后发生更新,则处理;否则返回304 Not Modified。用于客户端或代理服务器向源服务器询问本地资源的有效性来更新资源。可以通过Last-Modified来确认资源更新时间。
-
If-None-Match:与If-Match相反,可以用在GET和HEAD方法中来更新资源,类似于If-Modified-Since。
-
If-Range:If-Range于Range搭配使用,如果资源ETag相匹配,则返回206 Partial Content,否则返回200 OK附带全部内容。如果不用If-Range使用If-Match将需要消耗2次请求(不匹配返回412,再次发送新请求)。
-
If-Unmodified-Since:与If-Modified-Since相反,如果发生更新返回412。
-
Max-Forwards:使用TRACE或OPTIONS方法,发送Max-Forwards请求时,每经过一个代理则Max-Forwards减一并转发,等于0时直接返回响应。这样可以用来调差请求失败的原因,把握传输路径的通信状况。
-
Proxy-Authorization:客户端与代理服务器之间的认证质询。
-
Range:发起范围请求。成功则返回206,失败返回200。
-
Referer:告知服务器资源请求者的URI。
-
TE:客户端能够响应的编码方式和优先级。与Accept-Encoding很像。可以指定trailer的分块编码方式,只需赋值给TE:trailers。
-
User-Agent:创建请求的浏览器和用户代理等信息传给服务器。爬虫会加入作者电子邮箱,经过代理也可能会被加上代理服务器名称。
- 响应首部字段
-
Accept-Ranges:告诉客户端是否接受范围请求,接受为bytes,不接受为none。
-
Age:表示源服务器多久之前创建了响应。Age值表示的是缓存后的响应再次发起认证到认证完成的时间值。
-
ETag:告知客户端实体标识。服务器为每份资源分配对应的ETag,当资源更新时ETag也更新,ETag生成无统一算法规则。如下载中断在连接时会使用ETag来指定资源。
-
强ETag和弱ETag:强ETag,无论发生多么细微的变化都会改变,例如,ETag:usagi-123,弱Etag会在资源发生根本改变时才会改变,例如,ETag:W/"usagi-123"。
-
Location:引导客户端,配合3XX重定向提示客户端资源的所在URI,客户端收到后重新发起请求。
-
Proxy-Authenticate:代理服务器发送需要的认证信息给客户端,类似于WWW-Authenticate,不同在于一个是代理,一个是源服务器。
-
Retry-After:与503 Service Unavailable或3XX 一起使用,告知客户端多久以后来访问,可以指定具体时间或响应传建后的秒数。
-
Server:告诉服务端当前服务器应用程序信息,版本号之类的
-
Vary:从代理服务器接受到源服务器返回包含 Vary 指定项的响应之后,若再要进行缓存,仅对请求中含有相同 Vary 指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于 Vary 指定的首部字段不相同,因此必须要从源服务器重新获取资源。假如源服务器返回给代理Vary:Accept-Language,那么如果请求的Accept-Language相同,直接缓存返回,否则向服务器重新发起请求。
-
WWW-Authenticate:用于HTTP认证,告知客户端认证方案(Basic还是Digest)和带参数的提示质询(challenge),伴随401返回。
- 实体首部字段
-
请求报文和响应报文的实体部分所用的首部,主要用来补充更新时间等相关信息。
-
Allow:通知客户端Request-URI所指定资源的所有HTTP方法。当服务器收到不支持方法的请求时返回405 Method Not Allowed,伴随着Allow字段给出支持的方法表。
-
Content-Encoding:告诉客户端服务器对实体部分的内容编码方式。
-
Content-Language:实体使用的自然语言。
-
Content-Length:实体主体部分的大小(字节),如果对实体主体进行编码传输,则不能使用该首部。
-
Content-Location:表示的是报文主体返回资源时对应的URI类似于请求首部里面的Referer。
-
Content-MD5:报文主体 -> MD5 -> BASE64 -> Content-MD5,来检查报文主体在传输过程中是否完整,接收方接收到后也会进行一次MD5计算比对。但不能保证是否被篡改。因为篡改后可能MD5也被重新计算
-
Content-Range:响应范围请求,告诉客户端实体属于那个方位,例如,Content-Range:bytes 5001-10000/10000。
-
Content-type:实体主体内对象的类型,charset表示字符集。例如,Content-type:text/html; charset=UTF-8。
-
Expires:缓存过期时间。时间以内代理直接返回缓存,否则向源服务器请求资源。可以设置为Date字段相同值禁止代理对资源缓存。max-age会覆盖Expires。
-
Last-Modified:最终修改时间。
- Cookie的首部字段
-
Cookie的工作机制是用户识别及状态管理。调用Cookie时由于可校验Cookie的有效期,发送方的域,路径,协议等信息,所以Cookie内的数据不会因为来自其他Web站点和攻击者的攻击而泄露。
-
Set-Cookie(响应):
-
NAME:Cookie的名称。
-
expires:指定Cookie的有效期;默认为浏览器关闭。Cookie一旦由服务器发送到客户端,则无法显式删除,仅能覆盖。
-
path:限制指定Cookie的发送范围的文件目录。可以避开,安全效果一般;
-
domain:域名与domain指定值结尾匹配。除非针对多个domain发送Cookie,否则不指定更安全。
-
secure:限制仅在HTTPS安全连接时才可以发送Cookie。省略时HTTP和HTTPS均可用。
-
HttpOnly:防止XSS攻击,使得JavaScript无法获得Cookie。JS的document.cookie无法读取HttpOnly属性的Cookie。
- Cookie(请求):客户端希望获取HTTP状态管理支持。
- 其他首部字段
-
HTTP首部字段是可以自行扩展的
-
X-Frame-Options:控制网站内容在其他web网站的Frame标签内的显示问题,防止点击劫持攻击。可以在apache中配置。
-
DENY:拒绝
-
SAMEORIGIN:仅在同源域名下的页面
-
X-XSS-Protection:响应首部,针对XSS攻击的对策,0为无效,1为有效。
-
DNT:请求首部,Do not Track,拒绝个人信息被收集,拒绝靶向广告的一种方法。0表示同意,1表示拒绝。
-
P3P:响应首部,保护个人隐私。
确保web安全的HTTPS
- HTTP的缺点([使用wireshark抓包](PYTHON黑帽编程1.5 使用WIRESHARK练习网络协议分析)):
-
通信使用明文,内容会被监听
-
不验证对方身份,会被伪装
-
无法验证报文完整性,会被篡改
-
HTTPS(HTTP secure 或 HTTP over SSL):通过和SSL(Secure Socket Layer)或者TLS(Transport Layer Security)的组合使用,加密HTTP通信内容。用SSL建立安全通信线路后,在该线路上发送请求。(关于SSL和TLS)
-
内容加密:仅加密报文主体不加密报文首部,要求客户端和服务器具有加密和解密的机制。不同于SSL或TLS将整个通信线路加密,这种加密方式仍有可能被篡改内容。
-
HTTP协议无论是谁发送的请求,都会返回响应(可以设置访问IP和端口限制),HTTP不验证通信方身份有以下几个问题:
-
无法确认服务器是否被伪装;
-
无法确认客户端是否被伪装;
-
无法确认通信方是否有访问权限;
-
无法判断请求源;
-
无意义的请求也会响应,易被DoS攻击。
-
HTTPS通过SSL提供加密和证书,用于确认身份,防止被伪装。
- HTTP协议的报文可能被篡改(MITM攻击 Man-in-the-Middle attack):
-
HTTP采用MD5,SHA-1,PGP(Pretty Good Privacy)创建数字签名和散列值来确保文件的正确性,但仍有可能被篡改。
-
需要HTTPS提供的加密和摘要服务
-
HTTPS = HTTP + 加密 + 认证 + 完整性保护:HTTPS就是身披SSL/TLS外壳的HTTP,在应用层HTTP与传输层TCP中间加了一层SSL。
-
HTTPS采用混合加密方式:传递对话密钥(对称加密)时使用非对称加密方式,加解密对话信息时使用的是对称加密生成的对话密钥。因为公钥加密与对称加密相比,处理效率更低,所以仅用于传递对话密钥。
-
HTTPS大致流程:
-
客户端从服务器处获取服务器公钥(注意,公钥传递可能被篡改);
-
客户端生成一个随机对话密钥(对称加密),并使用服务器公钥加密后发给服务器;
-
服务器使用私钥解密获取对话密钥;
-
客户端和服务器使用相同的对话密钥进行加密通信。
- CA(Certificate Authority)介入:为防止第一步中公钥传递被篡改需要第三方权威机构CA介入。介入流程为:
-
服务器运营人员向CA提交公钥并申请数字证书;
-
CA验证申请者身份后对使用自己的私钥对申请者的公钥做数字签名,并公布自己的公钥。
-
服务器将证书发给客户端(DNS域名解析时完成),客户端使用CA的公开密钥验证证书签名,如果成功则:确认证书有效,服务器的公开密钥是可信的。
-
关键在于如何传递CA的公钥给客户端,一般情况下CA的公钥会直接植入在浏览器内部。
-
EV SSL证书(Extended Validation SSL Certificate):基于国际标准的认证颁发的证书。防止用户被钓鱼攻击。
-
其他证书:客户端证书,中级认证证书,自认证证书(OpenSSL服务)。
-
HTTP通信全过程:协商决定加密组件,发送公钥证书,交换对话密钥,开始HTTP通信。
-
客户端发送ClientHello报文:客户端支持的SSL版本,加密组件(Cipher Suite)(加密算法和密钥长度);
-
服务端此时回复3份报文:
-
ServerHello:SSL版本以及加密组件(由客户端要求筛选);
-
Certificate报文:公钥证书;
-
ServerHelloDone报文:通知客户端SSL第一次握手结束
- 客户端发送3份报文:
-
ClientKeyExchange报文:Pre-master-secret的随机密码串(使用服务器公钥加密);
-
ChangeCipherSpec报文:提示服务器今后用Pre-master-secret加密;
-
Finished报文:至今全部报文的整体校验值
- 服务器收到后回复2份报文:
-
ChangeCipherSpec报文;
-
Finished报文:宣告第二次握手成功,至此SSL连接建立完成。
-
回到应用层,客户端与服务器开始用Pre-master-secret加密的HTTP协议通信,发送数据时会附加MAC(Message Authentication Code)的报文摘要,用以查知报文是否遭到篡改以保证完整性。
-
客户端断开连接,TCP四次挥手
- HTTPS由于使用了SSL导致处理效率慢,比HTTP慢2到100倍:
-
通信慢:TCP与HTTP以外多加了一层SSL协议;
-
消耗资源:加密解密运算消耗硬件资源。
- HTTPS与HTTP的选取:
-
机密场合使用HTTPS,HTTPS慢,需要CA认证费
-
一般情况使用HTTP。
确认访问用户身份的认证
-
HTTP认证方式:BASIC,DIGEST,SSL客户端认证,FromBase认证(基于表单认证),Windows系统还有Keberos认证和NTLM认证。
-
BASIC认证:无法注销,明文传输不安全,具体步骤如下:
-
如果需要BASIC认证,服务器返回401和WWW-Authenticate以及Request-URI的安全域字符串realm;例如:WWW-Authenticate:Basic realm="Input Your ID and Password"。
-
客户端发送ID:密码 -> Base64编码处理发送给服务器,例如,Authorization:Basic Z3Vlc3Q6Z3Vlc3Q=
-
服务器验证ID和密码,成功返回200和资源,失败返回401。
- DIGEST认证:采用质询/响应(challenge/response)方式,比BASIC安全,可以防窃听但不可以防止伪装。具体步骤:
-
服务器返回401和WWW-Authenticate包含质问响应方式realm和临时质询码(nonce,随机字符串->Base64)
-
客户端返回Authorization包含,username,realm,nonce,uri和response,其中realm和nonce与服务器返回值相同,uri的值就是Request-URI,是为了防止Request-URI被代理修改,response也就Request-Digest存放经过MD5运算后的密码字符
-
服务器校验,通过后返回Resquest-URI对应的资源。并在Authentication-Info写入认证成功的相关信息。
- SSL客户端认证:借由客户端证书完成认证,需要购买SSL客户端证书,具体步骤:
-
服务器返回包含Certificate-Request字段的报文,要求客户端提交证书;
-
客户端返回Client-Certificate提交证书;
-
服务器验证客户端证书后,领取客户端证书内密钥开始HTTPS加密通信。
-
表单认证:客户端向服务器的web应用程序上发送登陆信息(Credential),即一般的网页登陆。表单认证并不定义在HTTP协议中。
-
SSL客户端认证采用双因素认证:SSL双因素认证一般会和表单认证组合形成双因素认证(Two-factor authentication)。SSL客户端认证客户端计算机,表单密码认证认证用户本人,确定正确的人用正确的计算机。
-
认证大多是表单认证,BASIC认证和DIGEST认证几乎不怎么使用,SSL客户端认证需要维持费用,难以普及。
-
Session管理和Cookie应用
-
基于表单认证一般会用Cookie来管理回话Session;
-
具体步骤:
-
表单登陆时,客户端把用户ID和密码放入报文实体部分,以POST方式发送登陆请求;
-
服务器web应用核实用户登陆信息,发放用以识别用户的Session ID,并把用户状态与Session ID绑定后记录在服务器端,响应中在Set-Cookie内写入Session ID。(如果Session ID被盗走,对方便可以伪装你的身份,需要用难以推测的字符串,服务器也需要进行有效期管理,此外为了防止XSS攻击,最好事先加上httponly);
-
客户端收到Session ID后会把它作为Cookie保存在本地,以后的请求都会带上Cookie。
-
服务器通过Session ID识别用户和他的状态。
- 服务器保存用户密码的一种方法:密码+盐 -> hash计算出散列值保存。
基于HTTP的功能追加协议
- HTTP的瓶颈:
-
一个连接上只可以发送一个请求;
-
请求只能从客户端开始,客户端不能接受除响应以外的指定;
-
请求和响应首部没有压缩就发送,首部信息越多延迟越大;
-
发送过多冗长首部;
-
可任意选择数据压缩格式,而非强制压缩。
- Ajax的解决方案:
-
Ajax(Asynchronous JavaScript and XML,异步JavaScript与XML技术)利用JavaScript和DOM的操作,以达到Web页面替换加载的异步通信手段。与同步加载相比,它只替换一部分页面,响应传输的数据量也会因此减少。
-
核心在与XMLHttpRequest的API,使用JavaScript调用遍可以进行HTTP通信,借此以加载好的web页面为基础发起请求只更新局部页面。减少每次更新全部页面带来的流量消耗。但也会因此可能尝试大量请求。
- Comet的解决方案:
-
请求来了以后,Comet不会立即响应,为了实现推送,它会先把响应挂起,一旦服务器内容更新了,立马给客户端响应,模拟服务器推送功能(Server Push)。实现大流量网站的数据同步功能(FaceBook,YouTube等)
-
为了保留响应,一次连接的时间增长,维持连接也会消耗服务器资源。
- SPDY的目标:
-
Ajax和Comet都没有从实质上解决HTTP协议的瓶颈,SPDY旨在从协议级别上改进HTTP;
-
SPDY规定启用SSL表示层来增强安全级别,SPDY以会话层的形式夹在HTTP应用层与SSL表示层之间。
-
使用SPDY后HTTP协议额外获得以下功能:
-
多路复用流:单一TCP连接处理多个HTTP请求。TCP的处理效率提高;
-
赋予请求优先级:分配优先级解决在发送多个请求时因带宽低导致响应变慢的问题;
-
压缩HTTP首部:通信的数据包数量和发送的字节数减少;
-
推送功能:服务器可以直接发送数据不需要等待客户端的请求;
-
服务器提示功能:服务器主动提示客户端请求所需的资源,客户端可以获知资源的所在,因而可以避免发送不必要的请求,比如客户端得知资源在缓存中。
- SPDY的问题:仅仅是把带个域名(IP)的通信多路复用,当一个web网站使用多个域名下的资源时,改善效果就不明显
- 使用浏览器进行全双工通信的WebSocket
-
WebSocket:主要为了解决Ajax和Comet里XMLHttpRequest附带的缺陷所引起的问题。
-
WebSocket协议:服务端与客户端之间一旦建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专业协议进行,可以发送Json,XML,HTML等各种格式的文件。
-
WebSocket协议建立在HTTP基础上,由客户端发起,一旦建立,双方都可以直接发送报文;
-
WebSocket的主要特点:
-
推送功能:服务器直接给客户端发送报文;
-
减少通信量:一旦建立就一直保持,连接开销减少,WebSocket的首部信息减少,通信量也减少了;
- WebSocket协议的创建:在HTTP连接建立之后需要完成一次握手:
-
用 Upgrade: websocket 字段通知服务器协议改变以达到握手,Sec-WebSocket-Key记录握手必须的键值,Sec-WebSocket-Protocol记录使用的子协议;
-
服务器返回101 Switching Protocols,在响应报文中包含Sec-WebSocket-Accept字段,内容为基于Sec-WebSocket-Key字段值生成的字符串;
-
之后通信不采用HTTP,直接采用WebSocket独立的数据帧。
- WebSocket API:可以用JavaScript调用。
- HTTP/2.0
-
HTTP/2.0的目标是改善用户使用Web的速度体验。
-
实现:SPDY,HTTP Speed + Mobility,Network-Friendly HTTP Upgrade
- Web服务器管理文件的WebDAV
-
WebDAV(Web-Based Distributed Authoring and Versioning, 基于万维网的分布式创作和版本控制):一个可对Web服务器上的内容直接进行文件复制,编辑等操作的分布式文件系统,还具备创建者管理,加锁,版本控制。拓展于HTTP/1.1
-
新增概念:集合,资源,属性,锁;
-
新增了大量方法和状态码;
构建Web内容的技术
-
HTML,XML(雨同属于SGML(Standard Generalized Markup Language)),CSS,JavaScript,DOM
-
CGI是指Web服务器收到客户端发送来的请求后转发给程序的一组机制,CGI程序一般用PHP,Perl,Ruby和C等语言编写;
-
Servlet:一种能在服务器上创建动态内容的程序
- 相较于CGI:每次接到请求CGI程序(进程级别)都要跟着启动一次,因此一旦访问量过大,web服务器就要承担较大负载。Servlet运行在Web服务器相同进程中,因此负载较小。Servlet运行在Web容器或Servlet容器中。
-
XML的结构是用标签分割而成的树形结构,因此通过语法分析器(Parser)的解析功能解析XML结构并取出数据元素可以更容易地对数据进行读取。
-
JSON(JavaScript Object Notation)是以JavaScript的对象表示法为基础的轻量级数据标记语言。JSON的字符串可以直接被JavaScript轻易读取。
Web攻击技术
-
主动攻击:SQL注入,OS注入;被动攻击:XSS攻击和跨站点请求伪造;
-
输出值转义不完全引发的漏洞:客户端验证,输入输出值转义,不应该使用JS做关键的输入值验证,因为客户端可以关闭或篡改JS。
-
XSS攻击:存在安全漏洞的Web网站上注册用户的浏览器内运行非法的HTML标签或JS进行的一种攻击。
-
在URI字段中嵌入script脚本,通过e-mail发送给受害者;例如: http://example.jp/login?ID=">