Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm setting up my Bacula configuration in Puppet. One thing I want to do is ensure that each password field is different. My current thought is to hash the hostname with a secret value that would ensure each file daemon has a unique password and that password can be written to both the director configuration and the file server. I definitely don't want to use one universal password as that would permit anybody who might compromise one machine to get access to any machine through Bacula.

Is there another way to do this other than using a hash function to generate the passwords?

Clarification:

This is NOT about user accounts for services. This is about the authentication tokens (to use another term) in the client / server files. Example snippet:

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
}
share|improve this question
1  
Do your service accounts even need passwords? Whenever possible it is good to set them to have an un-usable password? –  Zoredache Jan 24 '12 at 18:05
    
@Zoredache clarified: this is not about the password of the user account that the process runs as. That is indeed left blocked out. –  Jeff Ferland Jan 24 '12 at 19:12

3 Answers 3

An alternative is to set something up via extlookup() that you can then have per-machine uniqueness that doesn't depend on a common value.

In our case, we've done stuff like this with similar tools that needed more uniqueness than what a hashed value with a common secret gave us.

In site.pp

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

Then, your ext data would look like:

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

Inside foo.csv, you'd put something like:

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

Then in your bacula module, you'd do

$bacula_password = extlookup('bacula_password')

which you could then reference in your template.

When the catalog is evaluated, the hostname "foo" would be found first in the ext precedence and the value of bacula_password would be pulled from there.

share|improve this answer

I'm quite pleased with my solution to this. It's a shell script called by generate() function from puppet manifest. Password for each host is generated and stored in simple file as needed.

#!/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"

Install pwgen or another password generation tool, modify workdir variable for your system settings, check password lengths. In template file call it:

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

Puppet variable bacula_dirname should be based on hostname or set from extlookup() e.g.:

$bacula_dirname = "${hostname}-dir"
share|improve this answer
up vote 3 down vote accepted
    $secret = "super special complicated long secure random string"
    $password = sha1("${fqdn}${secret}")
    notify {$password:}

Import $secret from another file (perhaps that one puppet class that you don't keep in version control) and there you have it. Magic password generation.

Passwords can be changed globally by changing $secret or individually in each declaration by using something other than $fqdn.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.