When automating Linux system administration tasks, you often need to change user passwords without manual interaction. Traditional methods like passwd
command require STDIN input, which isn't ideal for scripting scenarios.
The most straightforward method is using chpasswd
, which reads username:password pairs from STDIN:
echo "username:newpassword" | sudo chpasswd
For Ubuntu/Debian systems, you can also use:
echo "username:$(openssl passwd -6 'newpassword')" | sudo chpasswd -e
Another approach is using usermod
with encrypted passwords:
sudo usermod --password $(echo "newpassword" | openssl passwd -1 -stdin) username
While these methods work, be aware that:
- Command line arguments may be visible in process lists
- Bash history may store sensitive commands
- For production systems, consider using SSH certificates or other auth methods
When implementing this in scripts:
# Secure method using environment variable
NEWPASS="complex_password_here"
echo "username:$NEWPASS" | sudo chpasswd
unset NEWPASS
If encountering issues:
# Check password policy requirements
sudo grep -E "^PASS" /etc/login.defs
# Verify password change worked
sudo grep username /etc/shadow
For Ubuntu/Debian systems, the most direct method is using the chpasswd
utility which is specifically designed for batch password changes:
echo "username:newpassword" | sudo chpasswd
This works because chpasswd
reads username:password pairs from stdin. The command needs root privileges, hence the sudo
.
If chpasswd
isn't available, here are three other approaches:
Using passwd with --stdin
echo "newpassword" | sudo passwd --stdin username
Note: The --stdin
flag isn't available on all Linux distributions, but works on many including some Ubuntu versions.
Using usermod
sudo usermod --password $(echo "newpassword" | openssl passwd -1 -stdin) username
This method hashes the password first using OpenSSL before passing it to usermod.
Python One-liner
python -c "import crypt; print(crypt.crypt('newpassword', crypt.mksalt(crypt.METHOD_SHA512)))" | sudo tee /etc/shadow
While these methods work, be aware that:
- The password appears in shell history
- Visible in process listings during execution
- Potential exposure through SSH logging
For production systems, consider using SSH keys or temporary password files that get immediately deleted.
Here's how you might implement this in an automated provisioning script:
#!/bin/bash
NEW_USER="deploy"
TEMP_PASS="initPass123!"
# Create user if doesn't exist
id -u $NEW_USER &>/dev/null || sudo useradd -m $NEW_USER
# Set password non-interactively
echo "$NEW_USER:$TEMP_PASS" | sudo chpasswd
# Force password change on first login
sudo passwd -e $NEW_USER
This creates a user with a temporary password that must be changed at first login.