In Puppet, how would I secure a password variable (in this case a MySQL password)?

7,091

Solution 1

When working with Puppet and MySQL, I tend to put the root password in /root/.my.cnf, lock this file down, and then restrict SSH access onto the database server.

Yes, storing the root password on the db server in clear text isn't the most secure solution. However if you write the mysql root password in this file, securing the mysql root account to allow logins from localhost only will keep the password out of puppet, and also out of the process list ps table.

Additionally, if someone has root access to read the file at /root/.my.cnf, then they probably also have access to stop the local MySQL daemon and restart the daemon without the users table to gain immediate root access to the database.

Solution 2

Someone else can likely point out some plug-in or similar that corrects me, but the general way to go about this is to store the encrypted password, not the plain text password.

However, I can tell you right now, MySQL doesn't allow you to use an encrypted password--otherwise, that WOULD be the password, and the hash would allow you to login anyways.

There are a lot of "hacks" around that allow you to use third-party utilities such as Hiera and GPG. Obviously, you can roll your own--but even Puppet's own mailing lists suggests this method.

Solution 3

You didn't specify who you are protecting this password from. I'm going to assume it's other sysadmins or possibly developers who have access to the puppet master and/or the client boxes but don't need to know the root password.

For setting the password initially, you could use this syntax:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*6DF1FC54F0CCD999F55D59D3D88526878230C77C' WITH GRANT OPTION;

Which would allow you to store an encrypted password in your puppet configuration instead of a plaintext one.

For using mysqladmin and the mysql client on the command line, the best I can think of is to add a .my.cnf file to your puppet config that gets deployed into an appropriate user's home directory. The file both in the puppet master and on the clients should have appropriate, restrictive file permissions.

There are plenty of ways around those file permissions when you add puppet into the mix (such as writing an exec() that pulls the file from the clients) but it would seem to be an improvement over storing the password in a world readable file. This would be more difficult if you use a versioning system for your puppet config.

Share:
7,091

Related videos on Youtube

NukaRakuForgotEmail
Author by

NukaRakuForgotEmail

Learning and helping.

Updated on September 18, 2022

Comments

  • NukaRakuForgotEmail
    NukaRakuForgotEmail almost 2 years

    I am using Puppet to provision MySQL with a parameterised class:

    class mysql::server( $password ) {
    
            package { 'mysql-server': ensure => installed }
            package { 'mysql': ensure => installed }
    
            service { 'mysqld':
                    enable => true,
                    ensure => running,
                    require => Package['mysql-server'],
            }
    
            exec { 'set-mysql-password':
                    unless => "mysqladmin -uroot -p$password status",
                    path => ['/bin', '/usr/bin'],
                    command => "mysqladmin -uroot password $password",
                    require => Service['mysqld'],
            }
    }
    

    How can I protect $password? Currently, I removed the default world readable permission from the node definition file and explicitly gave puppet read permission via ACL.

    I'm assuming others have come across a similar situation so perhaps there's a better practice.

  • Andrew M.
    Andrew M. over 12 years
    But if someone retrieved the encrypted password, couldn't they just use the encrypted string to login?
  • NukaRakuForgotEmail
    NukaRakuForgotEmail over 12 years
    @Redmumba All my testing seems to indicate so. Perhaps I'm missing something that Ladadadada could elaborate on.
  • Ladadadada
    Ladadadada over 12 years
    No. When you use IDENTIFIED BY PASSWORD '*HASH-HERE' instead of IDENTIFIED BY 'PASSWORD-HERE' MySQL inserts the hash directly into the user table. You then have to use the password that generated that hash to log in. You can see what your grant command with the password hash would look like by logging in normally and typing SHOW GRANTS;. You can also check other users with SHOW GRANTS FOR user@host;
  • Andrew M.
    Andrew M. over 12 years
    Ah, so you can't use the hash itself to login, I see. However, if he has a client that needs to connect to the database--say, his front end--he would also need a way of storing the encrypted password, which is food for thought.
  • Kejau Touray
    Kejau Touray about 8 years
    Use mysql_config_editor if on mysql 5.6 and later. Then at least the password will not be in plain text.