【问题标题】:Not enough entropy to support /dev/random in docker containers running in boot2docker没有足够的熵来支持在 boot2docker 中运行的 docker 容器中的 /dev/random
【发布时间】:2014-09-24 15:45:15
【问题描述】:

在虚拟化 Linux 系统中耗尽熵似乎是一个常见问题(例如/dev/random Extremely Slow?Getting linux to buffer /dev/random)。尽管使用了硬件随机数生成器 (HRNG),但通常建议使用像 HAVEGED 这样的熵收集守护进程。但是熵收集守护进程 (EGD) 不能在 Docker 容器内运行,它必须由主机提供。

对于基于 Ubuntu、RHEL 等 Linux 发行版的 docker 主机,使用 EGD 可以正常工作。让这样的守护进程在基于 Tiny Core Linux (TCL) 的 boot2docker 中运行似乎是另一回事。虽然TCL有一个扩展机制,一个熵收集守护进程doesn't seem to be available的扩展。

因此,EGD 似乎是在(生产)托管环境中运行 docker 容器的合适解决方案,但如何解决它以在 boot2docker 中进行开发/测试?

由于在 boot2docker 中运行 EGD 似乎太难了,所以我考虑过简单地使用 /dev/urandom 而不是 /dev/random。使用 /dev/urandom 的安全性稍差一些,但对于大多数不生成长期加密密钥的应用程序来说仍然可以。至少在 boot2docker 中进行开发/测试应该没问题。

【问题讨论】:

  • openssl 用户urandom。你在做什么需要更多?
  • 一些 Java 加密提供程序在 /dev/random 上中继(例如,用于安全随机数生成)。
  • 我同意你不能总是控制它。无论如何,在这里你有一些关于 java SecureRandom/dev/[u]random - bugs.openjdk.java.net/browse/JDK-4705093 的附加信息

标签: docker boot2docker


【解决方案1】:

我刚刚意识到,将 /dev/urandom 从主机作为 /dev/random 挂载到容器中很简单:

$ docker run -v /dev/urandom:/dev/random ...

结果如预期:

$ docker run --rm -it -v /dev/urandom:/dev/random ubuntu dd if=/dev/random of=/dev/null bs=1 count=1024
1024+0 records in
1024+0 records out
1024 bytes (1.0 kB) copied, 0.00223239 s, 459 kB/s

至少我现在知道如何构建自己的 boot2docker 镜像了 ;-)

【讨论】:

  • 在开发机器上使用 /dev/urandom 而不是 /dev/random 对安全性的影响应该是非常有限的。
  • “事实:/dev/urandom 是类 UNIX 系统上加密随机性的首选来源。” 2uo.de/myths-about-urandom
  • 跨平台兼容性怎么样,即对于那些运行 Windows 的可怜人来说?
  • 我已经尝试了很多rng-tools/haveged 的建议,这是唯一有效的。谢谢!
  • @Claudiu docker-toolbox for Windows 仍然在 linux 上运行,而 docker for Windows 10+ 在 linux 子系统上运行(如果我理解正确的话),那么它应该还能工作吗?
【解决方案2】:

我发现的最优雅的解决方案是在单独的容器中运行 Haveged:

docker pull harbur/haveged
docker run --privileged -d harbur/haveged

检查是否有足够的熵可用:

$ cat /proc/sys/kernel/random/entropy_avail
2066

【讨论】:

    【解决方案3】:

    另一种选择是安装 rng-tools 包并将其映射到使用 /dev/urandom

      yum install rng-tools
      rngd -r /dev/urandom 
    

    有了这个,我不需要在 docker 容器中映射任何卷。

    【讨论】:

    • 这给了我这个消息:unable to adjust write_wakeup_threshold: Read-only file system
    • 在 docker 主机上运行它,而不是在容器中。
    【解决方案4】:

    由于我不想修改我的 Docker 容器以进行开发/测试,因此我尝试修改 boot2docker 映像。幸运的是,boot2docker 镜像是用 Docker 构建的,可以很容易地extended。所以我建立了自己的 Docker 构建 boot2docker-urandom。它使用 here 找到的 udev 规则扩展了标准 boot2docker 映像。

    构建自己的 boot2docker.iso 镜像很简单

    $ docker run --rm mbonato/boot2docker-urandom > boot2docker.iso
    

    要替换 boot2docker 附带的标准 boot2docker.iso,您需要:

    $ boot2docker stop
    $ boot2docker delete
    $ mv boot2docker.iso ~/.boot2docker/
    $ boot2docker init
    $ boot2docker up
    

    限制,来自 Docker 容器 /dev/random 仍然会阻塞。很可能是因为 Docker 容器不直接使用主机的 /dev/random ,而是使用相应的内核设备 - 仍然阻塞。

    【讨论】:

      【解决方案5】:

      Alpine Linux 可能是轻量级docker 主机的更好选择。 Alpine LXC & docker 图片只有 5mb(boot2docker 为 27mb)

      我在Alpine 上为LXC 客人使用haveged,在Debian 上为docker 客人使用。它提供了足够的熵来在容器中生成 gpg / ssh 密钥和 openssl 证书。 Alpine now has an official docker repo.

      或者为 Tiny Core 构建一个 haveged 包 - 有一个 package build system 可用。

      【讨论】:

        【解决方案6】:

        如果您在从运行 java 应用程序的自建镜像创建的 docker 容器中遇到此问题(例如,创建 FROM tomcat:alpine)并且无权访问主机(例如在托管 k8s 集群上),您可以将以下命令添加到您的 dockerfile 以使用 SecureRandom 的非阻塞播种:

        RUN sed -i.bak \
          -e "s/securerandom.source=file:\/dev\/random/securerandom.source=file:\/dev\/urandom/g" \
          -e "s/securerandom.strongAlgorithms=NativePRNGBlocking/securerandom.strongAlgorithms=NativePRNG/g" \
          $JAVA_HOME/lib/security/java.security
        

        这两个正则表达式在文件$JAVA_HOME/lib/security/java.security 中将file:/dev/random 替换为file:/dev/urandom,将NativePRNGBlocking 替换为NativePRNG,这会导致tomcat 在虚拟机上的启动速度相当快。我还没有检查这是否也适用于非基于 alpine 的 openjdk 映像,但如果 sed 命令失败,只需检查容器内文件 java.security 的位置并相应地调整路径。

        注意:在 jdk11 中路径已更改为 $JAVA_HOME/conf/security/java.security

        【讨论】:

        • 太基础了,这种技术不适用于 openjdk11,因为 java.security 文件不存在。
        • @ArchimedesTrajano:我使用来自adoptopenjdk.netopenjdk(目前为我自己使用Java8,但今天用于Jdk11 的实验)。从这个站点下载并解压 Jdk11 后,我运行命令$ grep -r securerandom *,它给了我路径conf/security/java.security(Jdk 主目录下的相对路径)。我希望这会有所帮助。
        • 我说的是来自 docker hub 的 openjdk:11-slim 图像,但希望它和你说的在同一个地方
        • @ArchimedesTrajano:以防万一:输入openjdk:11-slim-container 如下:$ docker run --rm -it openjdk:11-slim bash,然后是$ cd /(只是为了确保您在根目录中),然后是$ grep -r securerandom *这里给出:etc/java-11-openjdk/security/java.security(搜索需要一段时间,但您可以使用 Ctrl+C 停止它,然后使用 Ctrl+D 退出)。这很可能也适用于基于包含 jvm 的图像的其他容器。
        猜你喜欢
        • 2018-05-04
        • 1970-01-01
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        • 2022-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多