首页 > 解决方案 > 即使设置 cap_net_raw 也无法在 linux 容器中打开原始套接字

问题描述

我正在运行一个代码,该代码在 docker 容器内打开一个原始套接字,其中 kubernetes 作为协调器。

以下是我的示例代码:

#include <stdio.h>  
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>

int main (void)
{  
        //Create a raw socket
        int s = socket (AF_INET, SOCK_RAW, IPPROTO_SCTP);

        if(s == -1)
        {
                perror("Failed to create socket");
                exit(1);
        }

}

在我的容器/pod 中以非 root 用户身份运行代码时,出现此错误。

./rawSocTest
Failed to create socket: Operation not permitted

这很明显,因为它需要 root 级别的权限才能打开原始套接字。我通过设置能力 cap_net_raw 纠正了这一点。

getcap rawSocTest
rawSocTest = cap_net_raw+eip

现在当我再次运行它时。我得到一个不同的错误。

./rawSocTest
bash: ./rawSocTest: Permission denied

据我了解,设置功能应该可以解决我的问题。我在这里错过了什么吗?或者这是容器的已知限制吗?

提前致谢。

标签: clinuxdockerkubernetesraw-sockets

解决方案


我解决了。我需要在 Kubernetes 部署的容器的安全上下文部分中设置功能。我添加了 NET_RAW 功能以允许创建原始套接字。我的印象是,只需在构建过程中添加能力 cap_net_raw 就足够了。但事实证明我的理解是错误的。

我做了一些研究并清理了部署解决方案。我在我的 pod 安全策略的允许功能部分添加了 NET_RAW。然后创建了角色和角色绑定。通过角色绑定将其链接到将部署我的 pod 的命名空间中的服务帐户。然后在 pod 部署中使用了这个 serviceAccount。不确定这是否是一个好的解决方案。


推荐阅读