This commit is contained in:
Baohua Yang
2014-09-21 13:50:34 +08:00
parent c184f014ae
commit 49c4143e27
9 changed files with 9 additions and 9 deletions

5
security/README.md Normal file
View File

@@ -0,0 +1,5 @@
#安全
评估Docker的安全性时主要考虑3个方面:
* 由内核中名字空间和控制组提供的容器的内在安全
* Docker程序本身的抗攻击性
* 加固内核安全性来影响容器的安全性

View File

@@ -0,0 +1,4 @@
##控制组
控制组是LXC容器的另外一个关键组件由它来实现资源的审计和限制。他们提供了很多有用的特性还可以用来确保每个容器可以公平分享主机的内存、CPU、磁盘IO等资源更重要的是它可以保证当一个容器耗尽其中一个资源的时候不会连累主机宕机。
尽管他们不阻止容器之间相互访问、处理数据和进程但他们在防止拒绝服务攻击方面是必不可少的。在多用户的平台比如共有或则私有的PaaS上更加重要当某些应用程序表现不好的时候可以保证一直的uptime和性能。控制组始于2006年从2.6.24之后被引入。

16
security/daemon_sec.md Normal file
View File

@@ -0,0 +1,16 @@
##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等等。

View File

@@ -0,0 +1,21 @@
##内核权限
默认情况下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可以看到完整的清单列表。当然你还可以启用你需要的额外权限。默认Docker容器仅使用白名单的内capabilities。

10
security/kernel_ns.md Normal file
View File

@@ -0,0 +1,10 @@
##内核名字空间
Docker容器和LXC容器很相似他们提供的安全特性也差不多。当你用`docker run`启动一个容器时在后台Docker为容器创建了一个名字空间和控制组的集合。
名字空间提供了最初也是最直接的隔离,在容器中运行的进程不会被运行在主机上的进程和容器发现,他们之间相互影响也就小了。
每个容器都有自己的网络堆栈他们不能访问其他容器的sockets接口。不过如果在主机系统上做了相应的设置他们还是可以像跟主机交互一样的和其他容器交互通信。当你指定公共端口或则使用links来连接2个容器时他们就可以相互通信了。相互ping、udp、tcp都没问题也可以根据需要设定更严格的策略从网络架构上来看所有的容器通过主机的网桥接口相互通信就像物理机器通过物理交换机通信一样。
内核提供的名字空间和私有网络的代码有多成熟?
内核名字空间从内核2.6.15之后被引入距今已经5年了在很多大型生产系统中被验证。他们的设计和灵感提出的时间更早openvz项目利用名字空间重新封装他们的内核并合并到主流内核中。openvz最早的版本在2005所以其设计和实现都很成熟。

View File

@@ -0,0 +1,9 @@
##其它内核安全特性
Capabilities是现代linux内核提供的诸多安全特性中的一个Docker可以利用现有的如TOMOYO, AppArmor, SELinux, GRSEC来增强安全性。
为什么Docker当前只启用capabilities,而不介入其他系统。
因为这样就可以有很多方法来加固Docker主机下面是一些例子。
* 可以在内核中加载GRSEC和PAX这会增加很多安全检查。
* 可以使用一些有增强安全特性的发行版的模板比如带apparmor的模板和redhat系列带selinux dcoker策略这些模板提供了额外的安全特性。
* 使用你自己喜欢的访问控制机制来定义你自己的安全策略。
像其他添加到docker容器的第三方工具一样比如网络拓扑和文件系统共享有很多这样的工具利用他们可以不用改变docker内核就可以加固现有的docker容器

4
security/summary.md Normal file
View File

@@ -0,0 +1,4 @@
##结论
Docker容器默认还是比较安全的特别是你如果注意在容器中使用非root权限来允许进程的话。你还可以添加额外的比如Apparmor, SELinux, GRSEC等你熟悉的加固方法。
最后如果你对其他容器系统中的安全特性感兴趣你也可以在Docker中实现它毕竟所有的东西都已经在内核中了。