利用容器逃逸实现远程登录k8s集群节点

playwright自动化项目搭建

某天,

某鱼说要吃瞄,

于是……

李国宝:边缘计算k8s集群SuperEdge初体验

zhuanlan.zhihu.com
图标

照着上一篇文章来说,我这边边缘计算集群有一堆节点。

每个节点都在不同的网络环境下。

他们的共同点都是可以访问内网,

部分是某云学生主机,

部分是跑在家庭网络环境下的虚拟机,

甚至假设中还有一些是树莓派之类的机器。

所以他们另一个共同点是,基本都没有公网IP。

这样一来,我要实现远程登录到某些节点搞事的时候,

只有内网穿透这一条路子了。

使用frp进行内网穿透 – 少数派

sspai.com
图标
https://github.com/fatedier/frp

github.com

内网穿透倒没什么,在公司使用这货长期跑了两年垮大洋穿透也很稳定。

只是…

只是…

只是…

要一台台机器配置一次,要维护一个稳定的公网服务器作为桥接。

就是…麻烦了点。

然后想了下。

当前的kube superedge边缘计算集群本身就实现了4层和7层的内网穿透,

理论上直接使用它的能力也可以做到远程登录的。

于是开始研究了一下怎么实现在只有kubectl环境的机器上,

直接登录k8s容器集群的node节点。

搜了一波之后首先发现的是这个项目。

A kubectl plugin to SSH into Kubernetes nodes using a SSH jump host Pod

github.com
看描述和需求来说,完全符合我的要求。

$ kubectl krew install ssh-jump
照着教程配置好插件,装好环境之后实践了一下。

….

一切都好,就是连不上去。

蛋疼了…

接着又找了一波,发现了一个Redhat老哥的博客。

A consistent, provider-agnostic way to SSH into any Kubernetes node

完美。

Dubbo中的统一契约是如何实现的?

我想要的就是这个。

看了下插件代码。luksa/kubectl-plugins看了下插件代码。

https://github.com/luksa/kubectl-plugins/blob/master/kubectl-ssh

github.com

#!/usr/bin/env bash

set -e

ssh_node() {
  node=$1
  if [ "$node" = "" ]; then
    node=$(kubectl get node -o name | sed 's/node\///' | tr '\n' ' ')
    node=${node::-1}

    if [[ "$node" =~ " " ]]; then
      echo "Node name must be specified. Choose one of: [$node]"
      exit 1
    else
      echo "Single-node cluster detected. Defaulting to node $node"
    fi
  fi

  pod=$(
    kubectl create -o name -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  generateName: ssh-node-
  labels:
    plugin: ssh-node
spec:
  nodeName: $node
  containers:
  - name: ssh-node
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["chroot", "/host"]
    tty: true
    stdin: true
    stdinOnce: true
    securityContext:
      privileged: true
    volumeMounts:
    - name: host
      mountPath: /host
  volumes:
  - name: host
    hostPath:
      path: /
  hostNetwork: true
  hostIPC: true
  hostPID: true
  restartPolicy: Never
EOF
  )

  deletePod() {
    kubectl delete $pod --wait=false
  }
  trap deletePod EXIT

  echo "Created $pod"
  echo "Waiting for container to start..."
  kubectl wait --for=condition=Ready $pod >/dev/null
  kubectl attach -it $pod -c ssh-node

}

ssh_pod() {
  # TODO: improve this
  if [ "$1" == "" ]; then
    echo "Pod name must be specified."
    exit 1
  fi
  kubectl exec -it "$@" bash || (
    echo "Running bash in pod failed; trying with sh"
    kubectl exec -it "$@" sh
  )
}

print_usage() {
  echo "Provider-agnostic way of opening a remote shell to a Kubernetes node."
  echo
  echo "Enables you to access a node even when it doesn't run an SSH server or"
  echo "when you don't have the required credentials. Also, the way you log in"
  echo "is always the same, regardless of what provides the Kubernetes cluster"
  echo "(e.g. Minikube, Kind, Docker Desktop, GKE, AKS, EKS, ...)"
  echo
  echo "You must have cluster-admin rights to use this plugin."
  echo
  echo "The primary focus of this plugin is to provide access to nodes, but it"
  echo "also provides a quick way of running a shell inside a pod."
  echo
  echo "Examples: "
  echo "  # Open a shell to node of a single-node cluster (e.g. Docker Desktop)"
  echo "  kubectl ssh node"
  echo
  echo "  # Open a shell to node of a multi-node cluster (e.g. GKE)"
  echo "  kubectl ssh node my-worker-node-1"
  echo
  echo "  # Open a shell to a pod"
  echo "  kubectl ssh pod my-pod"
  echo
  echo "Usage:"
  echo "  kubectl ssh node [nodeName]"
  echo "  kubectl ssh pod [podName] [-n namespace] [-c container]"
  exit 0
}

if [ "$1" == "--help" ]; then
  print_usage
fi

if [[ "$1" == node/* ]]; then
  ssh_node ${1:5}
elif [ "$1" == "node" ]; then
  ssh_node $2
elif [[ "$1" == pod/* ]]; then
  ssh_pod "$@"
elif [ "$1" == "pod" ]; then
  shift
  ssh_pod "$@"
else
  print_usage
fi


认真看了一下这个脚本。

直呼人才啊。

果然是玩Linux的老哥啊。

牛逼啊。

太牛逼了。

太有趣了。

额。

讲人话。

这个脚本使用busybox镜像启动了容器实例,

通过chroot到 /host + 把宿主机所有文件挂在到容器实例的方式,

实现了在容器实例直接对宿主机系统一对一“Copy”(可能表达不太准确),

进而实现直接在这个容器实例中操作宿主机的所有资源。

是的,所有资源。

是的,所有资源。

是的,所有资源。

着这里直接能看到其他程序的进程,

免密码直接操作其他用户的数据。

所谓,

这就是容器逃逸。

然后….

我们的目的确实也达到了。

通过这种方式确实可以直接实现登录任意一台k8s node节点,

再也不需要密码和授权。

总结。

很好玩。

不明镜像确实有风险。

这个世界一直都不太安全。

参考资料:

docker 容器逃逸漏洞(CVE-2020-15257)风险通告

容器逃逸技术概览 – DockOne.io

rambo1412:容器逃逸技术概览

MyBatis初级实战之六:一对多关联查询

给TA买糖
共{{data.count}}人
人已赞赏
经验教程

痞子衡嵌入式:MCUBootFlasher v3.0发布,为真实的产线操作场景而生

2021-1-21 23:25:00

经验教程

playwright自动化项目搭建

2021-1-21 23:45:00

⚠️
免责声明:根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。 本站为个人博客非盈利性站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途,网站会员捐赠是您喜欢本站而产生的赞助支持行为,仅为维持服务器的开支与维护,全凭自愿无任何强求。本站部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。
无意侵害您的权益,请发送邮件至 momeis6@qq.com 或点击右侧 私信:momeis 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索