Назад | Перейти на главную страницу

Управление паролями служб с помощью Puppet

Я настраиваю свою конфигурацию Bacula в Puppet. Одна вещь, которую я хочу сделать, - это убедиться, что каждое поле пароля отличается. Моя текущая мысль состоит в том, чтобы хешировать имя хоста с секретным значением, которое гарантировало бы, что каждый файловый демон имеет уникальный пароль, и этот пароль может быть записан как в конфигурацию директора, так и на файловый сервер. Я определенно не хочу использовать один универсальный пароль, так как это позволит любому, кто может взломать одну машину, получить доступ к любой машине через Bacula.

Есть ли другой способ сделать это, кроме использования хэш-функции для генерации паролей?

Уточнение:

Это НЕ об учетных записях пользователей для сервисов. Речь идет о токенах аутентификации (если использовать другой термин) в файлах клиент / сервер. Пример фрагмента:

Director {                            # define myself
  Name = <%= hostname $>-dir
  QueryFile = "/etc/bacula/scripts/query.sql"
  WorkingDirectory = "/var/lib/bacula"
  PidDirectory = "/var/run/bacula"
  Maximum Concurrent Jobs = 3
  Password = "<%= somePasswordFunction =>"         # Console password
  Messages = Daemon
}
    $secret = "super special complicated long secure random string"
    $password = sha1("${fqdn}${secret}")
    notify {$password:}

Импортировать $secret из другого файла (возможно, того класса марионеток, который вы не храните в системе управления версиями), и вот он. Генерация волшебного пароля.

Пароли можно изменить глобально, изменив $secret или индивидуально в каждом объявлении, используя что-то иное, чем $fqdn.

Я вполне доволен своим решением. Это сценарий оболочки, вызываемый функцией generate () из манифеста марионетки. Пароль для каждого хоста генерируется и сохраняется в простом файле по мере необходимости.

#!/bin/bash
# /etc/puppet/helpers/bacula/getpwd

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <pwd_name>"
    exit 1
fi

if [ ! -x /usr/bin/pwgen ]; then
    echo "missing pwgen!" >&2
    exit 1
fi

workdir="/etc/puppet/helpers/bacula/"
workfile="$workdir/passwd"
[ ! -r $workfile ] && exit 2
get_name="$1"

# get password from storage
pwd=$(awk -F: -v name="$get_name" '
BEGIN      { r = "NOTFOUND" }
name == $1 { r = $2         }
END        { printf "%s", r }
' "$workfile")

if [ "$pwd" = "NOTFOUND" ]; then
    # generate new password & store it
    len=$((60 + $RANDOM % 9 ))
    pwd=$(/usr/bin/pwgen -s $len 1)

    echo "${get_name}:${pwd}" >> $workfile
fi

# echo password (without new line)
echo -n "$pwd"

Установите pwgen или другой инструмент генерации паролей, измените переменную workdir в соответствии с настройками вашей системы, проверьте длину пароля. В файле шаблона назовите его:

Password = <%= scope.function_generate("/etc/puppet/helpers/bacula/getpwd", bacula_dirname) %>

Переменная марионетки bacula_dirname должна быть основана на имени хоста или задана из extlookup (), например:

$bacula_dirname = "${hostname}-dir"

Альтернативой является установка чего-либо с помощью extlookup (), чтобы вы могли иметь уникальность для каждой машины, которая не зависит от общего значения.

В нашем случае мы делали подобные вещи с помощью аналогичных инструментов, которые требовали большей уникальности, чем то, что дает нам хешированное значение с общим секретом.

В site.pp

$extlookup_datadir = "/etc/puppet/manifests/extdata"
$extlookup_precedence = ["hostname/%{hostname}", "common"]

Тогда ваши внешние данные будут выглядеть так:

/etc/puppet/manifests/extdata
                             /common.csv
                             /hostname
                                      /foo.csv

Внутри foo.csv вы должны поместить что-то вроде:

bacula_password,"J()*JF)jj0j20f9j02rj9<whatever>"

Затем в вашем модуле bacula вы бы сделали

$bacula_password = extlookup('bacula_password')

на который вы затем можете ссылаться в своем шаблоне.

Когда каталог оценивается, имя хоста «foo» будет найдено первым в приоритете ext, и оттуда будет извлечено значение bacula_password.