在 Puppet 中,我如何保护密码变量(在本例中为 MySQL 密码)?

在 Puppet 中,我如何保护密码变量(在本例中为 MySQL 密码)?

我正在使用 Puppet 为 MySQL 提供一个参数化类:

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'],
        }
}

我该如何保护$password?目前,我从节点定义文件中删除了默认的全局可读权限,并puppet通过 ACL 明确授予了读取权限。

我假设其他人也遇到过类似的情况,所以也许有更好的做法。

答案1

在使用 Puppet 和 MySQL 时,我倾向于将 root 密码放在 /root/.my.cnf 中,锁定此文件,然后限制 SSH 对数据库服务器的访问。

是的,将 root 密码以明文形式存储在数据库服务器上并不是最安全的解决方案。但是,如果您在此文件中写入 mysql root 密码,则保护 mysql root 帐户以仅允许从 localhost 登录将使密码不会出现在 puppet 中,也不会出现在进程列表中ps

此外,如果有人具有 root 权限来读取 /root/.my.cnf 中的文件,那么他们可能也有权停止本地 MySQL 守护进程并在没有用户表的情况下重新启动守护进程,以立即获得数据库的 root 访问权限。

答案2

其他人可能会指出一些插件或类似的东西来纠正我,但解决这个问题的一般方法是存储加密密码,而不是纯文本密码。

但是,我现在可以告诉你,MySQL 不允许您使用加密密码 - 否则,那将是密码,并且哈希将允许您登录。

有很多“黑客”可以让你使用第三方实用程序,例如Hiera 和 GPG。显然,你可以自己动手——但是甚至 Puppet 自己的邮件列表也建议使用这种方法

答案3

您没有指定要保护此密码不让谁知道。我假设是其他系统管理员或可能是开发人员,他们可以访问 Puppet Master 和/或客户端框,但不需要知道 root 密码。

要最初设置密码,您可以使用以下语法:

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

这将允许您在 Puppet 配置中存储加密密码而不是纯文本密码。

对于在命令行上使用客户端,我能想到的最好的方法是将一个文件添加mysqladmin到puppet 配置中,该文件将部署到相应用户的主目录中。Puppet Master 和客户端上的文件都应具有适当的限制性文件权限。mysql.my.cnf

当您将 puppet 添加到组合中时,有很多方法可以绕过这些文件权限(例如编写一个 exec() 从客户端提取文件),但这似乎比将密码存储在世界可读的文件中有所改进。如果您对 puppet 配置使用版本控制系统,这将更加困难。

答案4

此链接建议两种方法:使用环境变量和使用子shell。

我认为您还可以为命令创建一个简单的包装器mysqladmin,并将加密的密码传递给它。然后,此包装器将解密密码并将其传递给mysqladmin。您需要保护包装器,因为它包含解密部分。

您可以根据您的环境以及谁有权访问您的系统来选择您认为更安全的方式。

相关内容