Coreos 安全

Coreos security

我正在玩 coreos 和 digitalocean,我想开始允许我的容器之间进行内部通信。

我已经为所有主机设置了专用网络,现在我想确保某些容器只打开本地主机和内部接口的端口。

我为此探索了很多选择,但 none 似乎令人满意:

那么最好的方法是什么,我会花时间让它发挥作用。

总的来说,我想我需要找到我能做的事情:

解决方案

我将详细说明我是如何解决这个问题的。感谢 larsks 的帮助。最后,他们的做法是正确的。这在 coreos 上很棘手,因为没有真正稳定的地址,就像 larsks 假设的那样。 coreos 的全部意义在于能够忘记 ip 地址。

我通过找到一种不太糟糕的方法将 ip 地址注入服务文件中的命令来解决这个问题。棘手的是它并不真正支持我期望的许多 shell 功能。我想要做的是将机器的IP地址分配给一个变量,然后将其注入命令:

ip=$(ifconfig eth1 | grep -o 'inet [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*');
/usr/bin/docker run -p $ip:7000:7000 ...

但是,如前所述,这是行不通的。那么该怎么办?获取 shell!

ExecStart=/usr/bin/sh -c "\
     export ip=$(ifconfig eth1 | grep -o 'inet [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*');\
     echo $ip;\
     /usr/bin/docker run -p $ip:7000:7000"

一路上我遇到了一些问题。

  1. 我很确定该命令中没有换行符,所以我必须添加“;”字符
  2. 当你在 shell 中测试上面的 bash -c 命令时,它会产生与 systemd 执行它时截然不同的效果。在 shell 你需要转义 '$' 字符,而在 systemd 配置文件中,你不需要。
  3. 我包含了 echo 以便我可以看到命令认为 ip 是什么。
  4. 当我做这一切时,我实际上在 docker 图像中插入了一个小型网络服务器,这样我就可以使用 curl 进行测试。

这种方法的缺点是它与 ifconfig 的工作方式和 ipv4 相关联。事实上,这种方法不适用于我的 linux mint 笔记本电脑,其中 ifconfig 会生成不同格式的输出。这里重要的一课是在 yaml 或 json 中输出东西,这样 shell json 工具可以更容易地访问东西。

I've got private networking set up for all the hosts, and now I'd like to ensure that some containers only open ports to localhost and to the internal interface.

这正是您在指定 IP 地址时使用 -p 选项获得的行为。假设我的主机有两个外部接口,eth0(地址为 10.0.0.10)和 eth1(地址为 192.168.0.10),docker0 网桥位于 172.17.42.1/ 16.

如果我像这样启动一个容器:

docker run -p 192.168.0.10:80:80 -d larsks/mini-httpd

这将启动一个容器,该容器可通过位于 192.168.0.10、端口 80 的 eth1 接口访问。此服务 可访问 -- 从主机容器所在的位置——在 docker0 网络上分配给容器的地址。这类似于 172.17.0.39,端口 80。

这似乎符合您的目标:

  • 容器端口通过 "private" eth1 接口公开。
  • 容器端口可从主机访问。

I can't easily test services by SSHing in, because that traffic originates from localhost.

如果您在容器内 运行 ssh,您将在 Docker 分配的 "internal" 地址处通过 ssh 连接到它。但是,如果您在容器中使用 运行 ssh,您可能需要考虑 而不是 并依赖 docker exec 等工具。

I need to write somewhat hacky shell scripts to start my services, in order to inject the address of the machine that the container is running on

有了这个方案,就不需要把机器ip注入容器了

您可以使用环境文件来获取安排服务的主机的 IP 地址(public 和私有地址),而不是 grep-ping IP 地址。这允许您以简单的方式将容器端口绑定到 public 或私有端口。

像这样:

[Service]
EnvironmentFile=/etc/environment
ExecStart=/usr/bin/docker run --name myservice -p \
    ${COREOS_PUBLIC_IPV4}:80:80 \
    ${COREOS_PRIVATE_IPV4}:3306:3306 \
    ubuntu /bin/bash