When creating user accounts, it is tempting to use a default password and ask the user to change it right after logging in the first time. Unless the user is forced to do this by means of a password policy, most users are just happy with the supplied password.
I know about a company (a hospital!) that uses one and the same password for new email accounts, allowing (ex)colleagues to read each others’ email!
A nice utility to generate random passwords is pwgen. The passwords are semi-random: random enough to be safe, but not too difficult to remember. By default, pwgen presents you a list from which you can choose:
$ pwgen
Vahvoi5u Da5ahrah Ogo0voh0 Fo3rieji aiw5zeuR qui1aiYo
thae5Chu Ha8bohSu oa2Eu3go JooQuia8 Aroh7Ohc UCoo4Hah
Woocee1i Ahnein6s di6aGeph fi5Ahngu ooRe8eeW Aish0sha
aikei3Fa Abohhai3 aeNgoo6o yiw2keiS eiyo5geH To5we6ey
… and 16 more lines. The man page explains that this is done so that you can pick a password without being afraid of someone ’shoulder surfing’ for the chosen password.
Used from within a script (non-interactively), pwgen will generate a single password:
$ pwgen | wc
1 1 9
Using pwgen to create a new user would involve a number of steps:
- run pwgen and write down the generated password
- create user account
- hand over the note with the password
- instruct the user how to log in and refer to the documentation about the service
You can argue about weather it is safe to write down the password, that’s another discussion.
I’ve written a little script that combines these steps.
The most interesting part of the script is the way that the generated password is fed in to the useradd command. The useradd option -p allows you to supply the encrypted password. “…, as returned by crypt(3)”, the man-page says.
Well, that brings up a problem. Isn’t there a binary or built-in equivalent? I would rather see crypt(1) being referenced… but that tool doesn’t exist.
This is where openssl comes to help! It can generate a passwd style hash for a given password. For example, to generate a hash for ‘mypassword’, execute:
$ openssl passwd -1 mypassword
$1$xBN626Gk$vsK88ODo4CfQ3pBx9Z1vD0
This looks like something that we can feed to useradd!!
The minimalist version of the script now looks like:
#!/bin/sh
# first argument is the username
USER=$1
# generate password
PASSWORD=`pwgen -cn -1`
# generate password hash
PW_HASH=`openssl passwd -1 ${PASSWORD}`
# create the user account
useradd -M -p ${PW_HASH} ${USER}
# display username and password
echo Account created:
echo Username: ${USER}
echo Password: ${PASSWORD}
The full script adds some ‘fancy features’ like checking the input argument and printing a receipt with the username and password and a link to the documentation.
I’m using the script to add accounts to a server that acts as a SSH gateway. There’s no need for home directories on this computer. By using the -M option for useradd, no home directory will be created.
Maybe I should write my next Nerdnote(tm) about setting up an SSH server to use as a secure gateway to a private network.