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.