fix the terminologies, add more content

This commit is contained in:
Baohua Yang 2014-09-17 16:31:25 +08:00
parent 7f5c1acf09
commit 22afe36b0f
9 changed files with 58 additions and 40 deletions

View File

@ -5,4 +5,4 @@ Jérôme Petazzoni 创建了一个叫pipework的shell脚本来帮助我们在复
https://github.com/brandon-rhodes/fopnp/tree/m/playground https://github.com/brandon-rhodes/fopnp/tree/m/playground
Brandon Rhodes创建了一个完整的docker容器网络拓扑包含 nat 防火墙服务包括HTTP, SMTP, POP, IMAP, Telnet, SSH, and FTP: Brandon Rhodes创建了一个完整的docker容器网络拓扑包含 nat 防火墙服务包括HTTP, SMTP, POP, IMAP, Telnet, SSH, and FTP:
工具使用的网络命令跟我们之前看到非常相似。 工具使用的网络命令跟之前看到非常相似。

View File

@ -1,15 +1,15 @@
##创建一个点到点连接 ##创建一个点到点连接
默认docker会将所有容器连接到由docker0提供的虚拟子网你也可以使用自己创建的网桥。但如果你想要2个特殊的容器之间可以直连通信而不用去配置复杂的主机网卡桥接。 默认Docker会将所有容器连接到由docker0提供的虚拟子网你也可以使用自己创建的网桥。但如果你想要2个特殊的容器之间可以直连通信而不用去配置复杂的主机网卡桥接。
解决办法很简单创建一对接口把2个容器放到这对接口中配置成点到点链路类型。这2个容器就可以直接通信了。配置如下
解决办法很简单创建一对接口把2个容器放到这对接口中配置成点到点链路类型。这2个容器就可以直接通信了。首先启动2个容器
``` ```
# 在2个终端中启动2个容器
$ sudo docker run -i -t --rm --net=none base /bin/bash $ sudo docker run -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/# root@1f1f4c1f931a:/#
$ sudo docker run -i -t --rm --net=none base /bin/bash $ sudo docker run -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/# root@12e343489d2f:/#
``` ```
找到他们的process IDs ,然后创建他们的 namespace entries 找到他们的进程号,然后创建他们的 namespace entries
``` ```
$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a $ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
2989 2989
@ -34,7 +34,7 @@ $ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 3004 ip link set B up $ sudo ip netns exec 3004 ip link set B up
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B $ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B
``` ```
现在这2个容器就可以相互ping通并成功建立连接。点到点链路不需要子网和子网掩码使用ip route 来连接单个ip地址到指定的网络接口。 现在这2个容器就可以相互ping通并成功建立连接。点到点链路不需要子网和子网掩码使用`ip route`来连接单个ip地址到指定的网络接口。
如果没有特殊需要你不需要指定--net=none来创建点到点链路。 如果没有特殊需要你不需要指定`--net=none`来创建点到点链路。
还有一个办法就是创建一个只跟主机通信的容器,除非有特殊需求,你可以仅用--icc=false来限制主机间的通信。 还有一个办法就是创建一个只跟主机通信的容器,除非有特殊需求,你可以仅用`--icc=false`来限制主机间的通信。

View File

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

View File

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

View File

@ -1,11 +1,16 @@
##Docker Daemon Attack Surface ##Docker Daemon Attack Surface
运行一个容器或则应用程序意味着运行一个docker 服务。docker服务要求root权限所以你需要了解一些重要的细节。 运行一个容器或则应用程序意味着运行一个Docker 服务。Docker服务要求root权限所以你需要了解一些重要的细节。
首先确保只有可信的用户可以访问docker服务因为这会直接导致很严重的后果。因为docker允许你在主机和容器之间共享文件夹这就容易让容器突破资源限制。比如当你在启动容器的时候将主机的/映射到容器的/host目录中那么容器就可以对主机做任何更改了。这听起来很疯狂不过你要知道几乎所有虚拟机系统都有在物理主机和虚拟机之间共享资源的限制所以需要你自己来考虑这一层的安全性。
比如当你使用一个web api来提供容器创建服务时要比平常更加注意参数的检查防止恶意的用户用精心准备的参数来创建带有任意参数的容器 首先确保只有可信的用户可以访问docker服务因为这会直接导致很严重的后果。因为Docker允许你在主机和容器之间共享文件夹这就容易让容器突破资源限制。比如当你在启动容器的时候将主机的/映射到容器的/host目录中那么容器就可以对主机做任何更改了。这听起来很疯狂不过你要知道几乎所有虚拟机系统都有在物理主机和虚拟机之间共享资源的限制所以需要你自己来考虑这一层的安全性。
比如当你使用一个web api来提供容器创建服务时要比平常更加注意参数的检查防止恶意的用户用精心准备的参数来创建带有任意参数的容器。
因此REST API在docker0.5.2之后使用unix socket替代了绑定在127.0.0.1上的tcp socket后者容易遭受跨站脚本攻击。现在你可以使用增强的unix sockt权限来限制对控制socket的访问。 因此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. 你依然可以将REST API发布到http服务上。不过一定要小心确认这里的安全机制确保只有可信的网络或则vpn或则受保护的stunnel和ssl认证可以对REST API进行访问。还可以使用https和认证HTTPS and certificates.
最近改进的linux namespace将很快可以实现使用非root用户来运行全功能的容器。这解决了因在容器和主机共享文件系统而引起的安全问题。 最近改进的linux namespace将很快可以实现使用非root用户来运行全功能的容器。这解决了因在容器和主机共享文件系统而引起的安全问题。
docker的终极目标是改进2个安全特性
Docker的终极目标是改进2个安全特性
* 将root用户的容器映射到主机上的非root用户减轻容器和主机之间因权限提升而引起的安全问题 * 将root用户的容器映射到主机上的非root用户减轻容器和主机之间因权限提升而引起的安全问题
* 允许docker服务在非root权限下运行委派操作请求到那些经过良好审计的子进程每个子进程拥有非常有限的权限虚拟网络设定文件系统管理、配置等等。 * 允许Docker服务在非root权限下运行委派操作请求到那些经过良好审计的子进程每个子进程拥有非常有限的权限虚拟网络设定文件系统管理、配置等等。
最后如果你在一个服务器上运行docker建议去掉docker之外的其他服务除了一些管理服务比如ssh 监控和进程管理工具nrpe clllectd等等。 * 最后如果你在一个服务器上运行Docker建议去掉Docker之外的其他服务除了一些管理服务比如ssh 监控和进程管理工具nrpe clllectd等等。

View File

@ -1,6 +1,8 @@
##Linux Kernel Capabilities ##内核权限
默认情况下docker启动的容器只严格使用一部分内核capabilities。这代表什么呢 默认情况下Docker启动的容器只严格使用一部分内核capabilities。这代表什么呢
这是一个root或非root 二分法粒度管理的访问控制系统。比如web服务进程只需要绑定一个低于1024的端口不需要用root来允许那么它只需要给它授权net_bind_service功能就可以了。还有很多其他的capabilities几乎所有需要root权限的仅需要指定一个部分capabilities就可以了。
这是一个root或非root二分法粒度管理的访问控制系统。比如web服务进程只需要绑定一个低于1024的端口不需要用root来允许那么它只需要给它授权net_bind_service功能就可以了。还有很多其他的capabilities几乎所有需要root权限的仅需要指定一个部分capabilities就可以了。
这对容器的安全有很多好处通常的服务器需要允许一大堆root进程通常有ssh cron syslogd模块和网络配置工具等等。容器则不同因为大部分这种人物都被容器外面的基础设施处理了 这对容器的安全有很多好处通常的服务器需要允许一大堆root进程通常有ssh cron syslogd模块和网络配置工具等等。容器则不同因为大部分这种人物都被容器外面的基础设施处理了
* ssh可以被主机上ssh服务替代 * ssh可以被主机上ssh服务替代
* 硬件管理也无关紧要容器中也就无需执行udevd或则其他类似的服务 * 硬件管理也无关紧要容器中也就无需执行udevd或则其他类似的服务
@ -14,4 +16,6 @@
* 还有一些其他的 * 还有一些其他的
就算攻击者在容器中取得了root权限他能做的破坏也少了也不能获得主机的更高权限。 就算攻击者在容器中取得了root权限他能做的破坏也少了也不能获得主机的更高权限。
然而这不会影响普通的web apps恶意的用户会想各种办法来对你默认情况下docker丢弃了它需要的功能之外的其余部分。这里有一个白名单和黑名单在 Linux manpages可以看到完整的清单列表。当然你还可以启用你需要的额外capabilities。默认docker容器仅使用白名单的内capabilities。 然而这不会影响普通的web apps恶意的用户会想各种办法来对你
默认情况下docker丢弃了它需要的功能之外的其余部分。这里有一个白名单和黑名单在 Linux manpages可以看到完整的清单列表。当然你还可以启用你需要的额外权限。默认Docker容器仅使用白名单的内capabilities。

View File

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

View File

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

View File

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