在CoreOS上将私钥安全地分发给Docker
我们开始使用Docker / CoreOS作为我们的基础架构。 我们正在部署EC2。 CoreOS集群由一个自动扩展组pipe理,所以新主机进出。 另外,还有很多。 我试图find一种方法来向所有主机分发一个秘密(私有RSA密钥或对称密码的共享密钥),以便我可以使用它来安全地分发数据库凭证,某些服务的AWS访问密钥等。
我想服从“最小特权原则”。 具体来说,如果我在同一主机上运行的两个不同容器中有两个应用程序,则每个应用程序只能访问应用程序所需的机密。 例如,应用程序A可能有权访问MySQL凭据,应用程序B可能有权访问Dynamo的AWS Access密钥,但A不能访问Dynamo,B无法访问MySQL。
如果我在每个服务器上都有一个秘密,那么这不会很难。 我可以使用像Crypt这样的工具从etcd中读取encryption的configuration数据,然后使用卷映射来select性地将凭据提供给单个容器。
问题是,我怎么安全地把钥匙到主机上。
以下是我考虑的一些事情,以及为什么他们不工作:
- 使用AWSangular色为每个主机授予对encryptionS3存储桶的访问权限。 主机然后可以从那里读取一个共享的秘密。 但是这不起作用,因为S3有一个REST API,Docker不限制networking访问容器有,而且angular色适用于整个主机。 因此,该主机上的任何容器都可以读取S3中的密钥,然后读取etcd(其中也包含不受限制的REST API)中的所有值并对其进行解密。
- 在我的CloudFormation模板中,我可以有一个密钥的参数。 然后embedded到UserData中并分发给所有主机。 不幸的是,任何容器都可以通过元数据服务REST API检索密钥。
- 使用船队向全部主机提交全局单元,并且该单元复制密钥。 但是,容器可以通过它的REST API访问队列,并执行“fleetctl cat”来查看密钥。
- 把密钥放在一个私人回购的容器中。 然后,可以将其作为全局单元分发给所有主机,并且该容器中的应用程序可以将密钥复制到卷装载。 不过,我认为,鉴于私人回购证书,有人可以用标准的networking工具下载容器,并提取密钥(尽pipe有一些努力)。 然后,问题就变成了如何安全地分发.dockercfg和私人回购的凭据,我想我们马上就回到了开始的地方。
基本上,似乎核心问题是,每个东西都有一个REST API,我不知道有什么办法来阻止容器访问某些networking资源。
想法?
如果你愿意把这个秘密保存在AMI中,你可以使用你提到的Crypt解决scheme。 我执行类似如下:
- 生成公钥/私钥对
- 将私钥烘焙到用于自动缩放组的AMI中
- 使用公钥encryption引导脚本,包括秘密
- Base64对encryption的引导脚本进行编码
- 将编码的文本embedded到使用私钥解密的包装脚本中,并将其用作AWS启动configuration的用户数据。
例如,引导脚本可能如下所示:
db="mysql://username:password@somehost:3306/somedb" apikey="some_api_secret_key" docker run --name "first container" -e db=$db -d MyImage MyCommand docker run --name "second container" -e apikey=$apikey -d MyOtherImage MyOtherCommand
要进行encryption,请使用openssl和smime来解决rsautl的低限问题。 假设bootstrap脚本位于/tmp/bootstrap.txt中,它可以像这样被encryption和编码:
$ openssl smime --encrypt -aes256 -binary -outform D -in /tmp/bootstrap.txt /tmp/public.key | openssl base64 -e > /tmp/encrypted.b64
成为用户数据的包装脚本可能如下所示:
#!/usr/bin/env bash -x exec >> /tmp/userdata.log 2>&1 cat << END > /tmp/bootstrap.dat <contents of /tmp/encrypted.b64> END decrypted_blob=$(cat /tmp/bootstrap.dat | openssl base64 -d | openssl smime -decrypt -inform -D binary -inkey /path/to/secret.key eval "${decrypted_blob}" rm /tmp/bootstrap.dat
现在,如果容器访问EC2元数据,他们将看到userdata脚本,但它只是encryption的blob。 私钥在主机上,哪些容器不能访问(理论上)。
另请注意,用户数据大小限制为16KB,因此脚本及其encryption数据必须小于此值。
- 带有Docker,Node和Nginxconfiguration问题的AWS EB
- 我无法使用AWS中托pipe的nodejs连接Docker Remote API
- Nginx,AWS,EB,Docker,TCP Socketconfiguration400个不好的请求
- Docker在Amazon Linux AMI上
- 在EC2上的Dockerregistry
- 把docker图像推到亚马逊ecs仓库
- Elastic Beanstalk多容器Docker环境:在两个API之间redirect请求
- 如何使用Docker for Mac为Docker awslogs驱动程序提供凭据?
- Elastic Beanstalk / Docker – 没有这样的文件或目录package.json