You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kernel 5.3(Fedora30/31)下启用Kernel TLS ULP时setsockopt调用失败求助

解决Kernel 5.3(Fedora 30/31)Kernel TLS ULP启用错误的问题

我来帮你拆解遇到的几个错误,并一步步解决问题:

1. 普通用户执行时的「No such file or directory」错误

这个问题很明确:当你以普通用户身份运行程序时,tls内核模块还未加载,而普通用户没有自动加载内核模块的权限,内核找不到对应的ULP实现,因此返回ENOENT错误。

2. sudo执行后的「Unknown error 524」错误

错误码524对应内核的EKEYREJECTED,本质原因是你只启用了TLS ULP,但没有配置必要的TLS密钥和上下文信息。Kernel TLS的规则是:启用ULP之后,必须先通过setsockopt设置TLS_CONF选项,提供加密算法、密钥、IV等参数,否则内核会拒绝后续操作。

另外,先确认你的Fedora内核是否开启了Kernel TLS的必要配置:

zcat /proc/config.gz | grep CONFIG_TLS

你需要看到CONFIG_TLS=y或者CONFIG_TLS=m(模块形式),如果显示# CONFIG_TLS is not set,说明内核未编译该功能,需要重新编译内核或更换支持的内核包。


修复步骤

步骤1:手动加载tls模块(需要sudo权限)

先确保模块已加载,避免后续权限问题:

sudo modprobe tls

执行后用lsmod确认:

lsmod | grep tls

正常会输出:

tls 57344 0

步骤2:完善测试代码,添加TLS上下文配置

你的原代码只做了启用ULP的操作,缺少关键的TLS参数配置。下面是修改后的测试代码,添加了最基础的AES-GCM算法配置(示例密钥仅用于测试,实际需从TLS握手获取):

// tls.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/tls.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

int main() {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket creation");
        exit(EXIT_FAILURE);
    }

    // 启用TLS ULP
    if (setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")) == -1 ) {
        perror("tls init");
        exit(EXIT_FAILURE);
    }

    // 配置TLS上下文(示例参数,仅用于测试)
    struct tls_conf conf = {
        .version = TLS_1_2,
        .cipher_type = TLS_CIPHER_AES_GCM_128,
    };
    // 示例密钥和IV(实际场景需从TLS握手流程获取)
    unsigned char key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                             0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    unsigned char iv[12] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
                            0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b};

    conf.rx_key.key = key;
    conf.rx_key.key_len = sizeof(key);
    conf.rx_key.iv = iv;
    conf.rx_key.iv_len = sizeof(iv);
    // 测试用:发送方向复用相同密钥IV,实际场景应使用独立的发送密钥
    memcpy(&conf.tx_key, &conf.rx_key, sizeof(struct tls_key));

    if (setsockopt(sock, SOL_TLS, TLS_CONF, &conf, sizeof(conf)) == -1) {
        perror("tls config");
        exit(EXIT_FAILURE);
    }

    printf("Kernel TLS ULP 启用成功!\n");

    close(sock);
    return EXIT_SUCCESS;
}

步骤3:编译并运行修改后的代码

编译代码:

gcc tls.c -O0 -g

运行(需要sudo权限,因为设置TLS配置需要CAP_NET_ADMIN权限):

sudo ./a.out

如果一切正常,会看到输出:

Kernel TLS ULP 启用成功!

额外注意事项

  • Kernel TLS仅负责对称加密的数据路径,TLS握手过程仍需用户态程序完成(比如用OpenSSL完成握手后,将密钥传递给内核)。
  • 必须拥有CAP_NET_ADMIN权限才能设置TLS配置选项,这也是需要sudo运行的原因。
  • Fedora 30/31的默认内核通常已开启CONFIG_TLS,如果未开启,需要安装内核源码重新编译,或更换支持该功能的内核包。

内容的提问来源于stack exchange,提问作者lukash256

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:51:37