SSL/TLS深度解析--TLS性能优化

发布时间:2020-06-23 20:13:50 作者:zyy123
来源:网络 阅读:1876

TCP 优化

Linux系统内核参数优化

[root@www ~]# cat /etc/redhat-release;uname -r
CentOS Linux release 7.5.1804 (Core) 
3.10.0-862.11.6.el7.x86_64
TLS 的下一层是 TCP 协议,所以对 TCP 的优化是可以直接影响到 TLS 的性能效率。
在对 TCP 的优化中,主要涉及以下几个概念:
(1)拥塞控制(congestion control)机制:在一个 TCP 连接开始时,不知道对方的速度有多快。如果有足够大的带宽,服务器端可以用最快的速度传送数据,但是如果对方的网络很慢,服务器发送的数据太多的话,会压跨连接,导致连接中断。所以,每个 TCP 连接都有一个称为拥塞窗口(cwnd = congestion window)的速度极限。这个窗口最初较小,在通信的过程中,如果双方都能接受这个速度,那么会加大这个拥塞窗口的值(初期增长很快,翻倍增长),这种机制被叫做慢启动(slow start)。
拥塞控制机制对于 TLS 连接的影响比较大,TLS 握手消耗了宝贵的初始连接字节(当拥塞窗口较小时);如果拥塞窗口足够大,那么慢启动不会有额外的延迟。但是,如果握手消息长度超过了拥塞窗口大小,发送方将必须把这个长信息拆分成两块,先发送一块,等待确认(1个往返),增加拥塞窗口,然后再发送剩下的部分。这样就增加了由 TLS 握手造成的延时。
(2) 慢启动阈值 ssthresh(避免 cwnd 增长过快,网络无法承担,造成丢包)
如果 cwnd 小于 ssthresh,表示在慢启动阶段,cwnd是翻倍增长的;如果 cwnd 大于 ssthresh,那么表示在拥塞避免阶段,这时候 cwnd 不再像慢启动阶段那样翻倍增长,而是线性增长,尽量避免网络拥塞。
(3) 接收窗口(rwnd),用来表示最多能保存多少数据,实际中接收窗口rwnd的合理值取决于BDP的大小,也就是带宽和延迟的乘积。如果带宽是 80Mbps,延迟是 100ms,那么计算过程如下:
BDP = 80Mbps 100ms = (80 / 8) (100 / 1000) = 1MB = 1024KB = 1048576B
TCP 用16位来记录窗口大小,也就是说最大值是64KB,如果超过这个值,就需要 tcp_window_scaling 机制(默认是开启)。配置内核参数中接收缓冲的大小,就可以控制接收窗口的大小:
net.ipv4.tcp_rmem = <MIN> <DEFAULT> <MAX>
Linux本身有一个缓冲大小自动调优的机制,窗口的实际大小会自动在最小值和最大值之间变化,找到性能和资源的平衡点。确认缓冲大小自动调优机制(0:关闭、1:开启):sysctl -a | grep tcp_moderate_rcvbuf。如果缓冲大小自动调优机制设置成关闭状态,那么就把缓冲的 DEFAULT 值设置为 BDP;如果缓冲大小自动调优机制设置成开启状态,那么就把缓冲的 MAX 设置为 BDP。
(4) 存储 TCP 连接本身一些信息的额外开销:net.ipv4.tcp_adv_win_scale 的值可能是 1 或者 2,如果是 1 的话,则表示二分之一的缓冲被用来做额外开销,如果是 2 的话,则表示四分之一的缓冲被用来做额外开销。按照这个逻辑,缓冲最终的合理值的具体计算方法如下:result=BDP / (1 – 1 / 2^tcp_adv_win_scale)。
(5) 空闲连接回到慢启动:慢启动在一段时间内没有任何流量的连接上起作用,达到降低速度的效果,并且速度下降非常快。所谓的“一段时间”可以是非常小的,比如1秒钟,但在实际场景中,每一个长连接(例如使用 HTTP 长连接)的速度都有可能被调到很慢!为了保持速度建议禁用这个功能。
在 Linux 上,可以在连接空闲时禁用慢启动: 0表示否,1表示开启慢启动,默认是1
可以通过一下命令使其临时生效,但重启以后就失效了,查看:sysctl -a | gerp slow_start_after_idle
临时:sysctl -w net.ipv4.tcp_slow_start_after_idle=0
永久生效:将 net.ipv4.tcp_slow_start_after_idle=0 设置添加到 /etc/sysctl.conf 配置文件中。
对拥塞窗口(cwnd)初始值调优:
启动速度限制被称为初始拥塞窗口(initial congestion window, initcwnd )。2013年4月发布的 RFC6928,google 建议默认情况下初始拥塞窗口设置为10个 MSS(约15 KB)。【Centos 7默认是10MSS】早期的建议是使用2或4个MSS(约3—6KB)。MSS 是 TCP 层上的概念,大小是 1460 字节。IP 层上是 MTU,1500字节。
[root@www ~]# sysctl -a |grep ssthresh
net.ipv4.tcp_max_ssthresh = 0   #在虚拟机中
[root@www ~]# sysctl -a |grep tcp_window_scaling
net.ipv4.tcp_window_scaling = 1
[root@www ~]# cat /proc/sys/net/ipv4/tcp_rmem    # rwnd值
4096    87380   6291456
[root@www ~]# sysctl -a |grep tcp_moderate_rcvbuf        
net.ipv4.tcp_moderate_rcvbuf = 1
[root@www ~]# sysctl -a |grep adv_win_scale
net.ipv4.tcp_adv_win_scale = 1
[root@www ~]# sysctl -a |grep start_after_idle
net.ipv4.tcp_slow_start_after_idle = 1

# 设置cwnd
[root@www ~]# ip route
default via 172.16.216.2 dev ens33 
169.254.0.0/16 dev ens33 scope link metric 1002 
172.16.216.0/24 dev ens33 proto kernel scope link src 172.16.216.188 
[root@www ~]# ip route | while read p; do ip route change $p initcwnd 10; done
[root@www ~]# ip route
default via 172.16.216.2 dev ens33 initcwnd 10 
169.254.0.0/16 dev ens33 scope link metric 1002 initcwnd 10 
172.16.216.0/24 dev ens33 proto kernel scope link src 172.16.216.188 initcwnd 10
# initcwnd 10:初始化cwnd
# 单方面提升发送端 cwnd 的大小并不一定有效,因为网络中实际传输的未经确认的数据大小取决于  rwnd 和 cwnd 中的最小值,所以一旦接收方的 rwnd 比较小的话,会抑制 cwnd 的发挥。

# 设置initrwnd(linux kernel 2.6.33 and newer)
[root@www ~]# ip route
default via 172.16.216.2 dev ens33 
169.254.0.0/16 dev ens33 scope link metric 1002 
172.16.216.0/24 dev ens33 proto kernel scope link src 172.16.216.188 
[root@www ~]# ip route | while read p; do ip route change $p initrwnd 10; done 
[root@www ~]# ip route
default via 172.16.216.2 dev ens33 initrwnd 10 
169.254.0.0/16 dev ens33 scope link metric 1002 initrwnd 10 
172.16.216.0/24 dev ens33 proto kernel scope link src 172.16.216.188 initrwnd 10 

# 一些系统的rwnd值:
# Linux 2.6.32                                      3*MSS (usually 4380)
# Linux 3.0.0                                       10*MSS (usually 14600)
# Windows NT 6.1    (Windows 7 or Server 2008 R2)   8192 ^ 2
[root@www ~]# getconf PAGE_SIZE
4096
总内存
net.ipv4.tcp_mem = 93408 124544 186816
写(缓冲)
net.ipv4.tcp_wmem = 4096 16384 3985408
读(缓存)
net.ipv4.tcp_rmem = 4096 87380 3985408
[root@www ~]# cd /proc/sys/net/ipv4
[root@www ipv4]# cat tcp_fin_timeout 
60
[root@www ~]# sysctl -a |grep timestamps
net.ipv4.tcp_timestamps = 1

initcwnd

ip-sysctl

SSL/TLS深度解析--TLS性能优化

TLS 协议优化

[root@www ~]# openssl s_client -connect www.openssl.org:443 -status |grep -i ocsp
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
OCSP response: 
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response

SSL/TLS深度解析--TLS性能优化

3. 会话恢复
TLS理解两种类型的握手:完整握手和简短握手。理论上完整握手只会在客户端与服务器建立TLS会话(TLS session)的时候进行一次。后续的连接,双方使用简短握手恢复之前协商的会话。简短握手因为不需要密钥交换与密钥生成等操作,所以会更快,并且少一次往返时间。
4.TLS的纪录协议造成的在网络传输中的额外开销
TLS协议的最小传输单位是一个TLS记录,它最多可以包含2^14=16384字节(16K)的数据。一条记录在不加密的情况下只有很小的开销;每个记录以5字节的元数据开头,即内容类型(1字节)、协议版本(2字节)和数据长度(2字节)。流加密、分组加密和已验证密码套件加密后的TLS记录的额外开销。

SSL/TLS深度解析--TLS性能优化

尽量避免发送小包数据。尽量缓冲应用层数据避免额外的网络开销。
5.对称加密对CPU资源的消耗
加密操作有明显的CPU成本,成本由加密算法、加密模式和完整性校验算法三者决定。
6. TLS 记录的缓存延迟
TLS记录是TLS发送和接收数据的最小单位。TLS记录的大小与下一层TCP包的大小并不匹配,一个全尺寸的TLS记录16 KB需要被拆分成许多小的TCP包(大约12个),通常每个小于1.5 KB(1.3KB)。整个TLS记录被分成小的TCP包后,各个小包会陆续到达,但在全部到齐之前是无法进行解密处理的。这是因为TLS记录同样是数据解密和完整性检验的最小单位。缓存延迟有时可能会比较大。
虽然通过TCP协议可以把丢失和延迟的数据包恢复,但仍然需要消耗一次往返。每一次额外的往返对于整个TLS记录都意味着延迟。 初始拥塞窗口另一个触发额外往返的延迟是在连接初期发送大量数据导致初始拥塞窗口溢出。一旦拥塞窗口满了,发送端必须等待响应(1次往返),等到拥塞窗口增加再发送更多数据。
如果Web服务器支持TLS记录调整,就应该考虑将默认值(16 KB这么大的数值)改成更为合理的值,调整这个值由部署的密码套件和相应的传输开销决定,一般情况下设置成4 KB。如果将TLS记录大小设置为与TCP/IP包准确匹配,那就设置成1400字节左右,然后通过观察数据包逐步调整。IP报文理论上最大是65535个字节,是很大的,但是由于IP分片效果很不好,所以TCP在三次握手中互相得知对方的MSS(MTU减IP头部),不给IP层很大块的数据,避免IP数据报分片
例如,数据链路层最大传输单元(maximum transfer unit,MTU)是1500字节,那么可以预见:
1,500 bytes MTU 去除额外开销,所传数据 1379 —1419 bytes 。
-20 bytes IPv4 herder | - 40 bytes IPv6 header
- 32 bytes TCP header TCP 头部 最小是20字节可拓展的是40字节,最大为60字节
- 29 bytes TLS record | - 49 bytes TLS record

MSS 是1460 bytes :1460 - 32 - 29|49 = 1379 — 1399 bytes
首先MTU的值是变化的。虽然多数客户端继承以太网1500字节的限制,但也有一些协议支持更大的数据。比如,巨型帧(jumbo frame)允许多达9000字节。还有就是使用IPv4和IPv6(IPv4头是20字节,IPv6头是40字节)计算会略有不同,所密码套件的变化也会影响这个数值。
另一个问题是减小TLS记录的大小会增加传输开销,也就是吞吐量会下降。如果将TLS记录长度调大(最大16K),那么由于是加密的数据,得要所有的数据(所有的IP包)都到齐了,才会顺利的解密出明文,等待的时间会较长,吞吐率是上去了,响应的实时性就下降了。nginx上也有配置这个值的选项,只是不能动态调整。
推荐阅读:
  1. 程序清单4.6_printout.c程序_《C Primer Plus》P68
  2. 在VS2015中使用lua语言

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

tls 性能优化 --

上一篇:Echarts多任务可视化之再优化

下一篇:cygwin syntax error: unexpected end of file

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》