From eac0410e45f82ae2834edf95a1bfd20ec85f87ef Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Tue, 4 Sep 2018 16:43:34 -0700 Subject: [PATCH] gce: use getrandom instead of urandom for on node rng In the context, our urandoms where generally safe, however getrandom has built in invariants around entropy pool initialization, making getrandom safe in all contexts. This should protect us from cryptopasta errors or weird entropy issues. --- cluster/gce/gci/configure-helper.sh | 40 ++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 331213b1501..baec2f9bc2d 100644 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -43,6 +43,40 @@ function setup-os-params { echo "core.%e.%p.%t" > /proc/sys/kernel/core_pattern } +# secure_random generates a secure random string of bytes. This function accepts +# a number of secure bytes desired and returns a base64 encoded string with at +# least the requested entropy. Rather than directly reading from /dev/urandom, +# we use uuidgen which calls getrandom(2). getrandom(2) verifies that the +# entropy pool has been initialized sufficiently for the desired operation +# before reading from /dev/urandom. +# +# ARGS: +# #1: number of secure bytes to generate. We round up to the nearest factor of 32. +function secure_random { + local infobytes="${1}" + if ((infobytes <= 0)); then + echo "Invalid argument to secure_random: infobytes='${infobytes}'" 1>&2 + return 1 + fi + + local out="" + for (( i = 0; i < "${infobytes}"; i += 32 )); do + # uuids have 122 random bits, sha256 sums have 256 bits, so concatenate + # three uuids and take their sum. The sum is encoded in ASCII hex, hence the + # 64 character cut. + out+="$( + ( + uuidgen --random; + uuidgen --random; + uuidgen --random; + ) | sha256sum \ + | head -c 64 + )"; + done + # Finally, convert the ASCII hex to base64 to increase the density. + echo -n "${out}" | xxd -r -p | base64 -w 0 +} + function config-ip-firewall { echo "Configuring IP firewall rules" @@ -2694,9 +2728,9 @@ function main() { fi # generate the controller manager, scheduler and cluster autoscaler tokens here since they are only used on the master. - KUBE_CONTROLLER_MANAGER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null) - KUBE_SCHEDULER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null) - KUBE_CLUSTER_AUTOSCALER_TOKEN=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null) + KUBE_CONTROLLER_MANAGER_TOKEN="$(secure_random 32)" + KUBE_SCHEDULER_TOKEN="$(secure_random 32)" + KUBE_CLUSTER_AUTOSCALER_TOKEN="$(secure_random 32)" setup-os-params config-ip-firewall