社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

手把手搭建 k8s docker 漏洞环境

系统安全运维 • 3 年前 • 423 次点击  

一、前言

此环境为复现 docker 以及 k8s 容器逃逸的集成漏洞环境。
涉及以下漏洞:
1、docker privileged 特权模式
2、参数SYS_ADMIN导致cgroup逃逸
3、proc挂载
4、docker remote api 未授权
5、挂载sock文件
6、脏牛内核逃逸(此条划掉,没符合漏洞版本的linux,而且在实战中这个漏洞也很少遇到,大家直接靶场lampiao复现一下这个洞就可以)
7、1day runc
8、k8s鉴权配置不当
9、k8s日志挂载
10、k8s账户权限配置不当

二、准备工作

使用huawei欧拉服务器V2.0 SP5
https://euleros2019.obs.cn-north-1.myhuaweicloud.com/ict/site-euleros/euleros/repo/yum/2.5/os/x86_64/iso/EulerOS-V2.0SP5-x86_64-dvd.iso
准备两台服务器(虚拟机)
master主服务器 192.168.88.180 k8s-master
node节点服务器 192.168.88.181 k8s-node
集群服务器至少2h2g30G
注意事项:
1、查看hostname如果是localhost,请使用以下命令进行修改
hostnamectl set-hostname test101
2、两台服务器的/etc/hosts文件中需添加如下配置
master主机IP 主机名
node节点IP 主机名
3、保持两台机器时间同步
利用date命令查看,不一致使用命令进行同步
ntpdate ntp1.aliyun.com

若更新源没问题,则进行第三步:安装,若有问题则看第四步:遇到的问题及解决方案。

三、安装

1、安装依赖

yum install go
yum install git
yum -y install gcc automake autoconf libtool make

把container-selinux-2.107-3.el7.noarch.rpm、runc.sh、privileged.sh放到两台机器上
http://ftp.riken.jp/Linux/cern/centos/7/extras/x86_64/Packages/container-selinux-2.107-3.el7.noarch.rpm

#runc.sh
#!/bin/bash
#sunian
echo "查找原有libseccomp进行删除"
results=`yum list installed|grep libseccomp`
if test ! -z "$results";then
yum -y remove $results
echo "删除完毕"
else
echo "已删除,进行下一步"
fi
`mkdir -p /home/runc`
`cd /home/runc`
`wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libseccomp-2.3.1-4.el7.x86_64.rpm`
rpm -ivh libseccomp-2.3.1-4.el7.x86_64.rpm
`wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libseccomp-devel-2.3.1-4.el7.x86_64.rpm`
rpm -ivh libseccomp-devel-2.3.1-4.el7.x86_64.rpm
`mkdir -p $HOME/go/src/github.com`
`go get github.com/opencontainers/runc`
cd $HOME/go/src/github.com/opencontainers/runc
git checkout v1.0.0-rc5
echo -e "\033[31m `git status` \033[0m"
make
make install
echo -e "\033[31m `runc -v` \033[0m"

注释:查找原有libseccomp进行删除,从官网下载所需libseccomp和libseccomp-devel进行rpm安装,利用go从github下载带有漏洞版本的runc v1.0.0-rc5并编译。

#privileged.sh
#!/bin/bash
#sunian
echo "查找原有docker进行删除"
results=`yum list installed|grep docker`
if test ! -z "$results";then
yum -y remove $results
echo "删除完毕"
else
echo "已删除,进行下一步"
fi
#开始安装存在漏洞版本docker
echo "创建并安装docker的依赖"
echo "安装在/home/privileged目录下"
mkdir -p /home/privileged
mv /root/container-selinux-2.107-3.el7.noarch.rpm /home/privileged
cd /home/privileged
rpm --force --nodeps -ivh container-selinux-2.107-3.el7.noarch.rpm
`wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-18.06.0.ce-3.el7.x86_64.rpm`
rpm -ivh docker-ce-18.06.0.ce-3.el7.x86_64.rpm
`service docker start`
echo `docker version`
echo -e "\033[31m `docker images` \033[0m"

注释:删除原有的docker,安装docker的依赖 即container-selinux,安装存在漏洞版本的docker,执行docker images并输出,查看是否安装成功。

2、配置k8s及安装

(1)系统设置:

安装nfs以及wget
yum install -y nfs-utils
yum install -y wget
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
关闭selinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
关闭swap分区
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
将桥接的IPv4 IPv6流量传递到iptables的链(直接shell脚本):

# 如果有配置,则修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf
# 可能没有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
# 执行命令以应用
sysctl -p

(2)配置k8s源

cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

(3)安装k8s

yum remove -y kubelet kubeadm kubectl
yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2

sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl restart docker
systemctl enable kubelet && systemctl start kubelet
(到此两台机器都有runc、docker、k8s工具(kubeadm kubectl kubelet))

(4)接下来开始初始化服务器master节点(node服务器无需操作)




    
# 只在 master 节点执行
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=192.168.88.180
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=172.18.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts

创建init_master.sh

#!/bin/bash
# 脚本出错时终止执行
set -e

if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then
echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"
echo 当前POD_SUBNET=$POD_SUBNET
echo 当前APISERVER_NAME=$APISERVER_NAME
exit 1
fi


# 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
cat < ./kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.2
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "${POD_SUBNET}"
dnsDomain: "cluster.local"
EOF

# kubeadm init
# 根据您服务器网速的情况,您需要等候 3 - 10 分钟
kubeadm init --config=kubeadm-config.yaml --upload-certs

# 配置 kubectl
rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config

# 安装 calico 网络插件
# 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises
echo "安装calico-3.13.1"
rm -f calico-3.13.1.yaml
wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml
kubectl apply -f calico-3.13.1.yaml

加权限执行进行初始化,预检有点慢,等一等
之后执行如下命令,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide

节点初始化状态为ready
kubectl get nodes -o wide

至此主机服务器安装完成

(5)配置node节点

在master服务器上获取join命令
kubeadm token create --print-join-command

node节点服务器执行该命令

# 只在 node 节点执行
# 192.168.88.180 为 master 节点的内网 IP
export MASTER_IP=192.168.88.180
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
执行master服务器获取的join命令

最后master服务器执行命令
kubectl get nodes -o wide

查看node节点服务器直到ready,至此安装完成

四、遇到的问题及解决方案

1、若无更新源或源有问题(如 无想要的包),可使用以下更新源

Makefile
在/etc/yum.repos.d/目录下,创建文件EulerOS.repo

[base]
name=EulerOS-2.0SP5 base
baseurl=http://repo.huaweicloud.com/euler/2.5/os/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://repo.huaweicloud.com/euler/2.5/os/RPM-GPG-KEY-EulerOS

执行yum clean all清除原有yum缓存。
执行yum makecache生成新的缓存。
yum update更新

2、go版本的问题,1.16以下的go版本不支持io/fs,但是该报错不影响后续运行

3、若使用centos,期间可能出现的问题:

网络问题,主要是go下载runc时请求github网络问题,解决方案:临时环境变量,使用aliyun go源
export GOPROXY=https://mirrors.aliyun.com/goproxy/

4、如果docker未启动

service docker start

5、10250端口占用

[ERROR Port-10250]: Port 10250 is in use
解决方法:
kubeadm reset

6、修改docker为cgroups或systemd驱动

cat > /etc/docker/daemon.json <{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF

systemctl daemon-reload && systemctl restart docker

7、rpm安装docker缺少依赖

报错如下
libcgroup is needed by docker-ce-18.06.0.ce-3.el7.x86_64
libltdl.so.7()(64bit) is needed by docker-ce-18.06.0.ce-3.el7.x86_64

解决方案:
http://mirror.centos.org/centos/7/os/x86_64/Packages/ 安装以下依赖
libcgroup-0.41-21.el7.x86_64.rpm
libtool-ltdl-2.4.2-22.el7_3.x86_64.rpm

8、nodeRegistration.name: Invalid value

hostname或dnsname不能用下划线,只能用'-'或'.'。

作者:sunian    来源FreeBuf.COM
原文地址: https://www.freebuf.com/vuls/321244.html


推荐↓↓↓
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/130440
 
423 次点击