Unable to create a user with password via ssh

This is a classic quoting issue.

Problem: Without any quoting or double quoting the command substitution ($()) and variable expansion (the $s in the hashed password returned by openssl are being treated as variable indicator) are being done in the local environment, not on the remote shell.

Solution: use single quotes around the useradd command used with ssh on the local shell to prevent the command substitution and variable expansion on local environment, let the expansions take place on the remote non-login, non-interactive shell:

ssh [email protected] 'useradd -p "$(openssl passwd -1 1234)" newuser'

Note the quotings.

Security issues:

  • SSH root login should be disabled, if you must have it enabled only key-based authentication should be allowed

  • MD5 is already broken, and without a salt you are subjected to simple Rainbow table attack (does not even need brute forcing/dictionary attack); openssl passwd does generate a random salt though. Anyway, you should really consider using SHA-2 with salt-ing

  • Passwords passed as arguments to commands might be visible to other processes in the (remote) system; this depends on how your procfs is mounted (look at hidepid), and if the command is rewriting itself (it this case presumably it does not)


As @heemayl noted, the MD5 password hash algorithm is aged, and current systems the newer SHA-2 based password hashes, that have a customisable work factor. But the OpenSSL command line tool doesn't seem to support those.

The chpasswd utility, however, will allow you to change the password of a user according to the system settings.

This should allow you to create the new user and change their password on the remote end.

echo "newuser:newpass" | ssh [email protected] 'useradd newuser; chpasswd' 

chpasswd takes the username and password from stdin, not the command line. This is actually an advantage since command line arguments are visible for all other processes on the system, so if run openssl passwd on the remote, the password would be momentarily visible to all processes on the system.

I'm not sure if there is a ready-made command line utility for generating password hashes known by the system crypt(3) function. Perl has the crypt function builtin, but a proper salt would still need to be generated.