rng-tools 启动延迟因过早尝试向未就绪的 /dev/random 注入熵所致,应通过 systemd 依赖 systemd-random-seed-load.service 确保等待 crng init done 信号后再启动。

为什么 rng-tools 启动时总报 crng init done 延迟?
Linux 内核在完成 CSPRNG(crng)初始化前,会阻塞对 /dev/random 的阻塞式读取。而 rng-tools 默认启动时立即尝试向 /dev/random 注入熵,若此时内核尚未输出 random: crng init done,服务就会卡住或反复重试,表现为启动超时、Failed to start rng-tools.service 或日志里持续出现 failed to read from entropy source。
如何让 rng-tools 等到 crng init done 再启动?
关键不是“延迟几秒”,而是等待内核明确就绪信号。推荐用 systemd 的 After=systemd-random-seed-load.service + Wants=systemd-random-seed-load.service,因为该 service 本身已定义了 ExecStartPost=/bin/sh -c 'while ! grep -q "crng init done" /proc/sys/kernel/random/entropy_avail 2>/dev/null; do sleep 0.1; done' 类似逻辑(实际由内核导出的 /proc/sys/kernel/random/crng_ready 或 entropy_avail 判断)。
实操建议:
- 编辑
/etc/systemd/system/rng-tools.service.d/wait-for-crng.conf(新建目录和文件) - 写入以下内容:
[Unit] After=systemd-random-seed-load.service Wants=systemd-random-seed-load.service
然后执行 systemctl daemon-reload && systemctl restart rng-tools
rng-tools 启动失败时该查哪些日志和状态?
不要只看 journalctl -u rng-tools,容易漏掉前置依赖。必须组合检查:
-
journalctl -b | grep -i "random\|crng"—— 找最早一条random: crng init done出现时间 -
cat /proc/sys/kernel/random/crng_ready—— 返回1表示就绪,0表示未就绪(比entropy_avail更直接) -
systemctl list-dependencies --reverse rng-tools.service—— 确认是否真依赖了systemd-random-seed-load - 如果用了
rngd -f -r /dev/hwrng手动运行,注意加-q(quiet)避免干扰判断,且-r指定的设备必须真实存在(ls /dev/hwrng*验证)
ARM 平台或无硬件 RNG 的机器要特别注意什么?
这类机器往往熵池填充慢,crng init done 可能晚于所有用户空间服务启动完成。单纯靠 After= 不够,还需补充熵源:
- 确认内核编译启用了
CONFIG_RANDOM_TRUST_CPU=y(Intel/AMD)或CONFIG_RANDOM_TRUST_BOOTLOADER=y(ARM),否则即使有 CPU RNG 也不会被信任 - 安装
haveged作为软件熵源:它不依赖crng就能工作,且会主动唤醒内核熵池;但注意不能和rng-tools同时喂同一个设备(如都往/dev/random写),否则可能冲突 -
rng-tools的/etc/default/rng-tools中,RNGDOPTIONS="--hrng-device=/dev/hwrng --fill-watermark=90%"这类配置在无硬件设备时会导致启动失败,务必注释或删掉--hrng-device
最常被忽略的是:crng init done 不代表熵值高,只代表密钥已生成、可安全阻塞读取。低熵环境仍需持续喂入,但服务启动那一刻,等这个信号就够了。









