random grub password

I currently have a task that adds a grub password so if the user wants to change anything in grub they have to enter the proper user and password.

The problem is that I have it working only when I generate the password by hand using grub-mkpasswd-pbkdf2 enter the password twice, which generates the hash. I then paste the hash into the variable “grub_password”.

The problem is I want to generate a random grub password on the fly and pass this password to grub-mkpasswd-pbkdf2 to generate the hash, then put the hash into a variable. I cannot figure out how to do this. Do I have to use the expect module to feed the random generated password into grub-mkpasswd-pdkdf2?

I’ve scoured online but everyone seems to have generated the hash beforehand. Any ideas how I can do this?

Actually, it's not that easy.
I had previously created a filter to generate PBKDF2 hashes for the
"mosquitto" application. Based on that I made a grub_mkpasswd_pbkdf2
filter:

https://gist.github.com/dnmvisser/c567608193ad6bc1465b182e9a58bca7

Example on how to use it:

dick.visser@foobar ~$ ansible -i localhost, all -m debug -a msg="{{
'hackme' | grub_mkpasswd_pbkdf2 }}"
localhost | SUCCESS => {
    "msg": "grub.pbkdf2.sha512.10000.380BF76393CDE1AB16ACE9F32AE6DB262FDD43021FEEEC1A94B87F14640F6D09D3D7DA61977BB7A4384766697148758D061E84FD5F81745EDDFF4E4B6C7DB0D0.92DC5B05FED969DB16BC4982B8B23B8B575D12E2ED776A911D7D47901DC5DDD8B4BAD65C535C33900321D050B8BE9BC2A6C3EDF96C1FB0825A0DC54BBBEB2F5B"
}

That is pretty cool. Mgmt is not thrilled with using a filter and want me to see if I can do it another way. I’m trying using the expect module, but not getting the response I thought:

  • name: Use expect

expect:
command: /usr/bin/grub-mkpasswd-pbkdf2
responses:
(?i)Enter password: “{{ random_plaintext_password }}”
(?i)Reenter password: {{ random_plaintext_password }}"
register: grub_hash
delegate_to: 127.0.0.1

  • name: Print grub_hash
    debug:
    msg: “Grub hash is {{ grub_hash.stdout }}”

However this prints the entire “exchange”:

New grub hash is Enter password:
Reenter password:
PDKDF2 hash of your password is…

Why is the entire exchange printed out? I expected that the last line above would be printed which I could then use cut on to print only the password.

The .stdout contains everything that is printed to stdout, hence the name.
You have .stdout_lines where each lines is an element in the list,
so grub_hash.stdout_lines[-1] gives you the last line.

So what you are looking for is this

   {{ grub_hash.stdout_lines[-1].split()[-1] }}

Thanks for that. Guess I need to learn more about the stdout options

I currently have a task that adds a grub password so if the user wants to change anything in grub they have to enter the proper user and password.

The problem is that I have it working only when I generate the password by hand using grub-mkpasswd-pbkdf2 enter the password twice, which generates the hash. I then paste the hash into the variable “grub_password”.

The problem is I want to generate a random grub password on the fly and pass this password to grub-mkpasswd-pbkdf2 to generate the hash, then put the hash into a variable. I cannot figure out how to do this. Do I have to use the expect module to feed the random generated password into grub-mkpasswd-pdkdf2?

I’d stay away from expect.

I’ve scoured online but everyone seems to have generated the hash beforehand. Any ideas how I can do this?

Here is some python code that is completely unverified:

https://github.com/ryran/burg2-mkpasswd-pbkdf2

I just recently did this in puppet (ruby based):

def default_grub_mkpasswd_pbkdf2(
clear_text,
salt,
rounds = 10000
)
require ‘openssl’

digest = OpenSSL::Digest::SHA512.new

hashed_password = OpenSSL::PKCS5.pbkdf2_hmac(clear_text, salt, rounds, digest.digest_length, digest).unpack(‘H*’).first.upcase

return “grub.pbkdf2.sha512.#{rounds}.#{salt.unpack(‘H*’).first.upcase}.#{hashed_password}”
end

I know that is a ruby, but it shouldn’t be hard to translate.

If you pass it the same salt each time, you’ll get the same hash each time. That is, it is deterministic.

Cheers,

-m