452. Linux进程地址空间
- 文本段:包含程序的可执行代码
- 初始化数据段(数据段):包含已初始化的全局变量和静态变量。
- 未初始化数据段(BSS段):包含未初始化的全局变量和静态变量。
- 堆:动态分配内存时(如使用malloc和new),分配的内存位于堆区域。
- 栈:用于存储局部变量、函数参数和返回地址等,每个线程都有自己的栈。
453. 内核空间在哪?
内核空间位于进程地址空间的上部,这是操作系统内核运行和管理系统资源的区域。在许多操作系统(包括Linux)中,进程地址空间被分为两大部分:用户空间和内核空间。
454. socket专门用于单机进程通信的?
不是,socket不仅仅用于单机进程通信,她更广泛用于网络间的进程通信。
Socket是操作系统提供的编程接口(API),允许程序在网络中发送和接受数据包。Sockets提供了基于不同网络协议(如TCP/IP或UDP)的端到端通信机制,进程可以使用sockets在不同的计算机上相互通信。
455. 为什么能进行进程通信,本质原因?
进程通信能够实现的本质原因是操作系统提供的抽象层。操作系统通过进程控制块管理所有的进程,并提供一系列进程间的通信机制,允许在同一台计算机上或通过网络连接的计算机之间的进程安全的交换信息。
456. TCP和UDP的区别
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,他保证数据正确性和顺序。
UDP(用户数据报协议)是一种无连接的协议,提供快速、尽最大努力交付的传输方式,但不保证数据包的顺序或可靠性。简而言之,TCP强调可靠性,而UDP强调速度。
457. TCP保证可靠性的机制有哪些
可靠性的主要机制:
- 三次握手:建立连接前的同步过程,确保双方准备好进行数据传输。
- 序列号和确认应答:每个TCP包都有序列号,接收方回送确认包告知发送方数据已接受。
- 数据重传:丢失或错误的数据包会被重新发送。
- 流量控制:使用滑动窗口机制,调整发送频率以匹配接收方的处理能力。
- 拥塞控制:根据网络状况动态调整数据发送的速率,防止网络拥塞。
- 数据校验:使用校验和检测数据在传输过程中的任何变化。
458. 滑动窗口的原理是什么?如何保证消息的顺序?
滑动窗口原理是分配一个固定数量的序列号给发送方的未确认消息(即窗口大小),控制发送方在收到确认之前可以发送的消息总数,从而调节发送速度。为了保证消息顺序,接收方按照消息的序列号顺序处理消息,不按需到达的消息会被缓存起来,直到缺失的消息补齐后在一起处理。这个过程确保了即使消息在传输过程中出现乱序,也能在最终处理时恢复正确的顺序。
459. HTTPS用的对称加密还是非对称加密?原理?建立连接的过程?
HTTPS使用非对称加密来建立安全连接,然后使用对称加密来传输数据。
原理是:
- 浏览器请求HTTPS连接并获取服务器的公钥。
- 浏览器验证服务器证书的有效性。
- 使用非对称加密,浏览器生成一个对称加密的密钥(会话密钥),并用服务器的公钥加密他,发送到服务器。
- 服务器使用自己的私钥解密,获取对称会话密钥。
- 双方是用这个会话密钥进行对称加密通信,确保数据的安全传输。
460. http和https的区别
区别主要有以下四点:
- http是超文本传输协议,信息是明文传输,存在安全风险问题。https则解决http不安全的缺陷,在TCP和HTTP网络层之间加入了
SSL/TLS
安全协议,使得报文能够加密传输。 - http连接建立相对简单,tcp三次握手之后便可进行http的报文传输。而https在tcp三次握手之后,还需进行SSL/TLS的握手过程,才可进入加密报文传输。
- 两者的默认端口不一样,http的默认端口号是
80
,https默认端口号是443
. - https协议需要向
CA
(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
461. SSL/TLS写一下建立连接的过程
传统的TLS握手基本都是使用RSA算法来实现密钥交换的,在将TLS证书部署服务端时,证书文件其实就是服务器的公钥,会在TLS握手阶段传递给客户端,而服务器端的私钥则一直留在服务端,一定要确保私钥不能被窃取。在RSA密钥协商算法中,客户端会生成随机密钥,并使用服务端的公钥加密再传给服务端。根据非对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双方就得到了相同的密钥,再用他加密应用消息。我用Wireshark工具抓了用RSA密钥交换的TLS握手过程,可以看到一共经历了四次握手:
TLS第一次握手:
首先,由客户端向服务器发起加密通信请求,也就是Client Hello
请求。在这一步,客户端主要向服务器发送以下信息:
- 客户端支持的TLS协议版本,如TLS 1.2 版本。
- 客户端生产的随机数(Client Random),后面用于生成【会话密钥】条件之一。
- 客户端支持的密码套件列表,如RSA加密算法。
TLS第二次握手:
服务器收到客户端请求后,向客户端发出响应,也就是SeverHello。服务器回应的内容有以下内容:
- 确认TLS 协议版本,如果浏览器不支持,则关闭加密通信。
- 服务器生产的随机数(Server Random),也就是后面用于生产的【会话密钥】条件之一。
- 确认的密码套件列表,如RSA加密算法。
- 服务器的数字证书。
TLS第三次握手:
客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的CA公钥,确认服务器的数字证书的真实性。如果证书没有问题,客户端会从数字证书中取出服务器公钥,然后使用他加密报文,向服务器发送如下信息:
- 一个随机数(pre-master key)。该随机数会被服务器公钥加密。
- 加密通信算法改变通知,表示随后的信息都将适用于【会话密钥】加密通信。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务器校验。
上面第一项的随机数是整个握手阶段的第三个随机数,会发给服务端,然后这个随机数客户端和服务端都是一样的。服务端和客户端有了这三个随机数,接着就用双方协商的加密算法,各自生成本次通信的【会话密钥】。
TLS第四次握手:
服务器收到客户端的第三个随机数之后,通过协商的加密算法,计算出本次通信的【会话密钥】。然后,向客户端发送最后的消息:
- 加密通信算法改变通知,表示随后的信息都将用【会话密钥】加密通信。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
至此,整个TLS的握手阶段全部结束。接下来,客户端和服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用【会话密钥】加密内容。
462. 有哪些常见的状态码?
HTTP状态码分为5大类:
-
1xx
类状态码属于提示信息,是协议处理的一种中间状态,实际用到的比较少 -
2xx
类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。 -
3xx
类状态码表示客户端请求的资源发生了变动,需要客户端用新的URL重新发送请求获取资源,也就是重定向。 -
4xx
类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义 -
5xx
类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
其中常见的具体状态有:
- 200:请求成功
- 301:永久重定向;302:临时重定向;
- 404:无法找到此页面;405:请求的方法类型不支持
- 500:服务器内部出错
463. 有哪些常见的字段
HTTP请求字段
-
Host
:指定请求的主机名和端口号。 -
Content-Type
:指定请求体的媒体类型,通常用于POST请求。 -
Content-Length
:指定请求体的长度(以字节为单位)。 -
Cookie
:用于向服务器发送存储在客户端的Cookie。
HTTP响应字段:
-
Content-Type
:指定响应体的媒体类型。 -
Content-Length
:指定响应体的长度(以字节为单位) -
Cache-Control
:指定缓存机制的指令,例如no-cache,max-age等。 -
Set-Cookie
:用于向客户端设置Cookie -
Location
:在进行重定向时,指定新的URL。 -
Server
:提供关于服务器的信息,例如软件名称和版本。
464. HTTPS如何保证应用数据的完整性
在数据传输过程中,SSL/TLS使用消息认证码(MAC)来验证数据的完整性。对每个数据包,发送方会计算一个MAC,并将其附加到数据包中。在接收端,接收方会使用相同的算法和密钥重新计算MAC,并与接收到的MAC进行比较。如果匹配,数据被认定是完整且未被篡改的。
465. OCSP的作用
客户端在验证证书时,是个复杂的过程,会走证书链逐级验证,验证的过程不仅需要【用CA公钥解密证书】以及【用签名算法验证证书的完整性】,而且为了知道证书是否被CA吊销,客户端有时还会再去访问CA,下载CRL或者OCSP数据,以确认证书的有效性。这个访问过程是HTTP访问,因此又会产生一系列网络通信的开销,如DNS查询、建立连接、收发数据等。
CRL:
CRL被称为证书吊销列表,这个列表是由CA定期更新,列表内容都是被撤销信任的证书序号,如果服务器的证书在此列表,就认为证书已经失效,不在的话,则认为证书是有效的。
但是CRL存在两个问题:
- 由于CRL列表是由CA维护的,定期更新,如果一个证书刚被吊销后,客户端在更新CRL之前还是会信任这个证书,实时性较差;
- 随着吊销证书的增多,列表会越来越大,下载的速度就会越慢,下载完客户端还得遍历这么大的列表,那么就会导致在校验证书这一环节的延时很大,进而拖慢了HTTPS的连接。
OCSP:
因此,现在基本上都是使用OCSP,名为在线证书状态协议来查询证书的有效性,他的工作方式是向CA发送查询请求,让CA返回证书的有效状态。
不必像CRL方式客户端需要下载大大的列表,还要从列表查询,同时因为可以实时查询每一张证书的有效性,解决了CRL的实时性问题。OCSP需要向CA查询,因此也是要发生网络请求,而且还得看CA服务器的“脸色”,如果网络状态不好,或者CA服务器繁忙,也会导致客户端在校验证书这一环节的延时变大。
OCSP Stapling:
于是为了解决这一个网络开销,就出现了OCSP Stapling。其原理是:服务器向CA周期性的查询证书状态,获得一个带有时间戳和签名的响应结果并缓存他。
当客户端发起连接请求时,服务器会把这个【响应结果】在TLS握手过程中发给客户端。由于有签名的存在,服务器无法篡改,因此客户端就能得知证书是否已被吊销了,这样客户端就不需要再去查询。
466. 什么是会话复用?
TLS握手的目的就是为了协商出会话密钥,也就是对称加密密钥,那我们如果把首次TLS握手协商的对称加密密钥缓存起来,待下次需要建立HTTPS连接时,直接【复用】这个密钥,不就减少TLS握手的性能损耗了么?这种方式就是【会话复用】。
会话复用分为两种:
- 一种叫
Session ID
; - 一种叫
Session Ticket
Session ID:
工作原理是,客户端和服务器首次TLS握手连接后,双方会在内存缓存会话密钥,并用唯一的Session ID,Session ID和会话密钥相当于key-value关系。当客户端再次连接时,hello消息里会带上Session ID,服务器收到后就会从内存找,如果找到就直接用该会话密钥回复会话状态,跳过其余的过程,只用一个消息往返就可以建立安全通信。当然为了安全性,内存中的会话密钥会定期失效。
但是他有两个缺点:
- 服务器必须保持每一个客户端的会话密钥,随着客户端的增多,服务器的内存压力也会越大。
- 现在网站服务一般是由多台服务器通过负载均衡提供服务,客户端再次连接不一定会命中上次访问过的服务器,于是还要走完整的TLS握手过程。
Session Ticket:
为了解决Session ID的问题,就出现了Session Ticket,服务器不再缓存每个客户端的会话密钥,而是把缓存的工作交给了客户端,类似于HTTP的Cookie。客户端与服务器首次建立连接时,服务器会加密【会话密钥】作为Ticket发给客户端,交给客户端缓存该Ticket。客户端再次连接服务器,客户端会发送Ticket,服务器解密后就可以获取上一次的会话密钥,然后验证有效期,如果没有问题,就可以恢复会话了,开始加密通信。
对于集群服务器的话,要确保每台服务器加密【会话密钥】的密钥是一致的,这样的客户端携带Ticket访问任意一台服务器时,都能恢复会话。
467. http是无状态协议嘛?
是的,HTTP是一个无状态协议。这意味着每个请求都是独立的,服务器不会存储有关客户端之前请求的信息。虽然HTTP是无状态的,但在许多应用中需要管理状态(例如用户登陆状态、购物车等)。为了实现这一点,常见的方法包括:cookie、session、token。
468. session、token、cookie的区别
-
session
存储与服务器,可以理解为一个状态列表,拥有一个唯一识别符号sessionID,通常存放于cookie中。服务器收到cookie后解析出sessionID,再去session列表中查找,才能找到相应session,依赖cookie。 -
cookie
类似一个令牌,装有sessionID,存储在客户端,浏览器通常会自动添加。 -
token
也类似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可以知道是哪个用户,需要开发者手动添加。
469. 如何抵抗csrt?
CSRT(跨站请求伪造) 是一种攻击手段,攻击者通过诱导用户执行恶意操作,从而获取用户数据或执行恶意代码。CSRT攻击通常通过伪造一个合法的HTTP请求来实现,这个请求看起来是合法的,但实际上是为了执行一个攻击者控制的操作。
解决CSRF攻击的方法主要有以下几种:
- 验证用户会话:在服务器端对用户会话进行验证,确保请求的会话标识符与当前会话标识符匹配。这样可以防止攻击者伪造会话标识符。
- 使用双重验证:除了会话验证,还可以使用其他验证方式,例如验证码、签名验证等。这些验证方式可以增加攻击的难度。
- 防止跨站请求:通过设置CSP(内容安全策略)来防止跨站请求,限制网页中可执行的脚本源,减少攻击者诱导用户执行恶意操作的可能性。
- 避免使用自动提交表单:禁用默认的自动提交功能,要求用户再提交表单前确认操作,防止攻击者诱导用户在未经授权的情况下提交表单。
- 强制Referer头部:在服务器端检查请求的Referer头部,确保请求来自可行来源。
470. 分布式情况下的session会存在什么问题?
在多个应用服务器之间存储session会话状态时,保持会话的一致性变得困难。如果用户的请求被路由到不同的服务器,可能导致无法访问到相同的会话数据,为解决这个问题,一般将会话数据存储在缓存系统(如Redis)中,确保所有服务器都能访问。
471. JWT的作用
JWT最常见的用途是身份验证。在用户登陆成功后,服务器会生成一个JWT,并将其返回给客户端。客户端随后可以在后续的请求中使用这个令牌来证明身份,这种方式不需要在服务器上存储会话状态,避免了分布式情况下会话数据需要共享的问题,因为JWT本身包含了用户的信息和验证信息。
472. 接收方如何验证JWT的真实性和完整性?
JWT由三部分组成,使用点(.)分割,格式为header.payload.signature。接收方首先需要将JWT解码为这三部分:
Header
:包含类型(通常是JWT)和使用的签名算法(如HMACSHA256)。Payload
:包含用户可识别的信息和声明(如用户ID、权限、过期时间等)。Signature
:由头部和载荷的JSON字符串生成的签名。
为了验证JWT的真实性和完整性,接收方需要i执行以下步骤:
- 获取签名密钥:接收方需要知道用于签名的密钥。对于对称签名算法(如HMAC),密钥在接收方和发送方之间共享;对于非对称签名算法(如RSA),接收方需要获取发送方的公钥。
- 重建签名:将头部和载荷部分使用相同的编码方法(通常是Base64 URL编码),拼成一个字符串,例如:<encoded_header>.<encoded_payload>。使用签名算法和密钥对这个字符串进行签名,生成新的签名。
- 比较签名:将新生成的签名与JWT中的签名部分进行比较。如果这两者匹配,则证明JWT的真实性和完整性,即令牌未被篡改。
即使签名验证通过,接收方还需要检查载荷中的有效性信息:
- 过期时间(exp):检查JWT是否已过期。exp声明表示JWT的失效时间,接收方需要验证当前时间是否在该时间之前。
- 颁发者(iss):确认JWT的颁发者是否可信。
- 受众(aud):验证JWT的受众是否与请求的目标服务匹配。
- 其他自定义声明:根据业务要求,接收方可以检查其他声明(如权限、角色等)。