介绍
使用Docker对应用程序和服务进行容器化可以为您提供一些开箱即用的安全优势,但默认的Docker安装仍有一些空间可用于某些与安全相关的配置改进。 互联网安全中心是一个致力于推广互联网安全最佳实践的非盈利组织,它为保护Docker创建了一个逐步检查清单 。 随后,Docker团队发布了一个安全审计工具 - Docker Bench Security for Security - 在Docker主机上运行此清单并标记找到的所有问题。
在本教程中,我们将安装Docker Bench for Security,然后使用它来评估Ubuntu 16.04主机上的默认Docker安装(来自官方Docker存储库)的安全状态。 然后,我们将解决它警告我们的一些问题。
我们的修补程序大多由以下两个配置更新组成:
- 安装
auditd
并为Docker守护进程及其相关文件设置审计规则 - 更新Docker的
daemon.json
配置文件
我们不会详细讨论创建安全容器的细节,我们将只关注本教程中Docker主机安全性的更新。
先决条件
为了完成本教程,您需要以下内容:
- 一个启用了sudo的非root用户的Ubuntu 16.04服务器。 您可以学习如何使用Ubuntu 16.04指南的初始服务器设置进行设置
- 从官方Docker存储库安装Docker,如在Ubuntu 16.04上安装和使用Docker所述 。 请确保通过将非Docker用户添加到Docker组来让他们访问Docker。 这在本教程的第2步中介绍。
第1步 - 安装Docker Bench Security
首先,以非root用户身份登录到Docker主机。
我们将首先使用git
将Docker Bench for Security脚本克隆到服务器,然后直接从克隆的存储库运行脚本。
导航到您的用户可以写入的目录。 在这个例子中,我们将脚本下载到用户的主目录:
cd ~
然后克隆docker-bench-security
Git存储库:
git clone https://github.com/docker/docker-bench-security.git
这将从仓库中提取所有文件,并将它们放置在本地docker-bench-security
目录中。 接下来,进入这个结果目录:
cd docker-bench-security
最后,要执行安全审计,请运行docker-bench-security.sh
脚本:
./docker-bench-security.sh
Output# ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.4
#
# Docker, Inc. (c) 2015-
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker Community Edition Benchmark v1.1.0.
# ------------------------------------------------------------------------------
Initializing Tue Jun 5 18:59:11 UTC 2018
[INFO] 1 - Host Configuration
[WARN] 1.1 - Ensure a separate partition for containers has been created
[NOTE] 1.2 - Ensure the container host has been Hardened
[INFO] 1.3 - Ensure Docker is up to date
[INFO] * Using 18.03.1, verify is it up to date as deemed necessary
. . .
该脚本运行各种测试,并为每个测试提供INFO
, NOTE
, PASS
或WARN
结果。 Ubuntu 16.04上默认的Docker安装会通过许多这些测试,但会在第1,2和4节中显示一些警告。
在本教程的其余部分中,我们将通过确保Docker安装来解决这些警告。
第2步 - 更正主机配置警告
审计的第一部分测试主机操作系统的配置,包括其加固,软件包版本和审计配置。 让我们看看本节中的测试:
1.1确保为容器创建了单独的分区
为确保适当的隔离,将Docker容器和/var/lib/docker
全部保留在它们自己的文件系统分区上是一个好主意。 在某些您可能无法分区驱动器的云托管环境中,这可能很困难。 在这些情况下,您可以通过将Docker的数据目录移动到外部网络连接的块设备来满足此测试。
- 要了解如何分区驱动器,请参阅如何在Linux中分区和格式化存储设备 。
- 要将块存储设备安装到DigitalOceanDroplet,请阅读 。
- 要了解如何在其他云平台上安装块存储设备,请参阅提供商的文档。
1.2确保容器主机已经加固
这个测试只是提醒你考虑强化你的主机。 加固通常包括设置防火墙,锁定各种服务,设置审计和记录以及实施其他安全措施。 您可以通过阅读7安全措施来保护您的服务器开始 。
1.3确保Docker是最新的
这个测试打印出你的Docker版本。 您可以通过访问Docker CE发行说明来检查哪个版本是当前的稳定版本。 如果您没有及时更新,并且您使用apt-get install
来安装Docker,则可以再次使用apt-get
来升级Docker包:
sudo apt-get update
sudo apt-get upgrade
1.4确保只有受信任的用户才能控制Docker守护进程
在先决条件Docker设置教程中,我们将我们的非root用户添加到docker组中,以使其可以访问Docker守护程序。 该测试从/etc/group
文件输出docker组的行:
Outputdocker:x:999:sammy
此行显示Docker窗组中包含的所有用户。 查看该行并确保只有合适的用户才有权控制Docker守护进程。 在上面的例子中,我们的授权用户sammy被突出显示。 要从该组中删除用户,可以使用gpasswd
:
gpasswd -d username docker
1.5-1.13确保为各种Docker文件配置审计
我们需要安装和配置auditd
以启用对某些Docker文件,目录和套接字的审计。 Auditd是一个Linux访问监控和记帐子系统,可在内核级别记录值得注意的系统操作。
用apt-get
安装auditd
:
sudo apt-get install auditd
这将安装并启动auditd
守护进程。 我们现在将配置auditd
来监视Docker文件和目录。 在文本编辑器中,打开审计规则文件:
sudo nano /etc/audit/audit.rules
您应该看到以下文字:
# This file contains the auditctl rules that are loaded
# whenever the audit daemon is started via the initscripts.
# The rules are simply the parameters that would be passed
# to auditctl.
# First rule - delete all
-D
# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 320
# Feel free to add below this line. See auditctl man page
将以下代码片段粘贴到文件底部,然后保存并退出编辑器:
-w /usr/bin/docker -p wa
-w /var/lib/docker -p wa
-w /etc/docker -p wa
-w /lib/systemd/system/docker.service -p wa
-w /lib/systemd/system/docker.socket -p wa
-w /etc/default/docker -p wa
-w /etc/docker/daemon.json -p wa
-w /usr/bin/docker-containerd -p wa
-w /usr/bin/docker-runc -p wa
这些规则指示auditd监视( -w
)指定的文件或目录,并将任何写入或属性更改( -p wa
)记录到这些文件。
重新启动auditd
以使更改生效:
sudo systemctl restart auditd
此时,您已成功配置auditd
以查看Docker文件和目录中是否存在可疑更改。 您可以重新运行Docker Bench for Security脚本以确认第1部分中的测试通过。
有关auditd
更多信息,可以阅读我们的教程如何在CentOS 7上使用Linux审计系统 。 尽管是为CentOS编写的,但配置和使用审计系统的部分同样适用于Ubuntu。
现在我们已经验证了我们的主机配置,接下来我们将继续讨论Docker安全审计的第2部分,即Docker守护程序配置。
第3步 - 更正Docker守护程序配置警告
审计的这一部分涉及Docker守护程序的配置。 这些警告都可以通过为守护进程创建一个名为daemon.json
的配置文件来daemon.json
,我们将添加一些与安全相关的配置参数。 我们将首先创建并保存该配置文件,然后逐个检查配置中的测试和相应行。
首先,在您最喜欢的编辑器中打开配置文件:
sudo nano /etc/docker/daemon.json
这会给你一个空白的文本文件。 粘贴在以下内容中:
{
"icc": false,
"userns-remap": "default",
"log-driver": "syslog",
"disable-legacy-registry": true,
"live-restore": true,
"userland-proxy": false,
"no-new-privileges": true
}
保存并关闭该文件,然后重新启动Docker守护进程,以便获取此新配置:
sudo systemctl restart docker
您现在可以重新运行审计,以确认所有第2部分的警告都已解决。
我们插入到这个文件中的配置变量按照与审计警告相同的顺序排列。 让我们来看看它们中的每一个:
2.1确保默认网桥上的容器之间的网络流量受到限制
此警告通过配置文件中的"icc": false
来解决。 此配置创建的容器只能在使用Docker命令行上的--link= container_name
或Docker Compose配置文件中的links:
参数明确链接时彼此进行通信。 其中一个好处是,如果攻击者损害了一个容器,他们将很难在同一主机上查找和攻击其他容器。
2.8启用用户名称空间支持
Linux命名空间为在容器中运行的进程提供额外的隔离。 用户名称空间重新映射允许进程在容器中作为root运行,同时被重新映射到主机上权限较低的用户。 我们使用配置文件中的"userns-remap": "default"
行来启用用户名称空间重新映射。
我们将该参数设置为default
,这意味着Docker将创建一个dockremap用户,将容器用户重新映射到该用户。 您可以验证是否使用id
命令创建了dockremap用户:
sudo id dockremap
您应该看到类似于以下内容的输出:
Outputuid=112(dockremap) gid=116(dockremap) groups=116(dockremap)
如果将容器用户重新映射到其他主机用户对于您的用例更有意义,请在配置文件中指定用户或user:group
组合组合来代替default
。
警告:用户重新映射是一项强大的功能,如果配置不当,可能会导致中断和破坏,因此强烈建议您阅读官方文档,并在生产环境中实施此更改之前了解其含义。
2.11确保已启用对Docker客户端命令的授权
如果您需要允许网络访问Docker套接字,则应查阅官方Docker文档以了解如何安全设置必要的证书和密钥。
我们不会在这里介绍这个过程,因为具体情况在很大程度上取决于个人情况。 审计将继续将此测试标记为WARN
,尽管只需要访问默认的仅限本地的Docker套接字即可通过需要Docker窗组中的成员资格来保护,因此可以安全地忽略它。
2.12确保配置了集中和远程日志记录
在Docker守护进程配置文件中,我们使用"log-driver": "syslog"
行启用了标准syslog日志记录。 然后,您应该配置syslog以将日志转发到集中式syslog服务器。 这会从Docker主机中注销并远离任何可能更改或删除它们的攻击者。
如果您只想转发Docker日志并且不想发布系统日志,则可以通过将以下参数附加到文件中来指定Docker配置文件中的远程系统日志服务器:
`"log-opts": { "syslog-address": "udp://198.51.100.33:514" }`
请务必用您自己的系统日志服务器地址替换IP地址。
或者,您可以指定像splunk
或fluentd
这样的日志驱动程序,以使用其他日志聚合服务来发送Docker守护程序日志。 有关Docker日志驱动程序及其配置的更多信息, 请查阅官方的Docker日志驱动程序文档 。
2.13确保遗留注册表(v1)上的操作已禁用
此警告已通过守护进程配置文件中的"disable-legacy-registry": true
行修复。 这将禁用不安全的传统映像注册表协议。 由于对此协议的支持已从Docker守护程序中删除,因此此标志正在被弃用。
2.14确保活动恢复已启用
通过在守护进程配置中指定"live-restore": true
,当Docker守护进程不在时,我们允许容器继续运行。 这改进了主机系统更新期间的容器正常运行时间和其他稳定性问题。
2.15确保Userland Proxy已禁用
"userland-proxy": false
行修复了此警告。 这会禁用docker-proxy
userland进程,默认情况下,该进程会将主机端口转发到容器,并将其替换为iptables
规则。 如果发夹式NAT可用,则不需要用户级代理,应禁用该代理以减少主机的攻击面。
2.18确保容器被限制获取新的权限
守护进程配置中的"no-new-privileges": true
行阻止了容器内的特权升级。 这确保容器不能使用setuid
或setgid
二进制文件获得新的权限。
现在我们已经更新了Docker守护进程配置,让我们在第四部分的审计中修复剩下的警告。
第4步 - 启用内容信任
我们审计标记的最终测试是4.5 Ensure Content trust for Docker is Enabled
。 内容信任是一种系统,用于在运行它们之前签署Docker映像并验证它们的签名。 我们可以使用DOCKER_CONTENT_TRUST
环境变量启用内容信任。
要为当前shell会话设置此变量,请在shell中键入以下内容:
export DOCKER_CONTENT_TRUST=1
在此export
命令之后运行审核应显示内容信任已启用并清除此警告。 要为所有用户和所有会话自动启用它,请将DOCKER_CONTENT_TRUST
变量添加到/etc/environment
文件中,该文件是用于分配系统范围环境变量的文件:
echo "DOCKER_CONTENT_TRUST=1" | sudo tee -a /etc/environment
有关Docker Content trust的更多信息可以在官方的Docker Content信任文档中找到 。
此时,我们已经解决了由Docker Bench for Security脚本标记的所有警告。 我们现在有一个更安全的Docker主机来运行容器。
结论
在本教程中,我们安装了Docker Bench for Security脚本,用它来审计Docker安装的安全性,并通过安装和配置auditd
以及Docker守护程序的配置文件来解决警告。
完成本教程后,运行审计脚本应该会导致很少的错误或警告。您还应该了解并有理由忽略那些持续存在的问题。
有关Docker安全性配置选项的更多信息,请参阅Docker文档,并查看本教程中已包含的文档特定小节的链接。