Good developers know how things work, Great developers know why things work.
DNS
DNS递归解析过程
DNS常见记录类型
EDNS Client Subnet
HTTPDNS的应用
DNS劫持及DoH/DoT
UDP报文结构
0...15 | 16...31 |
---|---|
Source Port | Destination Posr |
Length | CheckSum |
Data octets | (payload...) |
如表格所示,UDP包头共有8个字节,除却源端口以及目标端口,这里的长度Length占两个字节,即理论上UDP单个报文的最大长度为2^16-1 = 65535
,实际上如果你在Python中构造65535的数据包会提示Message too long
。
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
payload= random_string(65535)
sock.sendto(payload.encode(), (IP, PORT))
因为IPv4包头同样也有占两个字节的Total Length,包括header+data,即IP包大小范围在20<size<65535
,那UDP整体数据荷载为65535(entire IPv4 packet size)-20(IP Header)-8(UDP Header)=65507
。
Tips:
- 互联网中的所有设备必须能支持最大不超过576字节的数据包.
512(payload)+20(Fixed Header)+40(Option Header)+4=576
- 那IPv4发包是不是越大越好呢?
- JumboFrame
- 需要交换机等网络设备支持
- 设置本机
MTU=9000
TCP/IP
HTTP
HTTP优化指南
- 避免发送http请求
- 浏览器缓存
- Cache-control
- Etag
- 浏览器缓存
- 减少http请求次数
- 合并请求
- 建联次数少了
- 重复头部少了
- 合并请求
- 减少响应数据大小
- 无损压缩
- gzip
- brotli
- deflate
- 有损压缩
- png
- webp
- 无损压缩
- Lazyload
- 细碎图片直接base64化走html gzip
HTTPS
加密方式
对称加密
在对称加密算法中,加密、解密时需要的密钥是相同的,也就是说,使用“小鸡炖蘑菇”这句话既可以对信息加密,也可以用来解密加密后的字符串,因此在使用对称加密是,密钥一定不能被人知晓,对称加密不具备前向安全性;当然因为加解密逻辑简单,所以对称加密性能高速度快。
[root@JumpServer ~]# openssl speed aes
Doing aes-128 cbc for 3s on 16 size blocks: 19905551 aes-128 cbc's in 2.96s
Doing aes-128 cbc for 3s on 64 size blocks: 5527716 aes-128 cbc's in 2.97s
Doing aes-128 cbc for 3s on 256 size blocks: 1403847 aes-128 cbc's in 2.95s
Doing aes-128 cbc for 3s on 1024 size blocks: 356786 aes-128 cbc's in 2.97s
Doing aes-128 cbc for 3s on 8192 size blocks: 44622 aes-128 cbc's in 2.97s
Doing aes-192 cbc for 3s on 16 size blocks: 16907744 aes-192 cbc's in 2.97s
Doing aes-192 cbc for 3s on 64 size blocks: 4576864 aes-192 cbc's in 2.95s
Doing aes-192 cbc for 3s on 256 size blocks: 1175446 aes-192 cbc's in 2.97s
Doing aes-192 cbc for 3s on 1024 size blocks: 295352 aes-192 cbc's in 2.97s
Doing aes-192 cbc for 3s on 8192 size blocks: 36745 aes-192 cbc's in 2.95s
Doing aes-256 cbc for 3s on 16 size blocks: 14730699 aes-256 cbc's in 2.98s
Doing aes-256 cbc for 3s on 64 size blocks: 3957665 aes-256 cbc's in 2.97s
Doing aes-256 cbc for 3s on 256 size blocks: 998590 aes-256 cbc's in 2.95s
Doing aes-256 cbc for 3s on 1024 size blocks: 253385 aes-256 cbc's in 2.97s
Doing aes-256 cbc for 3s on 8192 size blocks: 31612 aes-256 cbc's in 2.96s
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128 cbc 107597.57k 119115.77k 121825.37k 123013.09k 123078.59k
aes-192 cbc 91085.49k 99294.68k 101317.90k 101831.80k 102039.00k
aes-256 cbc 79091.00k 85283.02k 86657.30k 87362.37k 87488.35k
非对称加密
在非对称加密中,加密和解密的密钥是不同的,公钥加密的内容只有私钥才能解开,私钥加密的内容只有公钥才能解开。原理是大数求对数难度相当高,因为非对称加密比较复杂,性能远低于对称加密。
[root@JumpServer ~]# openssl speed rsa
Doing 512 bit private rsa's for 10s: 176715 512 bit private RSA's in 9.83s
Doing 512 bit public rsa's for 10s: 3049621 512 bit public RSA's in 9.86s
Doing 1024 bit private rsa's for 10s: 80712 1024 bit private RSA's in 9.87s
Doing 1024 bit public rsa's for 10s: 1299532 1024 bit public RSA's in 9.87s
Doing 2048 bit private rsa's for 10s: 11920 2048 bit private RSA's in 9.74s
Doing 2048 bit public rsa's for 10s: 433963 2048 bit public RSA's in 9.87s
Doing 4096 bit private rsa's for 10s: 1890 4096 bit private RSA's in 9.84s
Doing 4096 bit public rsa's for 10s: 124375 4096 bit public RSA's in 9.85s
sign verify sign/s verify/s
rsa 512 bits 0.000056s 0.000003s 17977.1 309292.2
rsa 1024 bits 0.000122s 0.000008s 8177.5 131664.8
rsa 2048 bits 0.000817s 0.000023s 1223.8 43967.9
rsa 4096 bits 0.005206s 0.000079s 192.1 12626.9
综上,https握手交互密钥阶段会使用非对称加密,而传输数据时使用对称加解密。
TLS1.2建联
HTTPS加密算法
- TLS_RSA_WITH_AES_128_GCM_SHA384
- 秘钥交换算法+签名算法+对称加密算法+摘要算法
- 秘钥+签名:RSA
- 对称加密:AES128
- GCM分组
- SHA384为摘要和信息验证
- RSA算法的最大问题是不支持前向保密
- DH
- 服务器生成一对公私钥,发送客户端公钥
- 客户端生成一对公私钥,发送服务端公钥
- 各自的私钥+对方的公钥=Key
- 性能比较低->ECDHE
- DH
- ECDHE
- DH
- 基础是离散对数
- a^i (mod p) = b (p如果是一个超大质数)
- a p是公开的,通过i可以推出b,但是通过b很难很难推出i
- DHE
- DH有一方的私钥是静态的 叫static DH,一般是服务器侧,随着时间的积累可能会被破解
- E即临时动态生成,每次DHE都是动态生成的私钥
- ECDHE
- 解决DHE需要做大量乘法带来的计算量问题
- Q=(dG)
- d1Q2 = d2Q1
- TLS False Start
- TLS第二次握手最后一次会图Server Key Exchange
- 告知ECDH服务端参数
- namedcurve G
- sign= rsa(Pubkey + d1)
- DH
HTTP2
HTTP2与HTTP1的区别
- 头部压缩
- HPACK
- 二进制
- 不再使用明文报文
- 效率满满
- 基础单位是帧
- 数据流
- 客户端发出的是奇数
- 服务端发出的是偶数
- 多路复用
- 解决HTTP 队头阻塞
- maxstream
- Server Push
- 一个TCP连接上有多少流
HTTP2改进项
- 头部压缩
- 很多字段占据大量字节,有必要压缩
- 多次传输的数据都是重复的
- 字段是ASCII编码,有必要改成二进制编码
- HPACK (50~90%压缩效率)
- 静态字典
- 61组
- 动态字典
- Http2maxrequests
- 避免动态表无限增大
- Http2maxrequests
- Huffman编码(压缩算法)
- 静态字典
- 二进制帧
- header+payload
- 9 =(帧长度3+帧类型1+标志位1+2^31流标志符)
- 并发传输
- Connection [N*Stream [(Request|Response)Message[N *frame]]]
- Stream 单调递增
- nginx http2maxconcuttentstreams = 128
- goaway
- Connection [N*Stream [(Request|Response)Message[N *frame]]]
- server push
- 通过pushpromise帧告诉下一个资源
- 需要预先设置
HTTPS优化指南
分析性能损耗
- TLS协议握手过程,使用的算法
- 握手后的对称加密报文传输
- AES
- AES-128-CGM比AES-256-GCM快一点点
- Chacha20-poly1305
- cipher list尽可能把性能好的套件放前面
- AES
硬件优化
- 选择支持AES-NI的CPU
- Offload
软件
- 升级Openssl
- 升级内核
会话复用
- session id
- Session tickct
- Pre-shared key
- 重放攻击
- 设置一个合理的时间
- 只允许GET/HEAD使用绘画重用
协议优化
- 密钥交换算法优化
- ECDHE
- x25519椭圆算法速度最快
- TLS升级为1.3
- Early Data
- 客户端发出请求时指定1.3并带上支持的椭圆曲线,以及计算出来的公钥们(N个)
- 服务器端选定指定的椭圆曲线带上服务器计算出来的公钥(1个)
- 仅支持ECDHE
- 仅支持5个cipher套件,避免被中间人强制降级
证书优化
- 传输优化
- ECDSA 256
- 带上中间证书,但不带CA
- 证书验证
- CRL
- OCSP
- OCSP stapling
- cache 7天?
- OCSP stapling