Commit 4f2b2230 authored by Joshua Tauberer's avatar Joshua Tauberer

add comments about how openssl generates random numbers for genrsa and what...

add comments about how openssl generates random numbers for genrsa and what could create a perfect storm to make the key not random

see #596
parent 05e128ca
...@@ -88,6 +88,10 @@ if [ ! -f "$STORAGE_ROOT/dns/dnssec/$algo.conf" ]; then ...@@ -88,6 +88,10 @@ if [ ! -f "$STORAGE_ROOT/dns/dnssec/$algo.conf" ]; then
# #
# `ldns-keygen` outputs the new key's filename to stdout, which # `ldns-keygen` outputs the new key's filename to stdout, which
# we're capturing into the `KSK` variable. # we're capturing into the `KSK` variable.
#
# ldns-keygen uses /dev/random for generating random numbers. See the
# notes in ssl.sh about how /dev/urandom is seeded, which probably also
# applies here, but also /dev/random is seeded by the haveged daemon.
KSK=$(umask 077; cd $STORAGE_ROOT/dns/dnssec; ldns-keygen -a $algo -b 2048 -k _domain_); KSK=$(umask 077; cd $STORAGE_ROOT/dns/dnssec; ldns-keygen -a $algo -b 2048 -k _domain_);
# Now create a Zone-Signing Key (ZSK) which is expected to be # Now create a Zone-Signing Key (ZSK) which is expected to be
......
#!/bin/bash #!/bin/bash
# #
# SSL Certificate # RSA private key, SSL certificate, Diffie-Hellman bits files
# --------------- # -------------------------------------------
# Create a self-signed SSL certificate if one has not yet been created. # Create an RSA private key, a self-signed SSL certificate, and some
# Diffie-Hellman cipher bits, if they have not yet been created.
# #
# The certificate is for PRIMARY_HOSTNAME specifically and is used for: # The RSA private key and certificate are used for:
# #
# * DNSSEC DANE TLSA records
# * IMAP # * IMAP
# * SMTP submission (port 587) and opportunistic TLS (when on the receiving end) # * SMTP (opportunistic TLS for port 25 and submission on port 587)
# * the DNSSEC DANE TLSA record for SMTP # * HTTPS
# * HTTPS (for PRIMARY_HOSTNAME only)
# #
# When other domains besides PRIMARY_HOSTNAME are served over HTTPS, # The certificate is created with its CN set to the PRIMARY_HOSTNAME. It is
# we generate a domain-specific self-signed certificate in the management # also used for other domains served over HTTPS until the user installs a
# daemon (web_update.py) as needed. # better certificate for those domains.
#
# The Diffie-Hellman cipher bits are used for SMTP and HTTPS, when a
# Diffie-Hellman cipher is selected during TLS negotiation. Diffie-Hellman
# provides Perfect Forward Secrecy.
source setup/functions.sh # load our functions source setup/functions.sh # load our functions
source /etc/mailinabox.conf # load global vars source /etc/mailinabox.conf # load global vars
...@@ -23,9 +28,46 @@ echo "Creating initial SSL certificate and perfect forward secrecy Diffie-Hellma ...@@ -23,9 +28,46 @@ echo "Creating initial SSL certificate and perfect forward secrecy Diffie-Hellma
apt_install openssl apt_install openssl
mkdir -p $STORAGE_ROOT/ssl mkdir -p $STORAGE_ROOT/ssl
# Generate a new private key. # Generate a new private key.
# Set the umask so the key file is not world-readable. #
# The key is only as good as the entropy available to openssl so that it
# can generate a random key. "OpenSSL’s built-in RSA key generator ....
# is seeded on first use with (on Linux) 32 bytes read from /dev/urandom,
# 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!
#
# A perfect storm of issues can cause the generated key to be not very random:
#
# * 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)
#
if [ ! -f $STORAGE_ROOT/ssl/ssl_private_key.pem ]; then 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 \ (umask 077; hide_output \
openssl genrsa -out $STORAGE_ROOT/ssl/ssl_private_key.pem 2048) openssl genrsa -out $STORAGE_ROOT/ssl/ssl_private_key.pem 2048)
fi fi
...@@ -44,10 +86,9 @@ if [ ! -f $STORAGE_ROOT/ssl/ssl_certificate.pem ]; then ...@@ -44,10 +86,9 @@ if [ ! -f $STORAGE_ROOT/ssl/ssl_certificate.pem ]; then
-in $STORAGE_ROOT/ssl/ssl_cert_sign_req.csr -signkey $STORAGE_ROOT/ssl/ssl_private_key.pem -out $STORAGE_ROOT/ssl/ssl_certificate.pem -in $STORAGE_ROOT/ssl/ssl_cert_sign_req.csr -signkey $STORAGE_ROOT/ssl/ssl_private_key.pem -out $STORAGE_ROOT/ssl/ssl_certificate.pem
fi fi
# For nginx and postfix, pre-generate some Diffie-Hellman cipher bits which is # Generate some Diffie-Hellman cipher bits.
# used when a Diffie-Hellman cipher is selected during TLS negotiation. Diffie-Hellman # openssl's default bit length for this is 1024 bits, but we'll create
# provides Perfect Forward Secrecy. openssl's default is 1024 bits, but we'll # 2048 bits of bits per the latest recommendations.
# create 2048.
if [ ! -f $STORAGE_ROOT/ssl/dh2048.pem ]; then if [ ! -f $STORAGE_ROOT/ssl/dh2048.pem ]; then
openssl dhparam -out $STORAGE_ROOT/ssl/dh2048.pem 2048 openssl dhparam -out $STORAGE_ROOT/ssl/dh2048.pem 2048
fi fi
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment