rng-tools 의 rngd 서비스가 뜨지 않는다.
rngd: Initialization Failed
rngd: [hwrng]: Initialization Failed
rngd: [namedpipe]: Initialization Failed
가상 머신이나 컨테이너 호스트에서 흔하다. 하드웨어 난수 발생기가 없거나, 있어도 커널 모듈이 올라오지 않았기 때문이다.
rngd 는 하드웨어 난수원에서 값을 읽어 커널 엔트로피 풀(/dev/random)에 채워 넣는다. 엔트로피가 마르면 /dev/random 읽기가 블록되던 시절, 부팅 직후 TLS 키 생성이나 SSH 호스트 키 생성이 몇 분씩 멈추는 문제를 풀기 위한 도구였다.
지금은 이 전제가 대부분 사라졌다. 리눅스 커널 5.6 부터 /dev/random 은 초기 시드가 잡힌 뒤로는 블록하지 않고, 5.18 이후로는 /dev/random 과 /dev/urandom 이 사실상 같은 CSPRNG 를 쓴다. 최신 x86 CPU 는 RDRAND·RDSEED 를 내장하고 커널이 그것을 직접 쓴다.
그래서 rngd 가 안 뜬다고 해서 시스템에 문제가 생기는 것은 아니다. 조치를 하기 전에 정말 필요한지부터 판단한다.
# 하드웨어 RNG 장치
ls -l /dev/hwrng
cat /sys/class/misc/hw_random/rng_available
cat /sys/class/misc/hw_random/rng_current
# CPU 명령 지원 여부
grep -o -m1 -E 'rdrand|rdseed' /proc/cpuinfo
# 현재 엔트로피
cat /proc/sys/kernel/random/entropy_avail
rng_available 이 비어 있으면 커널이 인식한 하드웨어 난수원이 없다. entropy_avail 이 256 이상이면 커널 풀은 이미 시드가 잡힌 상태다.
가장 정직한 선택이다. 하드웨어 난수원이 없고 최신 커널이라면 rngd 는 할 일이 없다.
systemctl disable --now rngd
호스트의 엔트로피를 게스트에 전달하는 장치다. 실제 난수원을 게스트에 주는 유일한 제대로 된 방법이다.
libvirt 라면 도메인 XML 에 넣는다.
<rng model='virtio'>
<backend model='random'>/dev/urandom</backend>
</rng>
게스트에서 확인한다.
lsmod | grep virtio_rng
cat /sys/class/misc/hw_random/rng_current # virtio_rng.0
TPM 이나 칩셋 RNG 가 달렸는데 인식되지 않는 경우다.
modprobe tpm_rng # TPM
modprobe rng_core
echo tpm_rng > /etc/modules-load.d/tpm_rng.conf
하드웨어 난수원이 전혀 없는 환경에서 rng-tools 6.x 는 CPU 실행 시간의 지터를 난수원으로 쓸 수 있다.
# /etc/sysconfig/rngd (RHEL 계열)
EXTRAOPTIONS="-x hwrng -x rdrand -n jitter"
-x 는 해당 난수원을 끄고, -n 은 켠다. 쓰지 않는 난수원을 꺼 두면 초기화 실패가 사라진다.
/dev/urandom 을 rngd 의 입력으로 지정해 /dev/random 에 밀어 넣는 방식이 인터넷에 널리 퍼져 있다.
# 하지 않는다
rngd -r /dev/urandom
이것은 커널 풀에서 꺼낸 값을 다시 같은 풀에 넣는 것이다. 새 엔트로피가 하나도 늘지 않으면서 커널의 엔트로피 추정치만 부풀린다. 엔트로피가 실제로 부족한 상황이라면 이 방식은 문제를 숨길 뿐 해결하지 않는다. 엔트로피가 부족하지 않은 상황이라면 애초에 rngd 가 필요 없다.
rng-tools 6.x 에서는 -r 옵션 자체가 없어졌고 난수원을 -n·-x 로 고른다. 예전 문서를 그대로 따라 하면 옵션 오류로 기동에 실패한다.
rng-tools 의 namedpipe 난수원이 켜져 있는데 지정한 FIFO 가 없을 때 난다. 이 난수원을 쓰지 않는다면 꺼 버리면 된다.
EXTRAOPTIONS="-x namedpipe"
실제로 쓰려면 FIFO 를 미리 만들어 두고, 쓰는 쪽 프로세스가 붙어 있어야 한다. 읽기 전용으로 열린 FIFO 는 쓰는 쪽이 붙을 때까지 블록한다.
mkfifo /run/rng-pipe
chmod 0600 /run/rng-pipe
배포판 패키지가 유닛을 제공하므로 직접 만들 일은 드물다. 굳이 만든다면 난수원을 명시하고 전면 실행(-f)으로 둔다.
[Unit]
Description=Hardware RNG Entropy Gatherer Daemon
Documentation=man:rngd(8)
ConditionPathExists=/dev/hwrng
[Service]
ExecStart=/usr/sbin/rngd -f -x rdrand -x namedpipe
Restart=on-failure
[Install]
WantedBy=multi-user.target
ConditionPathExists 를 두면 장치가 없는 머신에서 서비스가 조용히 건너뛰어진다. 실패 로그가 쌓이지 않는다.