K8s中非root用户修改MAC地址
2023-02-20 00:05:11 +08 字数:1166 标签: Linux Docker K8s因业务需要,程序要修改MAC地址,并且开关K8s中Pod的网络。
虽然root
用户可以轻松实现这一点,但考虑到安全因素,更应该使用普通用户。
通过使用Linux的Capabilities功能,对/bin/ip
进行cap_net_admin
授权,可以实现MAC修改功能。
注意:K8s集群中,Pod的网络是否可开关,取决于网络插件。 已知flannel可以,calico不行。 以下涉及K8s的内容,都只在flannel下确保生效。
基本操作 ¶
安装 ¶
虽然ip
这个命令,通常会默认安装。
但如果实在没有,就需要手动安装。
sudo apt install iproute2
基本网络操作 ¶
关闭名称为<name>
的网络:
sudo ip link set dev <name> down
修改Mac,格式应该满足XX:XX:XX:XX:XX:XX
:
sudo ip link set dev <name> address XX:XX:XX:XX:XX:XX
打开网络:
sudo ip link set dev <name> up
查看新的MAC地址:
ip link show <name>
基本capabilities ¶
添加cap_net_admin
:
sudo setcap cap_net_admin+ep /bin/ip
查看:
$ getcap /bin/ip
/bin/ip = cap_net_admin+ep
删除所有:
sudo setcap -r /bin/ip
容器验证 ¶
在容器中,无论是Docker还是Kubernetes都对Capabilities做出了限定。
除了配置setcap
外,还需要在运行时额外赋予权限。
Docker ¶
基于以下Dockerfile,可以制作验证镜像cap:latest
:
FROM debian:bullseye
RUN useradd -m octopus -s /bin/bash \
&& setcap cap_net_admin+ep /bin/ip
USER octopus
CMD ["/bin/ip", "link", "show"]
构建完成后,在默认模式下运行,仍然会缺少授权。
$ docker build -t cap .
$ docker run --rm cap
standard_init_linux.go:219: exec user process caused: operation not permitted
这是因为Docker在运行时对Capabilities做了限制。
需要使用--cap-add
参数,放开具体的限制。
$ docker run --rm --cap-add=cap_net_admin cap
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
43: eth0@if44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 01:xx:xx:xx:xx:ef brd ff:ff:ff:ff:ff:ff link-netnsid 0
以上MAC地址01:xx:xx:xx:xx:ef
做了匿名化处理。
Kubernetes ¶
在Kubernetes中,虽然共用了同一个镜像,但是却是使用不同的runtime。
因此配置方式会略有不同。
以下是一个可以运行的job.yaml
示例。
---
apiVersion: batch/v1
kind: Job
metadata:
name: cap
spec:
backoffLimit: 0
template:
spec:
activeDeadlineSeconds: 300
restartPolicy: Never
containers:
- name: cap
image: cap
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add: ["NET_ADMIN"]
args:
- 'sh'
- '-c'
- >
/bin/ip link show eth0;
/bin/ip link set dev eth0 down;
/bin/ip link set dev eth0 address 01:xx:xx:xx:xx:ef;
/bin/ip link show eth0;
/bin/ip link set dev eth0 up;
/bin/ip link show eth0;
执行kubectl apply -f job.yaml
后,等待运行完成。
通过日志,可以确认修改生效。
结论 ¶
以上方案,无需root
权限,最小化授权,安全可信。
但是,开关网络、改变MAC等功能,只在部分网络插件下有效,比如flannel。
另外,充分利用Linux本身的Capability能力,可以让很多其它root才能做的的功能,在普通用户、用指定可执行二进制文件实现。
参考 ¶
- capabilities(7) - Linux manual page
- 为 Pod 或容器配置安全性上下文 | Kubernetes
- Network - Configuration | Ubuntu
- Docker security | Docker Documentation
- Runtime privilege and Linux capabilities
- How to Change MAC Address in Linux
- 在 Kubernetes 中配置 Container Capabilities-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生