Anaconda kickstart and rootpw option
I've tried a few different methods of generating an encrypted password on SL 6.5, but nothing seems to work for me. I'm not finding any errors anywhere in the various /var/log/anaconda* files, but I can't log in so it's obviously not working.
The original auto-created file at /root/anaconda-ks.cfg
I used as a template looked like this:
rootpw --iscrypted $6$...(about 100 characters)
authconfig --enableshadow --passalgo=sha512
Next I tried openssl passwd -1
which gave me:
rootpw --iscrypted $1$...(about 30 characters)
authconfig --enableshadow --passalgo=sha512
I realized that wasn't SHA-512 so I tried a Python one-liner I found repeated in a few places:
rootpw --iscrypted $6...(about 10 characters)
authconfig --enableshadow --passalgo=sha512
Nothing works; I can't log in and I end up having to reset the root password in single-user mode.
Solution 1:
Make sure you have shadow and passalgo=sha512 on a machine, set the root pass to whatever password you want on that machine and take it from /etc/shadow and put it in the kickstart. This is not advisable for production use.
To do it programmatic, use the crypt library of your chosen language that generates the kickstart file:
RUBY:
'password'.crypt('$6$' + (Base64.encode64(6.times.map{ Random.rand(256).chr }.join)).strip)
PHP:
crypt ('password', '$6$' . base64_encode (openssl_random_pseudo_bytes(6)));
Perl:
crypt ('password', '$6$' . encode_base64 (join '' => map chr (rand (256)), 0..5))
Python:
crypt.crypt('password', '$6$' + base64.b64encode(os.urandom(6)))
It is highly advisable that you use a random salt each time, like I did here, specially if you use the same password on all servers.
EDIT: Python 3:
crypt.crypt("password", crypt.mksalt())
Replaces the call to os.random
with the crypt specific mksalt
.
See Python Standard Library: crypt: crypt.mksalt()
: "Return a randomly generated salt of the specified method. If no method is given, the strongest method available as returned by methods() is used"
EDIT:
1) '$6$' is for SHA512. You would need to replace it with the encryption type of your choice.
2) You can transform any of these into one liners too in order to do it from bash.
EDIT (to have a complete answer, thanks to miken32 and dawud):
3) BSD crypt is a different implementation comparing to the GNU one so they are not compatible. If you want to use this on BSD systems (like OSX), you can use the PHP (with PHP version > 5.3.0) version as it implements its own crypt() function.
Another alternative on the mac is to use passlib:
python -c 'import getpass; import passlib.hash; h=passlib.hash.sha512_crypt.hash(getpass.getpass()); print(h if (passlib.hash.sha512_crypt.verify(getpass.getpass("Confirm:"), h)) else "")'
or, with glibc's default no. of rounds (5000):
python -c 'import getpass; import passlib.hash; h=passlib.hash.sha512_crypt.using(rounds=5000).hash(getpass.getpass()); print(h if (passlib.hash.sha512_crypt.verify(getpass.getpass("Confirm:"), h)) else "")'
Solution 2:
The way a hashed password is generated is documented here.
$ python -c 'import crypt; print(crypt.crypt("My Password", "$6$My salt"))'
The reason why it is not working for you is because you are using a Mac to generate the hash.
The crypt
implementation differs from the GNU/Linux one.
From the crypt(3)
manpage:
Glibc notes
The glibc2 version of this function supports additional encryption
algorithms.
If salt is a character string starting with the characters "$id$" fol-
lowed by a string terminated by "$":
$id$salt$encrypted
then instead of using the DES machine, id identifies the encryption
method used and this then determines how the rest of the password
string is interpreted. The following values of id are supported:
ID | Method
---------------------------------------------------------
1 | MD5
2a | Blowfish (not in mainline glibc; added in some
| Linux distributions)
5 | SHA-256 (since glibc 2.7)
6 | SHA-512 (since glibc 2.7)
So $5$salt$encrypted is an SHA-256 encoded password and
$6$salt$encrypted is an SHA-512 encoded one.
"salt" stands for the up to 16 characters following "$id$" in the salt.
The encrypted part of the password string is the actual computed pass-
word. The size of this string is fixed:
MD5 | 22 characters
SHA-256 | 43 characters
SHA-512 | 86 characters
The characters in "salt" and "encrypted" are drawn from the set
[a-zA-Z0-9./]. In the MD5 and SHA implementations the entire key is
significant (instead of only the first 8 bytes in DES).
The $id$
extension does not exists in OSX crypt
For SHA512 you need to generate the hash in a GNU/Linux machine.
Solution 3:
New documentation location of where to find out more on generating a hashed password for the kickstart option: --iscrypted
:
http://pykickstart.readthedocs.io/en/latest/kickstart-docs.html#rootpw
python -c 'import crypt; print(crypt.crypt("My Password", "$6$My Salt"))
This will generate sha512 crypt of your password using your provided salt.