ensure /dev/urandom is seeded with a blocking call to /dev/random and using Ubuntu's pollinate servers
This commit is contained in:
parent
4f2b223070
commit
e8264e9b6a
2 changed files with 63 additions and 23 deletions
27
setup/ssl.sh
27
setup/ssl.sh
|
@ -37,35 +37,18 @@ mkdir -p $STORAGE_ROOT/ssl
|
|||
# the process ID, user ID, and the current time in seconds. [During key
|
||||
# generation OpenSSL] mixes into the entropy pool the current time in seconds,
|
||||
# the process ID, and the possibly uninitialized contents of a ... buffer
|
||||
# ... dozens to hundreds of times." /dev/urandom is, in turn, seeded from
|
||||
# "the uninitialized contents of the pool buffers when the kernel starts,
|
||||
# the startup clock time in nanosecond resolution, input event and disk
|
||||
# access timings, and entropy saved across boots to a local file" as well
|
||||
# as the order of execution of concurrent accesses to /dev/urandom.
|
||||
# (Heninger et al 2012, https://factorable.net/weakkeys12.conference.pdf)
|
||||
#
|
||||
# /dev/urandom draws from the same entropy sources as /dev/random, but
|
||||
# doesn't block or issue any warnings if no entropy is actually available.
|
||||
# (http://www.2uo.de/myths-about-urandom/) Thus eventually /dev/urandom
|
||||
# can be expected to have been seeded with the "input event and disk access
|
||||
# timings", but there's no guarantee that this has even ocurred.
|
||||
#
|
||||
# Some of these seeds are obviously not helpful for us: There are no input
|
||||
# events on severs (keyboard/mouse), and the user ID of this process is
|
||||
# always the same (we're root). And the seeding of /dev/urandom with the
|
||||
# time and a seed from a previous boot is handled by *during boot* by
|
||||
# /etc/init.d/urandom, which, in principle, may not have occurred yet!
|
||||
# ... dozens to hundreds of times."
|
||||
#
|
||||
# A perfect storm of issues can cause the generated key to be not very random:
|
||||
#
|
||||
# * improperly seeded /dev/urandom, but see system.sh for how we mitigate this
|
||||
# * the user ID of this process is always the same (we're root), so that seed is useless
|
||||
# * zero'd memory (plausible on embedded systems, cloud VMs?)
|
||||
# * a predictable process ID (likely on an embedded/virtualized system)
|
||||
# * a system clock reset to a fixed time on boot
|
||||
# * one CPU or no concurrent processes on /dev/urandom (so no concurrent accesses)
|
||||
# * no hard disk (so no disk access timings - but is this possible for us?)
|
||||
# * early run (no entry yet, boot not finished)
|
||||
# * first boot (no entropy saved from previous boot)
|
||||
#
|
||||
# Since we properly seed /dev/urandom in system.sh we should be fine, but I leave
|
||||
# in the rest of the notes in case that ever changes.
|
||||
if [ ! -f $STORAGE_ROOT/ssl/ssl_private_key.pem ]; then
|
||||
# Set the umask so the key file is never world-readable.
|
||||
(umask 077; hide_output \
|
||||
|
|
|
@ -54,8 +54,65 @@ apt_get_quiet upgrade
|
|||
echo Installing system packages...
|
||||
apt_install python3 python3-dev python3-pip \
|
||||
netcat-openbsd wget curl git sudo coreutils bc \
|
||||
haveged unattended-upgrades cron ntp fail2ban
|
||||
haveged pollinate \
|
||||
unattended-upgrades cron ntp fail2ban
|
||||
|
||||
# ### Seed /dev/urandom
|
||||
#
|
||||
# /dev/urandom is used by various components for generating random bytes for
|
||||
# encryption keys and passwords:
|
||||
#
|
||||
# * TLS private key (see `ssl.sh`, which calls `openssl genrsa`)
|
||||
# * our management server's API key (via Python's os.urandom method)
|
||||
#
|
||||
# Why /dev/urandom? It's the same as /dev/random, except that it doesn't wait
|
||||
# for a constant new stream of entropy. In practice, we only need a little
|
||||
# entropy at the start to get going. After that, we can safely pull a random
|
||||
# stream from /dev/urandom and not worry about how much entropy has been
|
||||
# added to the stream. (http://www.2uo.de/myths-about-urandom/) So we need
|
||||
# to worry about /dev/urandom being seeded properly (which is also an issue
|
||||
# for /dev/random), but after that /dev/urandom is superior to /dev/random
|
||||
# because it's faster and doesn't block indefinitely to wait for hardware
|
||||
# entropy. Note that `openssl genrsa` even uses `/dev/urandom`, and if it's
|
||||
# good enough for generating an RSA private key, it's good enough for anything
|
||||
# else we may need.
|
||||
#
|
||||
# Now about that seeding issue....
|
||||
#
|
||||
# /dev/urandom is seeded from "the uninitialized contents of the pool buffers when
|
||||
# the kernel starts, the startup clock time in nanosecond resolution,...and
|
||||
# entropy saved across boots to a local file" as well as the order of
|
||||
# execution of concurrent accesses to /dev/urandom. (Heninger et al 2012,
|
||||
# https://factorable.net/weakkeys12.conference.pdf) But when memory is zeroed,
|
||||
# the system clock is reset on boot, /etc/init.d/urandom has not yet run, or
|
||||
# the machine is single CPU or has no concurrent accesses to /dev/urandom prior
|
||||
# to this point, /dev/urandom may not be seeded well. After this, /dev/urandom
|
||||
# draws from the same entropy sources as /dev/random, but it doesn't block or
|
||||
# issue any warnings if no entropy is actually available. (http://www.2uo.de/myths-about-urandom/)
|
||||
# Entropy might not be readily available because this machine has no user input
|
||||
# devices (common on servers!) and either no hard disk or not enough IO has
|
||||
# ocurred yet --- although haveged tries to mitigate this. So there's a good chance
|
||||
# that accessing /dev/urandom will not be drawing from any hardware entropy and under
|
||||
# a perfect-storm circumstance where the other seeds are meaningless, /dev/urandom
|
||||
# may not be seeded at all.
|
||||
#
|
||||
# The first thing we'll do is block until we can seed /dev/urandom with enough
|
||||
# hardware entropy to get going, by drawing from /dev/random. haveged makes this
|
||||
# less likely to stall for very long.
|
||||
|
||||
echo Initializing system random number generator...
|
||||
dd if=/dev/random of=/dev/urandom bs=1 count=32 2> /dev/null
|
||||
|
||||
# This is supposedly sufficient. But because we're not sure if hardware entropy
|
||||
# is really any good on virtualized systems, we'll also seed from Ubuntu's
|
||||
# pollinate servers:
|
||||
|
||||
pollinate -q -r
|
||||
|
||||
# Between these two, we really ought to be all set.
|
||||
|
||||
# ### Package maintenance
|
||||
#
|
||||
# Allow apt to install system updates automatically every day.
|
||||
|
||||
cat > /etc/apt/apt.conf.d/02periodic <<EOF;
|
||||
|
|
Loading…
Reference in a new issue