Add the container security chapter
parent
9e38647231
commit
7699a762ca
|
@ -0,0 +1,5 @@
|
|||
#容器安全
|
||||
评估docker的安全性时,主要考虑3个方面:
|
||||
* 由内核中namespace和cgruoups提供的容器的内在安全
|
||||
* docker程序本身的抗攻击性
|
||||
加固内核安全性来影响容器的安全性
|
|
@ -0,0 +1,3 @@
|
|||
##Control Groups
|
||||
Control Groups 是LXC容器的另外一个关键组件,由它来实现资源的审计和限制。他们提供了很多有用的特性,还可以用来确保每个容器可以公平分享主机的内存、cpu、磁盘IO等资源,更重要的是,它可以保证当一个容器耗尽其中一个资源的时候不会连累主机宕机。
|
||||
尽管他们不阻止容器之间相互访问、处理数据和进程,但他们在防止拒绝服务攻击方面是必不可少的。在多用户的平台比如共有或则私有的paas上更加重要,当某些应用程序表现不好的时候,可以保证一直的uptime和性能。Control Groups 始于2006年,从2.6.24之后被引入。
|
|
@ -0,0 +1,11 @@
|
|||
##Docker Daemon Attack Surface
|
||||
运行一个容器或则应用程序意味着运行一个docker 服务。docker服务要求root权限,所以你需要了解一些重要的细节。
|
||||
首先,确保只有可信的用户可以访问docker服务,因为这会直接导致很严重的后果。因为,docker允许你在主机和容器之间共享文件夹,这就容易让容器突破资源限制。比如当你在启动容器的时候将主机的/映射到容器的/host目录中,那么容器就可以对主机做任何更改了。这听起来很疯狂?不过,你要知道几乎所有虚拟机系统都有在物理主机和虚拟机之间共享资源的限制,所以需要你自己来考虑这一层的安全性。
|
||||
比如,当你使用一个web api来提供容器创建服务时,要比平常更加注意参数的检查,防止恶意的用户用精心准备的参数来创建带有任意参数的容器
|
||||
因此,REST API在docker0.5.2之后使用unix socket替代了绑定在127.0.0.1上的tcp socket(后者容易遭受跨站脚本攻击)。现在你可以使用增强的unix sockt权限来限制对控制socket的访问。
|
||||
你依然可以将REST API发布到http服务上。不过一定要小心确认这里的安全机制,确保只有可信的网络或则vpn或则受保护的stunnel和ssl认证可以对REST API进行访问。还可以使用https和认证HTTPS and certificates.
|
||||
最近改进的linux namespace将很快可以实现使用非root用户来运行全功能的容器。这解决了因在容器和主机共享文件系统而引起的安全问题。
|
||||
docker的终极目标是改进2个安全特性:
|
||||
* 将root用户的容器映射到主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题
|
||||
* 允许docker服务在非root权限下运行,委派操作请求到那些经过良好审计的子进程,每个子进程拥有非常有限的权限:虚拟网络设定,文件系统管理、配置等等。
|
||||
最后,如果你在一个服务器上运行docker,建议去掉docker之外的其他服务,除了一些管理服务比如ssh 监控和进程管理工具nrpe clllectd等等。
|
|
@ -0,0 +1,17 @@
|
|||
##Linux Kernel Capabilities
|
||||
默认情况下,docker启动的容器只严格使用一部分内核capabilities。这代表什么呢?
|
||||
这是一个root或非root 二分法粒度管理的访问控制系统。比如web服务进程只需要绑定一个低于1024的端口,不需要用root来允许:那么它只需要给它授权net_bind_service功能就可以了。还有很多其他的capabilities,几乎所有需要root权限的仅需要指定一个部分capabilities就可以了。
|
||||
这对容器的安全有很多好处,通常的服务器需要允许一大堆root进程,通常有ssh cron syslogd;模块和网络配置工具等等。容器则不同,因为大部分这种人物都被容器外面的基础设施处理了:
|
||||
* ssh可以被主机上ssh服务替代
|
||||
* 硬件管理也无关紧要,容器中也就无需执行udevd或则其他类似的服务
|
||||
* 网络管理也都在主机上设置,除非特殊需求,ifconfig、route、ip也不需要了。
|
||||
|
||||
这意味这大部分情况下,容器完全不需要“真正的”root权限。因此,容器可以运行一个减少的capabilities集,容器中的root也比“真正的root"拥有更少的capabilities,比如:
|
||||
* 完全禁止任何mount操作
|
||||
* 禁止直接访问宿主主机的socket
|
||||
* 禁止访问一些文件系统的操作,比如创建新的设备node等等
|
||||
* 禁止模块加载
|
||||
* 还有一些其他的
|
||||
|
||||
就算攻击者在容器中取得了root权限,他能做的破坏也少了,也不能获得主机的更高权限。
|
||||
然而这不会影响普通的web apps,恶意的用户会想各种办法来对你!默认情况下,docker丢弃了它需要的功能之外的其余部分。这里有一个白名单和黑名单,在 Linux manpages可以看到完整的清单列表。当然,你还可以启用你需要的额外capabilities。默认docker容器仅使用白名单的内capabilities。
|
|
@ -0,0 +1,6 @@
|
|||
##Kernel Namespaces
|
||||
docker容器和lxc容器很相似,他们提供的安全特性也差不多。当你用docker run启动一个容器时,在后台docker 为容器创建了一个namespace和contril groups的集合。
|
||||
Namespaces提供了最初也是最直接的隔离,在容器中运行的进程不会被运行在主机上的进程和容器发现,他们之间相互影响也就小了。
|
||||
每个容器都有自己的网络堆栈,他们不能访问其他容器的sockets接口。不过,如果在主机系统上做了相应的设置,他们还是可以像跟主机交互一样的和其他容器交互通信。当你指定公共端口或则使用links来连接2个容器时,他们就可以相互通信了。(相互ping、udp、tcp都没问题,也可以根据需要设定更严格的策略)从网络架构上来看,所有的容器通过主机的网桥接口相互通信,就像物理机器通过物理交换机通信一样。
|
||||
内核提供的namesapce和私有网络的代码有多成熟?
|
||||
内核namesapce从内核2.6.15之后被引入,距今已经5年了,在很多大型生产系统中被验证。他们的设计和灵感提出的时间更早,openvz项目利用namespace重新封装他们的内核,并合并到主流内核中。openvz最早的版本在2005,所以他们的设计和实现都很成熟。
|
|
@ -0,0 +1,7 @@
|
|||
##其它安全特性
|
||||
Capabilities是现代linux内核提供的诸多安全特性中的一个,docker可以利用现有的如TOMOYO, AppArmor, SELinux, GRSEC来增强安全性。为什么docker当前只启用capabilities,而不介入其他系统。
|
||||
因为这样他就还可以有很多方法来加固docker主机,下面是一些例子。
|
||||
*你可以在内核中加载GRSEC和PAX,这会增加很多安全检查。
|
||||
*你可以使用一些有增强安全特性的发行版的模板,比如带apparmor的模板和redhat系列带selinux dcoker策略,这些模板提供了额外的安全特性。
|
||||
*使用你自己喜欢的访问控制机制来定义你自己的安全策略。
|
||||
像其他添加到docker容器的第三方工具一样(比如网络拓扑和文件系统共享),有很多这样的工具,利用他们可以不用改变docker内核就可以加固现有的docker容器
|
|
@ -0,0 +1,2 @@
|
|||
##结论
|
||||
docker容器默认还是比较安全的,特别是你如果注意在容器中使用非root权限来允许进程的话。你还可以添加额外的比如Apparmor, SELinux, GRSEC等你熟悉的加固方法。最后,如果你对其他容器系统中的安全特性感兴趣,你也可以在docker中实现它,毕竟,所有的东西都已经在内核中了。
|
Loading…
Reference in New Issue