I need to manually edit
/etc/shadow to change the root password inside of a virtual machine image.
Is there a command-line tool that takes a password and generates an
/etc/shadow compatible password hash on standard out?
You can use following commands for the same:
openssl passwd -1 -salt xyz yourpass
makepasswd --clearfrom=- --crypt-md5 <<< YourPass
As @tink suggested, we can update password using
chpasswd using :
echo "username:password" | chpasswd
Or you can use encrypted password with
chpasswd. First generate it using this:
perl -e 'print crypt("YourPasswd", "salt"),"\n"'
Then later you can use generated password to update:
echo "username:encryptedPassWd" | chpasswd -e
This encrypted password we can use to create a new user with password, for example:
useradd -p 'encryptedPassWd' username
echo -e "md5crypt\npassword" | grub | grep -o "\$1.*"
perl -e 'use Crypt::PasswdMD5; print unix_md5_crypt("Password", "Salt"),"\n"'
This one is used by
makepasswd, but allows more versatility (like custom or empty salt).
On Ubuntu 12.04, there is mkpasswd (from the whois package): Overfeatured front end to crypt(3)
mkpasswd -m sha-512 -S saltsalt -s <<< YourPass
-m= Compute the password using the TYPE method. If TYPE is help then the available methods are printed.
-S= salt used.
$ mkpasswd -m help -s = Read password from stdin
This solution has the following benefits:
Re-prompts for the password to avoid mistakes.
$ python3 -c "from getpass import getpass; from crypt import *; \ p=getpass(); print('\n'+crypt(p, METHOD_SHA512)) \ if p==getpass('Please repeat: ') else print('\nFailed repeating.')"
None of the current methods are acceptable to me - They either pass the password on the command line (which ends up in my shell's history), require the installation of additional utilities (
makepasswd), use hard-coded salts or use old hashing techniques.
This method would generate SHA-512 hashes after prompting for the password and would use a random salt.
A method utilising Python 2 without any non-standard libraries:
python2 -c 'import crypt, getpass,os,base64; print crypt.crypt(getpass.getpass(), "$6$"+base64.b64encode(os.urandom(16))+"$")'
To do it without a prompt: (This will leave your password in the command history)
python2 -c 'import crypt, os,base64; print crypt.crypt("MyPassword", "$6$"+base64.b64encode(os.urandom(16))+"$")'
The openssl and chpasswd -e pair didn't work in my case in RHEL6. Combining "openssl passwd" and "usermod -p" command did the job.
Generate hash value of password along with salt value.
$ openssl passwd -1 -salt 5RPVAd clear-text-passwd43
Then, copy the encrypted string to usermod. Make sure to wrap it with single quote.
$ usermod -p '$1$5RPVAd$vgsoSANybLDepv2ETcUH7.' root
Check it out in shadow file.
$ grep root /etc/shadow
Expanding a bit on the criticisms of u150825 and Gert van den Berg, I found myself needing something relatively flexible for different situations with different automation systems. I decided I would add to my own little library of useful scripts and write this. It uses only native libraries from python 2.7+, and works on python3 just as well.
You can pick it up here if you like. It's just as easy to drop this in your environment if you're needing to use it a lot, http hosted or whatever, and you can run it on any platform using whatever the default python interpreter you've got available to you is, pretty reliably counting on it working.
It defaults to prompting using getpass with prompts on stderr (allowing easy capture of stdout), but if you pipe a string to it it'll just reap from stdin. Depending on how you're going about this, it may not be showing up in command history, either, so just be cognizant of what it is you're working with. I like having a flexible tool that'll behave in an expected way, rather than having to rely on packages or python one-lining my way to victory 10 different ways.