1.HTTP响应码301和302代表的是什么,有什么区别,为什么尽量用301?

301代表永久性转移(Permanently Moved),302代表暂时性转移(Temporarily Moved )。 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 它们的不同在于,301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 尽量要使用301跳转是为了防止网址劫持,从网址A做一个302重定向到网址B时,主机服务器的隐含意思是网址A随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302转向时,百分之百的都抓取目标网址B的话,就不用担心网址URL劫持了。问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。 比如说,有的时候A网址很短,但是它做了一个302重定向到B网址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不用户友好。这时Google很有可能会仍然显示网址A。由于搜索引擎排名算法只是程序而不是人,在遇到302重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址URL劫持的可能性。也就是说,一个不道德的人在他自己的网址A做一个302重定向到你的网址B,出于某种原因,Google搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B上的内容,这种情况就叫做网址URL劫持。 简单理解是,从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了。

2.HTTPS

(1)为什么是安全的?

HTTP协议存在一个致命的缺点:不安全,中间人攻击篡改报文。 HTTPS其实是SSL+HTTP的简称,当然现在SSL基本已经被TLS取代了,不过接下来我们还是统一以SSL作为简称,SSL协议其实不止是应用在HTTP协议上,还在应用在各种应用层协议上,例如:FTP、WebSocket。 其实SSL协议大致就和上一节非对称加密的性质一样,握手的过程中主要也是为了交换秘钥,然后再通讯过程中使用对称加密进行通讯。 服务器是通过SSL证书来传递公钥,客户端会对SSL证书进行验证,其中证书认证体系就是确保SSL安全的关键。 在CA认证体系中,所有的证书都是由权威机构来颁发,而权威机构的CA证书都是已经在操作系统中内置的,我们把这些证书称之为CA根证书。 我们的应用服务器如果想要使用SSL的话,需要通过权威认证机构来签发CA证书,我们将服务器生成的公钥和站点相关信息发送给CA签发机构,再由CA签发机构通过服务器发送的相关信息用CA签发机构进行加签,由此得到我们应用服务器的证书,证书会对应的生成证书内容的签名,并将该签名使用CA签发机构的私钥进行加密得到证书指纹,并且与上级证书生成关系链。 当客户端(浏览器)做证书校验时,会一级一级的向上做检查,直到最后的根证书,如果没有问题说明服务器证书是可以被信任的。那么客户端(浏览器)又是如何对服务器证书做校验的呢,首先会通过层级关系找到上级证书,通过上级证书里的公钥来对服务器的证书指纹进行解密得到签名(sign1),再通过签名算法算出服务器证书的签名(sign2),通过对比sign1和sign2,如果相等就说明证书是没有被篡改也不是伪造的。

(2)HTTPS原理

HTTPS的整体过程分为证书验证和数据传输阶段。 证书验证阶段:

浏览器发起HTTPS请求。
服务端返回HTTPS证书。
客户端验证证书是否合法,如果不合法则提示告警。

数据传输阶段:

当证书验证合法后,在本地生成随机数。 通过公钥加密随机数,并把加密后的随机数传输到服务端。 服务端通过私钥对随机数进行解密。 服务端通过客户端传入的随机数构造对称加密算法,对返回结果内容进行加密后传输。

(3)为什么需要CA认证机构颁发证书?

HTTP 协议被认为不安全是因为传输过程容易被监听者勾线监听、伪造服务器,而HTTPS协议主要解决的便是网络传输的安全性问题。 首先我们假设不存在认证机构,任何人都可以制作证书,这带来的安全风险便是经典的“中间人攻击”问题。 “中间人攻击”的具体过程如下:

本地请求被劫持(如 DNS 劫持等),所有请求均发送到中间人的服务器。
中间人服务器返回中间人自己的证书。
客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间人,然后凭随机数构造对称加密对传输内容进行加密传输。
中间人因为拥有客户端的随机数,可以通过对称加密算法进行内容解密。
中间人以客户端的请求内容再向正规网站发起请求。
因为中间人与服务器的通信过程是合法的,正规网站通过建立的安全通道返回加密后的数据。
中间人凭借与正规网站建立的对称加密算法对内容进行解密。
中间人通过与客户端建立的对称加密算法对正规内容返回的数据进行加密传输。
客户端通过与中间人建立的对称加密算法对返回结果数据进行解密。

由于缺少对证书的验证,所以客户端虽然发起的是HTTPS请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。

(4)浏览器是如何确保CA证书的合法性?

证书包含信息如下:

颁发机构信息
公钥
公司信息
域名
有效期
指纹
......

首先,权威机构是要有认证的,不是随便一个机构都有资格颁发证书,不然也不叫做权威机构。 另外,证书的可信性基于信任制,权威机构需要对其颁发的证书进行信用背书,只要是权威机构生成的证书,我们就认为是合法的。 所以权威机构会对申请者的信息进行审核,不同等级的权威机构对审核的要求也不一样,于是证书也分为免费的、便宜的和贵的。 浏览器发起 HTTPS 请求时,服务器会返回网站的 SSL 证书。 浏览器需要对证书做以下验证: 验证域名、有效期等信息是否正确。证书上都有包含这些信息,比较容易完成验证。 判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证。 判断证书是否被篡改。需要与CA服务器进行校验。 判断证书是否已吊销。通过 CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现。 以上任意一步都满足的情况下浏览器才认为证书是合法的。

(5)用了HTTPS会被抓包吗?

HTTPS的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。 但是,正如前文所说,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。 因此,只要客户端是我们自己的终端,我们授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。 通常 HTTPS 抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互。 然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。 既然HTTPS不能防抓包,那HTTPS有什么意义?HTTPS可以防止用户在不知情的情况下通信链路被监听,对于主动授信的抓包操作是不提供防护的,因为这个场景用户是已经对风险知情。 要防止被抓包,需要采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解。

3.SSL证书生成

root.crt:根证书,server.key:服务证书私钥,server.crt:服务证书

根证书生成

# 生成一个RSA私钥
openssl genrsa -out root.key 2048
# 通过私钥生成一个根证书
openssl req -sha256 -new -x509 -days 365 -key root.key -out root.crt \
    -subj "/C=CN/ST=GD/L=SZ/O=lee/OU=work/CN=fakerRoot"

服务器证书生成

# 生成一个RSA私钥
openssl genrsa -out server.key 2048
# 生成一个带SAN扩展的证书签名请求文件
openssl req -new \
    -sha256 \
    -key server.key \
    -subj "/C=CN/ST=GD/L=SZ/O=lee/OU=work/CN=xxx.com" \
    -reqexts SAN \
    -config <(cat /etc/pki/tls/openssl.cnf \
        <(printf "[SAN]\nsubjectAltName=DNS:*.xxx.com,DNS:*.test.xxx.com")) \
    -out server.csr
# 使用之前生成的根证书做签发
openssl ca -in server.csr \
    -md sha256 \
    -keyfile root.key \
    -cert root.crt \
    -extensions SAN \
    -config <(cat /etc/pki/tls/openssl.cnf \
        <(printf "[SAN]\nsubjectAltName=DNS:xxx.com,DNS:*.test.xxx.com")) \
    -out server.crt

4.TCP/IP协议分层模型

(1)物理层将二进制的0和1和电压高低,光的闪灭和电波的强弱信号进行转换。 (2)链路层代表驱动。 (3)网络层。使用IP协议,IP协议基于IP转发分包数据。IP协议是个不可靠协议,不会重发。IP协议发送失败会使用ICMP协议通知失败。ARP解析IP中的MAC地址,MAC地址由网卡出厂提供。IP还隐含链路层的功能,不管双方底层的链路层是啥,都能通信。 (4)传输层。TCP协议面向有连接,能正确处理丢包,传输顺序错乱的问题,但是为了建立与断开连接,需要至少7次的发包收包,资源浪费。UDP面向无连接,不管对方有没有收到,如果要得到通知,需要通过应用层。 (5)会话层以上分层,TCP/IP分层中,会话层,表示层,应用层集中在一起。网络管理通过SNMP协议。

5.TCP三次握手和四次挥手

三次握手:

客户端–发送带有SYN标志的数据包–一次握手–服务端
服务端–发送带有SYN/ACK标志的数据包–二次握手–客户端
客户端–发送带有带有ACK标志的数据包–三次握手–服务端

四次挥手:

客户端-发送一个FIN,用来关闭客户端到服务器的数据传送
服务器-收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号
服务器-关闭与客户端的连接,发送一个FIN给客户端
客户端-发回ACK报文确认,并将确认序号设置为收到序号加1

为什么是四次挥手而不是三次?

因为服务端在接收到FIN, 往往不会立即返回FIN, 必须等到服务端所有的报文都发送完毕了,才能发FIN。因此先发一个ACK表示已经收到客户端的FIN,延迟一段时间才发FIN。这就造成了四次挥手。 如果是三次挥手会有什么问题? 等于说服务端将ACK和FIN的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为FIN没有到达客户端,从而让客户端不断的重发FIN。

6.HTTP协议

Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的。所以Http连接是一种短连接,是一种无状态的连接。 http传输流:发送端在层与层间传输数据时,没经过一层都会被加上首部信息,接收端每经过一层都会删除一条首部。 所谓的无状态,是指浏览器每次向服务器发起请求的时候,不是通过一个连接,而是每次都建立一个新的连接。如果是一个连接的话,服务器进程中就能保持住这个连接并且在内存中记住一些信息状态。而每次请求结束后,连接就关闭,相关的内容就释放了,所以记不住任何状态,成为无状态连接。 HTTP协议的无状态性是指服务器的协议层无需为不同的请求之间建立任何相关关系,它特指的是协议层的无状态性。但是这并不代表建立在HTTP协议之上的应用程序就无法维持状态。 应用层可以通过会话Session来跟踪用户请求之间的相关性,服务器会为每个会话对象绑定一个唯一的会话ID,浏览器可以将会话ID记录在本地缓存LocalStorage或者Cookie,在后续的请求都带上这个会话ID,服务器就可以为每个请求找到相应的会话状态。

7.HTTP状态码

2XX 成功
    200 OK,表示从客户端发来的请求在服务器端被正确处理
    204 No content,表示请求成功,但响应报文不含实体的主体部分
    206 Partial Content,进行范围请求

3XX 重定向
    301 moved permanently,永久性重定向,表示资源已被分配了新的URL
    302 found,临时性重定向,表示资源临时被分配了新的URL
    303 see other,表示资源存在着另一个URL,应使用GET 方法定向获取资源
    304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
    307 temporary redirect,临时重定向,和302含义相同

4XX 客户端错误
    400 bad request,请求报文存在语法错误
    401 unauthorized,表示发送的请求需要有通过HTTP认证的认证信息
    403 forbidden,表示对请求资源的访问被服务器拒绝
    404 not found,表示在服务器上没有找到请求的资源

5XX 服务器错误
    500 internal sever error,表示服务器端在执行请求时发生了错误
    503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

8.HTTP协议格式

HTTP的请求和响应的消息协议是一样的,分为三个部分,起始行、消息头和消息体。这三个部分以CRLF作为分隔符。最后一个消息头有两个CRLF,用来表示消息头部的结束。 HTTP请求的起始行称为请求行,形如GET /index.html HTTP/1.1。HTTP响应的起始行称为状态行,形如200 ok 消息头部有很多键值对组成,多个键值对之间使用CRLF作为分隔符,也可以完全没有键值对。形如Content-Encoding: gzip。 消息体是一个字符串,字符串的长度是由消息头部的Content-Length键指定的。如果没有Content-Length字段说明没有消息体,譬如GET请求就是没有消息体的,POST请求的消息体一般用来放置表单数据。GET请求的响应返回的页面内容也是放在消息体里面的。我们平时调用API返回的JSON内容都是放在消息体里面的。

9.输入url到页面加载都发生了什么事情

输入地址
浏览器查找域名的IP地址 这一步包括DNS具体的查找过程,包括:浏览器缓存->系统缓存->路由器缓存...
浏览器向web服务器发送一个HTTP请求
服务器的永久重定向响应(从 http://example.com 到 http://www.example.com)
浏览器跟踪重定向地址
服务器处理请求
服务器返回一个 HTTP 响应
浏览器显示HTML
浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)
浏览器发送异步请求

10.TCP与HTTP

(1)现代浏览器在与服务器建立了一个TCP连接后是否会在一个HTTP请求完成后断开?什么情况下会断开?

在HTTP/1.0中,一个服务器在发送完一个HTTP响应后,会断开TCP链接。但是这样每次请求都会重新建立和断开TCP连接,代价过大。所以虽然标准中没有设定,某些服务器对Connection: keep-alive的Header进行了支持。意思是说完成这个HTTP请求之后,不要断开HTTP请求使用的TCP连接。这样的好处是连接可以被重新使用,之后发送HTTP请求的时候不需要重新建立TCP连接,以及如果维持连接,那么SSL的开销也可以避免。 持久连接:既然维持TCP连接好处这么多,HTTP/1.1 就把Connection头写进标准,并且默认开启持久连接,除非请求中写明Connection: close,那么浏览器和服务器之间是会维持一段时间的TCP连接,不会一个请求结束就断掉。 默认情况下建立TCP连接不会断开,只有在请求报头中声明Connection: close才会在请求完成后关闭连接。 如果维持连接,一个TCP连接是可以发送多个HTTP请求的。

(2)一个TCP连接中HTTP请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

HTTP/1.1存在一个问题,单个TCP连接在同一时刻只能处理一个请求,意思是说:两个请求的生命周期不能重叠,任意两个HTTP请求从开始到结束的时间在同一个TCP连接里不能重叠。 虽然HTTP/1.1规范中规定了Pipelining来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。 Pipelining这种设想看起来比较美好,但是在实践中会出现许多问题: 一些代理服务器不能正确的处理HTTP Pipelining。正确的流水线实现是复杂的。Head-of-line Blocking 连接头阻塞:在建立起一个TCP连接之后,假设客户端在这个连接连续向服务器发送了几个请求。按照标准,服务器应该按照收到请求的顺序返回结果,假设服务器在处理首个请求时花费了大量时间,那么后面所有的请求都需要等着首个请求结束才能响应。 但是,HTTP2提供了Multiplexing多路传输特性,可以在一个TCP连接中同时完成多个HTTP请求。 所以这个问题也有了答案:在 HTTP/1.1存在 Pipelining技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的。在HTTP2中由于Multiplexing特点的存在,多个HTTP请求可以在同一个TCP连接中并行进行。 那么在 HTTP/1.1 时代,浏览器是如何提高页面加载效率的呢?主要有下面两点:维持和服务器已经建立的TCP连接,在同一连接上顺序处理多个请求。和服务器建立多个TCP连接。

(3)浏览器对同一Host建立TCP连接到数量有没有限制?

有。Chrome最多允许对同一个Host建立六个TCP连接。不同的浏览器有一些区别。 如果图片都是HTTPS连接并且在同一个域名下,那么浏览器在SSL握手之后会和服务器商量能不能用HTTP2,如果能的话就使用Multiplexing功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个TCP连接去获取,但是可以确定的是Multiplexing很可能会被用到。 如果发现用不了HTTP2呢?或者用不了HTTPS(现实中的HTTP2都是在HTTPS上实现的,所以也就是只能使用HTTP/1.1)。那浏览器就会在一个HOST上建立多个TCP连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。

11.说说半连接队列和SYN Flood攻击的关系

三次握手前,服务端的状态从CLOSED变为LISTEN, 同时在内部创建了两个队列:半连接队列和全连接队列,即SYN队列和ACCEPT队列。 半连接队列:当客户端发送SYN到服务端,服务端收到以后回复ACK和SYN,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,也就是半连接队列。 全连接队列:当客户端返回ACK, 服务端接收后,三次握手完成。这个时候连接等待被具体的应用取走,在被取走之前,它会被推入另外一个TCP维护的队列,也就是全连接队列(Accept Queue)。

SYN Flood攻击原理:

SYN Flood属于典型的DoS/DDoS攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的IP地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果: 处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。 由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

如何应对SYN Flood攻击?

增加SYN连接,也就是增加半连接队列的容量。 减少SYN + ACK重试次数,避免大量的超时重发。 利用SYN Cookie技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证Cookie合法之后才分配连接资源。

12.TCP和UDP的区别?

TCP是一个面向连接的、可靠的、基于字节流的传输层协议。TCP有三大核心特性: 面向连接。所谓的连接,指的是客户端和服务器的连接,在双方互相通信之前,TCP需要三次握手建立连接,而UDP没有相应建立连接的过程。 可靠性。TCP花了非常多的功夫保证连接的可靠,这个可靠性体现在哪些方面呢?一个是有状态,另一个是可控制。TCP会精准记录哪些数据发送了,哪些数据被对方接收了,哪些没有被接收到,而且保证数据包按序到达,不允许半点差错。这是有状态。当意识到丢包了或者网络环境不佳,TCP会根据具体情况调整自己的行为,控制自己的发送速度或者重发。这是可控制。相应的,UDP就是无状态, 不可控的。 面向字节流。UDP的数据传输是基于数据报的,这是因为仅仅只是继承了IP层的特性,而TCP为了维护状态,将一个个IP包变成了字节流。

UDP是一个面向无连接的传输层协议。

12.Apache HTTPS证书配置

(1)二级域名

在添加一条域名解析,A类型,主机记录为二级域名称,例如wechat,记录值为IP地址,例如一台阿里云服务器的外网IP。

(2)获取HTTPS证书

通过腾讯云SSL证书管理申请,针对某个二级域名。验证的方式是通过添加一条新的域名解析,CNAME类型,主机记录例如为s2hw3l7imz8ihypx307fdm7fxicap6pj.wechat,记录值例如为s20161121111701.wechat.zhanghao90.top。(腾讯云验证方式有变化,具体看其官方文档)

(3)Apache配置

SSL证书安装参考这里,修改conf/extra/httpd-ssl.conf文件如下:

<VirtualHost wechat.zhanghao90.top:443>
    DocumentRoot "C:/xampp/htdocs"
    ServerName wechat.zhanghao90.top:443
    SSLEngine on
    SSLCertificateFile "sslConfig/Apache/2_www.domain.com_cert.crt"
    SSLCertificateKeyFile "sslConfig/Apache/3_www.domain.com.key"
    SSLCertificateChainFile "sslConfig/Apache/1_root_bundle.crt"
</VirtualHost>

需要注意的是一定要用默认的443端口!至此已经可以通过https://wechat.zhanghao90.top访问htdocs目录下的文件。

在阿里云Linux机器上安装XAMPP后,需要这样配置才能生效。

<VirtualHost *:443>

(4)配置反向代理

通过Apache反向代理到另一个端口上的Tomcat。首先是要打开conf/httpd.conf文件中的一些模块。 参考利用Apache的转发模块实现反向代理服务器,因为已经配置了https,所有此时的ProxyPass和ProxyPassReverse应该写在conf/extra/httpd-ssl.conf文件中。例如

ProxyPass / http://localhost:8081
ProxyPassReverse / http://localhost:8081

可以同时做多个反向代理,但是要写在这条的上面

ProxyPass /console-web http://1.2.3.4:8081/console-web
ProxyPassReverse /console-web http://1.2.3.4:8081/console-web

13.挂NAS存储盘

# Windows服务器,然后输入用户和密码
net use U: \\XXX.XXX.XXX.XXX\BHCS_ZHPT_01

# Linux服务器,然后输入用户和密码
# sudo mount -t nfs -o vers=3,proto=tcp,rsize=1048576,wsize=1048576,hard,intr,timeo=600 XXX.XXX.XXX.XXX:/BHCS_ZHPT_01 /data/nasdata