installer: raise generated password entropy from ~23 to ~33 bits
generate_diceware_password() built the password from 3 words out of a 96 word list plus a single digit: 96^3 x 10 = 8,847,360 combinations, about 23 bits. That one password is the desktop login, the 'free' account password, and the only thing standing in front of the Hub, which runs as root and displays the root password, the SSH passphrase, the RTL password and the Vaultwarden admin token. 23 bits is thin for something that valuable, and the rate limiting in front of it was weaker than intended (see "hub: make the login lockout that LOGIN_FAIL_MAX described"). Now 4 words plus 2 digits: 96^4 x 100 = 8,493,465,600, about 33 bits, for the cost of one more word to write down. - iso/installer.py: generate_diceware_password(). - modules/credentials.nix: the three fallback generators in root-password-setup, free-password-setup and free-password-migration, so a machine provisioned without the installer gets the same strength. Affects new installs only; existing passwords are untouched. Checked by running the real thing. The installer function was exercised 2000 times: 96 words in the list, always word-word-word-word-NN, 33.0 bits. For the three services, the generator lines were taken from the script the evaluated module really produces (nix eval on the nixpkgs revision flake.lock pins) and run 1500 times each: 96 words in each list, always word-word-word-word-NN, every two-digit suffix from 00 to 99 seen, and no repeated password.
This commit is contained in:
+8
-3
@@ -54,9 +54,14 @@ DICEWARE_WORDS = [
|
||||
]
|
||||
|
||||
def generate_diceware_password():
|
||||
words = [secrets.choice(DICEWARE_WORDS) for _ in range(3)]
|
||||
digit = secrets.randbelow(10)
|
||||
return "-".join(words) + f"-{digit}"
|
||||
# 4 words from a 96 word list plus 2 digits: 96^4 x 100 = ~8.5e9, about
|
||||
# 33 bits. The old 3 words plus 1 digit was 96^3 x 10 = ~8.8e6, about 23
|
||||
# bits, for a password that is simultaneously the desktop login, the
|
||||
# 'free' account password and the only thing in front of a Hub that runs
|
||||
# as root and hands out every stored credential.
|
||||
words = [secrets.choice(DICEWARE_WORDS) for _ in range(4)]
|
||||
digits = f"{secrets.randbelow(100):02d}"
|
||||
return "-".join(words) + f"-{digits}"
|
||||
|
||||
try:
|
||||
logfile = open(LOG, "a")
|
||||
|
||||
+11
-8
@@ -91,7 +91,7 @@ in
|
||||
SECRET_FILE="/var/lib/secrets/root-password"
|
||||
if [ ! -f "$SECRET_FILE" ]; then
|
||||
mkdir -p /var/lib/secrets
|
||||
# Generate a diceware-style passphrase: word-word-word-N
|
||||
# Generate a diceware-style passphrase: word-word-word-word-NN
|
||||
WORDS="apple barn brook cabin cedar cloud coral crane delta eagle ember \
|
||||
fern field flame flora flint frost grove haven hedge holly heron \
|
||||
jade juniper kelp larch lemon lilac linden loch lotus maple marsh \
|
||||
@@ -106,8 +106,9 @@ in
|
||||
W1=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W2=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W3=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$((RANDOM % 10))
|
||||
ROOT_PASS="$W1-$W2-$W3-$DIGIT"
|
||||
W4=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$(printf '%02d' $((RANDOM % 100)))
|
||||
ROOT_PASS="$W1-$W2-$W3-$W4-$DIGIT"
|
||||
echo "$ROOT_PASS" > "$SECRET_FILE"
|
||||
chmod 600 "$SECRET_FILE"
|
||||
fi
|
||||
@@ -170,7 +171,7 @@ in
|
||||
fi
|
||||
|
||||
mkdir -p /var/lib/secrets
|
||||
# Generate a diceware-style passphrase: word-word-word-N
|
||||
# Generate a diceware-style passphrase: word-word-word-word-NN
|
||||
WORDS="apple barn brook cabin cedar cloud coral crane delta eagle ember \
|
||||
fern field flame flora flint frost grove haven hedge holly heron \
|
||||
jade juniper kelp larch lemon lilac linden loch lotus maple marsh \
|
||||
@@ -185,8 +186,9 @@ in
|
||||
W1=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W2=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W3=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$((RANDOM % 10))
|
||||
FREE_PASS="$W1-$W2-$W3-$DIGIT"
|
||||
W4=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$(printf '%02d' $((RANDOM % 100)))
|
||||
FREE_PASS="$W1-$W2-$W3-$W4-$DIGIT"
|
||||
echo "$FREE_PASS" > "$SECRET_FILE"
|
||||
chmod 600 "$SECRET_FILE"
|
||||
echo "free:$FREE_PASS" | chpasswd
|
||||
@@ -229,8 +231,9 @@ in
|
||||
W1=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W2=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
W3=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$((RANDOM % 10))
|
||||
FREE_PASS="$W1-$W2-$W3-$DIGIT"
|
||||
W4=''${WORD_ARRAY[$((RANDOM % COUNT))]}
|
||||
DIGIT=$(printf '%02d' $((RANDOM % 100)))
|
||||
FREE_PASS="$W1-$W2-$W3-$W4-$DIGIT"
|
||||
|
||||
printf '%s\n' "$FREE_PASS" > "$SECRET_FILE"
|
||||
chmod 600 "$SECRET_FILE"
|
||||
|
||||
Reference in New Issue
Block a user