从 Kubernetes 中部署的容器执行跟踪路由时不允许进行操作 [Linux 功能]

sco*_*omb 6 docker kubernetes

为了尝试了解 Kubernetes 中的安全上下文和功能,我创建了以下 pod 描述:

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  securityContext:
    runAsUser: 1000
  containers:
  - name: busy
    image: busybox
    command:
     - sleep
     - "3600"
    securityContext:
      runAsUser: 2000
      capabilities : 
        add: ["NET_ADMIN", "SYS_TIME"]
Run Code Online (Sandbox Code Playgroud)

我在其中添加 NET_ADMIN 和 SYS_TIME 功能。

给定 Linux 功能手册页: http://man7.org/linux/man-pages/man7/capability.7.html

我希望能够执行跟踪路由或设置日期:

$ kubectl exec -it app -- traceroute google.fr
traceroute: socket: Operation not permitted
command terminated with exit code 1

$ kubectl exec -it app -- /bin/sh date --set="10:00:00"
date: can't set date: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

由于设置了正确的功能,我发现奇怪的是不允许这些操作。这实际上是预期的吗?

Pjo*_*erS 2

在您的示例中,您使用的是Busybox

BusyBox 的磁盘大小在 1 到 5 Mb 之间(取决于变体),是制作节省空间的发行版的一个非常好的成分。BusyBox将许多常见 UNIX 实用程序的微型版本组合到一个小型可执行文件中。它提供了您通常在 GNU fileutils、shellutils 等中找到的大多数实用程序的替代品。BusyBox 中的实用程序通常比其全功能的 GNU 同类程序具有更少的选项;然而,其中包含的选项提供了预期的功能,并且行为与 GNU 对应选项非常相似。BusyBox 为任何小型或嵌入式系统提供了相当完整的环境。

我已经尝试在许多不同的场景中实现你想要的。老实说,您在这里选择测试的示例securityContext并不是最好的。我将发布非常详细的信息为什么。

要在 busybox 上运行跟踪路由或设置日期,您需要正确的privileges. 如果您使用默认的 busybox pod 和root如下例所示的权限,它将按预期工作。

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: busy
    image: busybox
    command:
     - sleep
     - "3600"

$ kubectl exec -ti app -- traceroute bbc.com
traceroute to bbc.com (151.101.128.81), 30 hops max, 46 byte packets
 1  10.32.1.1 (10.32.1.1)  0.006 ms  0.007 ms  0.003 ms
 2  216.239.48.36 (216.239.48.36)  5.476 ms  216.239.48.74 (216.239.48.74)  5.361 ms  216.239.48.36 (216.239.48.36)  4.669 ms
 ...
$ kubectl exec -ti app -- ping bbc.com
PING bbc.com (151.101.0.81): 56 data bytes
64 bytes from 151.101.0.81: seq=0 ttl=54 time=6.246 ms
64 bytes from 151.101.0.81: seq=1 ttl=54 time=6.081 ms
Run Code Online (Sandbox Code Playgroud)

要运行跟踪路由,您需要sudo特权`。有关详细信息,请查看busybox 上有关 Traceroute 的文档。

正如Kubernetes 文档中有关 securityContext 中提到的,您在 YAML 配置中设置了:

echo 'apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  securityContext:
    runAsUser: 1000 ## All containers in this pod will be run as user 1000
  containers:
  - name: busy
    image: busybox
    command:
     - sleep
     - "3600"
    securityContext:
      runAsUser: 2000 ## as you specified here, as default you will enter to this container as user with ID 2000
      capabilities : 
        add: ["NET_ADMIN", "SYS_TIME"]
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,您设置了runAsUser: 1000这意味着该 pod 中的每个容器默认将以用户 1000 身份登录。在 下container spec,您设置了runAsUser: 2000这意味着该特定容器,默认将以用户 2000 身份登录。

要解释是谁,user 1000请查看此文档。简而言之这个数字是

请注意 root 用户的 UID 为 0。大多数 Linux 发行版保留前 100 个 UID 供系统使用。新用户分配的UID从500或1000开始。例如,Ubuntu中的新用户从1000开始

接下来我要提的是Linux capabilities

BusyBox 的输出:

$ kubectl exec -ti app /bin/sh
/ # capsh --print
/bin/sh: capsh: not found
Run Code Online (Sandbox Code Playgroud)

Ubuntu 的输出:

$ kubectl exec -ti ubuntu /bin/bash
root@ubuntu:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
...
root@ubuntu:/# capsh --print
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Run Code Online (Sandbox Code Playgroud)

如果您想使用功能,则无法使用Busybox. traceroute如果您想了解有关linxu 的更多信息,请查看此链接

作为最后一次使用测试,traceroute我在容器中创建了随机用户。

Ubuntu(默认的ubuntu镜像没有traceroute,需要安装它。apt-get update更新存储库,然后apt-get install traceroute

$ kubectl exec -ti ubuntu /bin/sh
# whoami
root
# traceroute bbc.com
traceroute to bbc.com (151.101.0.81), 30 hops max, 60 byte packets
 1  10.32.1.1 (10.32.1.1)  0.032 ms  0.008 ms  0.007 ms
 2  209.85.253.197 (209.85.253.197)  6.294 ms 216.239.48.74 (216.239.48.74)  5.613 ms 216.239.48.36 (216.239.48.36)  5.335 ms
# useradd -m test    
# passwd test
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
# su test
$ whoami
test
$ id  
uid=1000(test) gid=1000(test) groups=1000(test)
$ traceroute bbc.com
traceroute to bbc.com (151.101.64.81), 30 hops max, 60 byte packets
 1  10.32.1.1 (10.32.1.1)  0.034 ms  0.008 ms  0.008 ms
 2  216.239.48.36 (216.239.48.36)  5.515 ms 216.239.51.111 (216.239.51.111)  5.494 ms 216.239.48.36 (216.239.48.36)  5.591 ms
Run Code Online (Sandbox Code Playgroud)

忙碌盒:

$ kubectl exec -ti app /bin/sh
/ # whoami
root
/ # traceroute bbc.com
traceroute to bbc.com (151.101.192.81), 30 hops max, 46 byte packets
 1  10.32.1.1 (10.32.1.1)  0.005 ms  0.006 ms  0.003 ms
 2  216.239.48.36 (216.239.48.36)  5.453 ms  216.239.48.74 (216.239.48.74)  4.812 ms  209.85.252.4 (209.85.252.4)  6.787 ms
/ # adduser test
Changing password for test
New password:
Retype password:
passwd: password for test changed by root
/ # su test
/ $ whoami
test
/ $ id
uid=1000(test) gid=1000(test) groups=1000(test)
/ $ traceroute bbc.com
traceroute: socket: Operation not permitted
Run Code Online (Sandbox Code Playgroud)

简而言之,要执行tracerouteBusybox您需要拥有root特权。要运行traceroute,ubuntu您必须预先安装traceroute 命令。

关于更改容器日期,请检查此步骤