当前位置: 首页 > Linux

容器安全皮卡——Rootless容器初探

时间:2023-04-06 22:35:42 Linux

摘要:Docker和Kubernetes已经成为企业IT架构的基础设施,安全的容器运行时越来越受到重视。近日,Docker19.03发布了一项重要特性“RootlessContainer”,在提高容器的安全隔离性和可管理性方面迈出了一大步。最近在Docker19.03中发布了一个重要特性“RootlessContainerSupport”。趁着五一假期,赶紧验证一下。本文参考了ExperimentingwithRootlessDocker的内容,并添加了更多细节和实践内容。Rootless容器背景及架构Docker和Kubernetes已经成为企业IT架构的基础设施,其自身的安全性也越来越受到关注。Docker提供基于Linux操作系统的应用虚拟化能力,通过命名空间和cgroups实现资源隔离和配额约束。DockerEngine是典型的Client-Server结构:DockerClient(TCP/UnixSocket)->DockerDaemon(Parent/ChildProcesses)->Container由于Linux需要特权用户创建命名空间,挂载分层文件系统等,所以Docker守护进程一直以root用户身份运行。这也导致拥有Docker访问权限的用户可以通过连接DockerEngine获取root权限,绕过系统的审计能力对系统进行攻击。这阻碍了容器在某些场景下的应用:例如在高性能计算领域,由于传统的资源管理和调度系统需要非特权用户运行容器,因此社区实现了另一种容器运行时Singularity。Moby社区的AkihiroSuda为DockerEngine和Buildkit贡献了无根容器支持,允许DockerEngine作为非特权用户运行并更好地重用Linux安全系统。注意:目前,rootless容器还处于实验阶段,还不支持cgroups资源控制、apparmor安全配置、checkpoint/restore等能力。目前只有Ubuntu支持rootless模式下的overlayfs。出于安全考虑,该方案尚未得到上游支持。其他操作系统需要使用VFS存储驱动,对性能有一定影响,不适合I/O密集型应用。无根容器有几项核心技术。第一种是使用用户命名空间将容器中的root用户uid/gid映射到宿主机的非特权用户范围。DockerEngine提供了--userns-remapflag来支持相关能力,提高容器的安全隔离。最重要的是,无根容器允许Docker守护进程也可以在重新映射的用户名空间中运行。其次,虽然Linux中的非特权用户可以在用户名空间中创建网络命名空间,并进行iptables规则管理、tcpdump等操作,但是非特权用户无法在宿主机和容器之间创建veth对,这也意味着容器做无法访问外部网络。为了解决这个问题,Akihiro使用用户态网络“SLiRP”,通过TAP设备连接到非特权用户命名空间,为容器提供外部网络连接。其架构如下,相关细节请参考slirp4netns项目环境准备本文在CentOS7.6虚拟机上验证创建用户$useraddmoby$passwdmoby将新用户添加到sudoers组usermod-aGwheelmoby切换为non-特权用户$su-moby$iuid=1000(moby)gid=1000(moby)groups=1000(moby),10(wheel)foruid/gidmappingconfiguration$echo"moby:100000:65536"|sudotee/etc/subuid$echo"moby:100000:65536"|sudotee/etc/subgid安装RootlessDocker$curl-sSLhttps://get.docker.com/rootless|sh如果是第一次安装,需要安装需要的包$curl-sSLhttps://get.docker.com/rootless|sh缺少系统要求。请运行以下命令以安装要求并再次运行此安装程序。或者,可以使用SKIP_IPTABLES=1cat</etc/sysctl.d/51-rootless.confuser.max_user_namespaces=28633EOTsysctl--systemEOF(optional)安装用户态网络协议栈实现slirp4netns:由于yum安装的slirp4netns版本太旧,无法执行,它需要从源代码构建$sudoyuminstallglib2-devel$sudoyumgroupinstall"开发工具"$gitclonehttps://github.com/rootless-c...$cdslirp4netns$./autogen.sh$./configure--prefix=/usr$make$sudomakeinstall安装RootlessDocker成功后,会出现如下提示$curl-sSLhttps://get.docker.com/rootless|未检测到shsystemd,需要手动启动dockerd守护进程/home/moby/bin/dockerd-rootless.sh--experimental--storage-drivervfsDocker二进制文件安装在/home/moby/bin确保设置了以下环境变量(或将它们添加到~/.bashrc):nexportXDG_RUNTIME_DIR=/tmp/docker-1000exportDOCKER_HOST=unix:///tmp/docker-1000/docker.sock验证无根容器执行$exportXDG_RUNTIME_DIR=/tmp/docker-1000$导出DOCKER_HOST=unix:///tmp/docker-1000/docker。sock$/home/moby/bin/dockerd-rootless.sh--experimental--storage-drivervfs然后在另一个窗口执行$exportXDG_RUNTIME_DIR=/tmp/docker-1000$exportDOCKER_HOST=unix:///tmp/docker-1000/docker.sock$dockerversionClient:版本:master-dockerproject-2019-04-29API版本:1.40Go版本:go1.12.4Git提交:3273c2e2内置:2019年4月29日星期一23:39:39OS/Arch:linux/amd64实验:falseServer:引擎:版本:master-dockerproject-2019-04-29API版本:1.40(最低版本1.12)Go版本:go1.12.4Git提交:9a2c263内置:2019年4月29日星期一23:46:23OS/Arch:linux/amd64实验:truecontainerd:Version:v1.2.6GitCommit:894b81a4b802e4eb2a91d1ce216b8817763c29fbrunc:Version:1.0.0-rc7+devGitCommit:029124da7af7360afa781a0234d1b083550f797cdocker-init:Version:0.18.0GitCommit:fec3683$dockerrun-d-p8080:80nginx$curllocalhost:8080使用iperf3进行网络性能测试,启动服务器端$dockerrun-it--rm--name=iperf3-server-p5201:5201networkstatic/iperf3-s测试容器间的网络带宽$SERVER_IP=$(码头检查--格式“{{.NetworkSettings.IPAddress}}"iperf3-server)$echo$SERVER_IP172.17.0.2$dockerrun-it--rmnetworkstatic/iperf3-c$SERVER_IP...-[ID]IntervalTransferBandwidthRetr[4]0.00-10.03sec29.8GBytes25.5Gbits/sec0sender[4]0.00-10.03sec29.8GBytes25.5Gbits/secreceiver测试容器和主机之间的网络带宽(外网访问)$HOST_IP=$(hostname--ip-address)$echo$HOST_IP192.168.1.162$dockerrun-it--rmnetworkstatic/iperf3-c$HOST_IP...-[ID]IntervalTransferBandwidthRetr[4]0.00-10.00sec1011MBytes848Mbits/sec0sender[4]0.00-10.00sec1008MBytes845Mbits/secreceiver可以看出容器之间的通信带宽比较好,但是容器和宿主机的不同网络命名空间之间的通信性能有很大的损失。它采取了在提高Docker/Runc容器的安全隔离性和可管理性方面向前迈进了一大步,可以很好地复用Linux安全体系,配合seccomp、SELinux等安全配置,减少攻击面。社区也提供了一个不需要特权用户的实验版Kubernetes,可以从下面的项目中获取https://github.com/rootless-c...但是,无根容器并不能防止容器的安全风险Linux内核,其网络和存储性能目前很差。它需要优化,需要在特定场景下使用。也期待社区不断提升容器的安全能力和效率,让容器有更广阔的应用场景。