注: 此系列内容来自网络,未能查到原作者。感觉不错,在此分享。不排除有错误,可留言指正。
网络:
路由转发:由A发给路由器B,B经过重封装后,源IP和目标IP是不变的,源MAC地址变成B2的MAC地址,目标MAC地址变成C1的MAC地址
网络大小端:
TCP通信:
连接一个不存在的地址:
目的IP在局域网内,第一次握手会失败,会不断尝试重发握手的请求。本机会不断发出ARP(地址解析协议)请求,企图获得目的机器的 MAC 地址。因为没能获得目的 MAC 地址,这些 TCP 握手请求最终都发不出去。
ip不存在时,发送不成功 client收不到第二次握手响应,触发TCP syn重传。重传次数通过 tcp_syn_retries 参数控制的linux里为6。
ip存在port不存在时,不管IP是局域网内外的IP地址,是异常连接,发送端都会收到目的主机的RST包消息断开连接。
修改服务器返回数据TCP包源IP时,对端是否可以收到 。可以,操作系统并不检测对端源ip地址信息。但是会对checkSum做校验处理,在校验和生成之前修改源IP,再发送给对端,对端是可以接收包的,并不检验源ip地址。
tcp-keepalive:tcp探活包,定时发sync回ack ,维护连接的正常。默认下是关闭、它每隔两个小时运行一次。Ping/Pong协议,应用层ping/pong可以感之保活时间。
TCP连接池:
TCP为啥可靠:
为啥三次握手:防止旧的重复连接(网络差延时)请求报文段突然又传送到了服务端,从而产生服务端以为有新的请求过来浪费了文件句柄
为啥四次挥手:客户端要关闭链接的时候,服务端可能还有数据要发送,等服务端发送完数据后再主动关闭。
数据丢失(延迟):发数据时会起一个定时器,指定时间内没收到ACK seq+1,就再发一次数据seq、数据重复:接收方直接丢弃收到的重复数据。
数据乱序:接收方收到的正确数据是seq,返回ACK为seq+1。此时收到了seq+2,因为顺序错了,接收方会再次返回seq+1的ACK,收到3次(包含本次)就重发seq+1包
数据错误:数据包都会带校验和(checkSum)。收到数据包seq后会先对校验和进行验证,若不对,则发送ACK为seq的包,让重新发数据。
累积确认:发送方发了1至4包,接受方成功收到1至3包。接受方可只发回一个序号4的确认包。发送方就知道包1到3都接收成功,必要时重发包4。一个确认包确认了累积到某一序号的所有包。不是对每个序号都发确认包。
拥塞控制(慢启动,快重传,快恢复)。Linux中,第一次握手SYN的重传数,是tcp_syn_retries参数控制的默认为6
TCP校验和:校验处理,TCP校验和包括了96位的伪头部,其中有源地址、目的地址、协议以及TCP的长度。可以避免报文被错误地路由。
TCP三次握手协商内容:
Socket:由IP地址和端口号组成,四元组、序列号:用来解决乱序问题等。
窗口大小:用来做流量控制,严格来说是确定双方的窗口放大因子(Window size scaling factor),因为窗口大小在后续的交互中还会变。
MSS:最大数据报文长度,防止IP层分片,提升传输效率。
MTU:最大传输单元,限制大小为1500Bytes。MSS:最大报文段长度TCP传往另一端的最大块数据长度1500-20(IP头)-20(TCP头)=1460
URG(紧急包) SYN(握手) FIN(挥手) PSH(推数据) RST(重置过期连接) ACK(确认) TCP六标志位
timewait作用
1:保证服务端ack没收到重发。若没timewait,此时主动关闭方处于closed状态,被动关闭方发FIN会收到RST包而不是ACK
2:旧连接持续时间内所产生的所有报文都从网络中消失,若没timeWait新连接可能是同ip同端口,传播延迟的数据包会被新链接接收 。有timewait了2msl的时间足够消化延迟数据包或让其消散。避免新旧链接混淆,新旧四元组互不干扰。
通用连接池:https://studygolang.com/articles/12333
timewait过多问题:端口被占满(2MSL时端口无法用)。防范:业务层用链接池处理、系统层改两个内核参数:net.ipv4.tcp_tw_reuse=1、net.ipv4.tcp_tw_recycle=1。设置操作系统TIMEWAIT的重用和快速回收。
closewait过多问题:服务端打开句柄过多,报tooManyOpenFile错误。防范:pprof trace 看方法调用链,是否调用关闭句柄。
服务端重启:https://zhuanlan.zhihu.com/p/390939380
宕机重启:tcp连接异常关闭问题,发ping时对端会发RST包,全局哈希表里查找sock拿不到对应的sock元素或重启时没有启动应用端口不存在,于是回了个RST,会报connectionResetByPeer。注意:四元组对不上会丢弃收到的包。
宕机没重启:对应IP的机器没找到,服务端超时重传报文次数达到一定值后,内核会判定该TCP有问题,然后通过Socket接口告诉应用该TCP连接出问题了。
TCP中的半链接与全链接:被请求方(服务端)发送完SYN+ACK包后,此时服务器进入SYN_RECV状态
SYN攻击(半链接攻击):DDOS攻击的一种,利用TCP协议缺陷,发送大量半连接请求,耗费CPU和内存资源。短时间内收到的SYN太多,半连接队列会溢出,操作系统会把新连接丢弃造成不能连接。SYN攻击包超过半连接队列最大值时,正常SYN请求连接会被服务器丢弃。目标系统运行缓慢,会引起网络堵塞甚至系统瘫痪。
防范:设置SYN Cookie,内核中开启net.ipv4.tcp_syncookies=1,即给每个请求连接的IP地址分配一个Cookie,若短时间连续收到某个IP的重复SYN报文,就认定受到攻击,以后这个IP的包都丢弃。
epoll:没用mmap,默认是水平触发。epoll_ctl把connfd放到epollfd并拷贝到内核态,有数据时对应connfd复制到rdlist;epollwait系统调用 ,会判断rdlist是否为空,不为空则把fd信息从内核态复制到用户态数组里。
水平触发:没有把数据(元素)一次性全部读写完,那么下次调用epoll_wait()时,它还会通知你在没读写完的文件描述符上继续读写,如果你一直不去读写,会一直通知你。耗费性能,但是水平触发相对安全,最起码事件不会丢掉。
边缘触发:没有把数据(元素)全部读写完,那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!减少了拷贝过程,增加了性能,相对来说,将会产生事件丢的情况。
HTTP状态码:
502 (nginx反代的服务主动断开与nginx的连接,如常驻进程里常见程序panic、httpServer的WriteTimeout设置过短程序执行时间过长响应写超时、idleTimeout小于nginx的keepaliveTimeout,导致go服务主动断开连接了)
500(服务内部错误)、503(服务无效)、504(nginx网关执行/等待超时,程序执行未超时,但nginx的read和send timeout,还未等到后端服务自己先超时了)
101(协议切换)、200(OK)、201(创建成功)、206(Partial Content常与content-range头配合做断点下载)、
301(永久重定向),302(临时跳转)、307(临时重定向),308(永久重定向)http1.1新增、304(内容未变更)、
401(未授权)、402(要求付款)、403(禁止)、404(notFound)、405(方法不允许)、429(请求过多)、499(客户端主动断开)
options请求:Access-Control-Max-Age时间(单位是秒)内,不再需要使用options进行请求。
HTTPS数字证书:
向CA机构申请数字证书, 证书除了内容还有公钥和hash算法。主要是为了验证公钥真伪,解决公钥传输信任问题,用来防中间人攻击。
中间人中途可以替换自己向CA申请的合法证书,会判断证书上域名与自己请求域名是否一致,若证书中的域名与client请求的域名不一致,client会认定为不通过!
HTTPS:
为什么要rsa和aes结合,对称加密具有加解密速度快,性能高的特点 ,而rsa保密性好,性能不佳,rsa加解密是很耗时的。核心原理:先rsa加密aes互相得到对称密文,然后aes对明文加密通信。当keepalive到时,重新发起https后aes密文会变。
https流程:1:client端发起https请求;2:服务端证书信息和公钥hash成摘要,然后用私钥加密成数据签名,数据签名和公钥、证书信息、hash算法一起发出去,然后用公钥解数据签名得到摘要和发过来的信息生成的摘要进行对比;3:成功后client端把aes密文用公钥加密发给server、最后双方得到互相通信的aes密钥进行加密通信。
长连接应用场景下,要有一方主动关闭连接。客户端和服务端之间一直不关闭的话,连接数会越来越多,严重的话会造成资源占用过高。解决方案也比较简单。连接长时间没有数据传输的话,属于空闲连接,在服务端设置空闲连接的存活时间,超过时间后服务端主动断掉,可保证无用连接及时释放。
HTTP1.1:可以不用等上一次请求结果的返回,就并发的发出一次请求,但服务端必须按照收到客户端请求的先后顺序依次返回响应结果
HTTP2.0:
二进制分帧(独立的stream帧) 首部压缩(两端维护了header索引表,以后传输用下标) 多路复用(虚拟信道,独立的帧时分复用发送) 请求优先级 服务器推送(双向流)
GRPC注意事项:pb文件里message定义的字段只能追加式新增,不能中间插入或修改。否则在正式、预发环境下会出现编译的pb.go文件不一致而产生环境问题。
Http2.0的问题:head of line blocks 前面一个包丢了要重传,后面的包都要排队。所以出现了http3.0
webscoket:推事件 拉数据 批处理(小时间段内大量消息合成消息块再推送出去) https://learnku.com/docs/eudore/14-http-websocket/9653
websocket协议规范:ws协议是二进制分帧传输,目前标准有继续帧、二进制帧(特殊字符无法用文本帧发送)、文本帧、ping帧、pong帧、close帧六种。
WebSocket是基于Http协议的,借用了Http协议来完成一部分握手,握手使用http的Upgrade机制,在握手阶段与Http是相同的。ws帧的结构基本就是标志位、掩码数据、长度、数据四块。websocket保持长连接必须通过鉴权了才能连上来,通过后就可能持续发送广播或心跳。
前端平滑新按钮更新添加 推事件广播,前端再拉数据,推拉结合。websocket推更新事件,前端监听到后请最新的js css代码动态覆盖更新
web安全:https://www.cnblogs.com/fundebug/p/details-about-6-web-security.html
xss:反射型:带有恶意脚本代码参数的 URL,当打开URL时,恶意代码被HTML解析、执行。存储型:源于数据库中读出来的数据。只要提交表单完成注入即可,这种XSS攻击成本还是很高。
防范:入库和渲染时过滤带html标签的字符串,html.EscapeString、HttpOnly Cookie、CSP:就是建立白名单,明确告诉浏览器哪些外部资源可以加载和执行
csrf:攻击者盗用了你的身份,以你的名义发送恶意请求。
防范:同源检测(origin referer)、带token提交验证、双重Cookie验证(url上带字段与cookie里的字段校验) ,设置cookie里的Samesite属性用来标明这个Cookie是个“同站Cookie”、httpOnly Cookie、验证码
sql注入:防御:预编译语句和参数化查询
OS命令注入攻击:和SQL注入差不多,只不过SQL注入是针对数据库的,而OS命令注入是针对操作系统的。
防御:不要在对外的接口里加入参数,不要以外部传参的方式去动态执行linux shell命令。如:http://www.xxx.com?order=exec(xxx)
点击劫持:
URL跳转漏洞:如:http://gate.baidu.com/index?act=go&url=http://t.cn/RVTatrd
防御:referer的限制、加入有效性验证Token