kTLS是将TLS记录层加解密移至内核态的软件加速机制,非网卡硬件卸载;它减少用户/内核态拷贝与上下文切换,依赖内核≥4.13、ULP配置及应用调用setsockopt启用,需配合GRO/TSO等卸载技术协同提效。

Linux内核中目前不支持TLS协议栈的完整硬件卸载,所谓“TLS卸载”实际指的是Kernel TLS(kTLS)——一种将TLS记录层的加解密操作从用户态移至内核态执行的软件加速机制,而非网卡硬件层面的卸载。它不依赖NIC硬件能力,但能显著降低CPU开销、减少内存拷贝、提升小包转发场景下的吞吐效率。
理解kTLS:不是硬件卸载,而是内核态加密加速
kTLS在TCP连接建立后,将对称加密/解密(如AES-GCM)卸载到内核协议栈完成,应用层仍负责握手(TLS handshake)、密钥派生等非对称操作。这意味着:
- 数据路径上不再需要用户态与内核态之间反复拷贝明文/密文,避免了send()/recv()调用带来的上下文切换开销;
- 加解密由内核使用优化的汇编或SIMD指令完成,比多数用户态TLS库(如OpenSSL)更轻量、更可控;
- 它与网卡checksum offload、GRO/GSO等可叠加使用,共同构成端到端的转发加速链路。
启用kTLS的前提条件
不是所有环境都能直接启用kTLS,需同时满足:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 内核版本 ≥ 4.13(推荐 ≥ 5.10,功能更稳定,支持TLS 1.3部分特性);
- 启用CONFIG_TLS、CONFIG_CRYPTO_USER_API_HASH等内核配置选项(主流发行版默认已开启);
- 应用使用标准socket API,并主动调用setsockopt(SOL_TCP, TCP_ULP, "tls")加载ULP模块;
- 加密套件必须匹配内核支持的类型(如TLS_AES_128_GCM_SHA256),且密钥、IV、salt等参数需由用户态提供并严格对齐结构体定义。
实操:在转发服务中集成kTLS
以一个基于epoll的代理服务为例,关键步骤如下:
- 建立TCP连接后,立即设置ULP:
setsockopt(sock, SOL_TCP, TCP_ULP, "tls", 4); - 完成TLS握手(通常仍在用户态用OpenSSL完成),获取协商后的密钥材料;
- 构造
struct tls12_crypto_info_aes_gcm_128,填入write方向的key、iv、salt、rec_seq; - 调用
setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info))启用发送加密; - 同理对读方向调用
TLS_RX启用接收解密(注意:收发可独立启用); - 后续所有
send()和recv()即自动走kTLS路径,无需修改业务逻辑。
配合其他卸载技术协同提效
kTLS单独作用有限,需与底层网络卸载联动才能释放最大转发效能:
- 开启网卡校验和卸载(
ethtool -K eth0 tx on rx on),避免CPU重复计算IP/TCP校验和; - 启用GRO(Generic Receive Offload)合并入向小包,减少软中断次数;
- 启用TSO或GSO分段卸载,让大块TLS密文由硬件分片,降低协议栈分片开销;
- 若使用DPDK或XDP,kTLS暂不兼容,此时应转向用户态TLS加速(如BoringSSL + io_uring)或专用加密卡。
不复杂但容易忽略:kTLS的价值不在单连接延迟,而在高并发小包场景下降低整体软中断负载与内存带宽压力。实测表明,在万级TLS连接+千兆带宽的反向代理节点上,启用kTLS后CPU softirq占用下降约12%,PPS吞吐提升5–7%。

















