Putting it all together, here's what I have for cert management on Macs.

1) A launchd job to launch puppet every hour
2) a script on the client to determine a unique attribute of the Mac  
and use it for cert name
3) a CGI on the server to clean a cert if the machine was re-imaged
3a) note: alter /etc/sudoers on the server to allow the cgi to run  
puppetca

Testing is rather easy. Runt he puppetd.sh script on the client (as  
root). Delete the /etc/puppet/ssl dir then run again. The system  
should clean the cert on the server



(1) This plist file should be in /Library/LaunchDaemons/
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd 
">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.mycompany.puppetd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/bin/puppetd.sh</string>
        </array>
        <key>QueueDirectories</key>
        <array/>
        <key>StartInterval</key>
        <integer>3600</integer>
        <key>WatchPaths</key>
        <array/>
</dict>
</plist>


(2) /usr/bin/puppet.sh and chmod 700 and chown root:wheel
#!/bin/sh
# puppetd.sh script
# Script to run puppet and use the "correct" certname
# we need the certname to be unique, so hostname is not great

# by Allan Marcus of LANL

# Version History
# 2009-07-08: initial version

# this script is run from a launchd job

# this suffix is added to the value to make it look like a FQDN.
# This allows for auto sign to work on the server with a simply wildcard
SUFFIX=mycompany.com

# this is the server to sent a puppetca clean to
SERVER=www.mycompany.com


# ---------------

# see if the MAC_UID is in nvram already
MAC_UID=`nvram MAC_UID 2>/dev/null | awk '{print $2}'`
if [ -z "$MAC_UID" ]; then
        # flag that nothing is in nvram yet
        NVRAM="no"
fi

# get the serial number for this Mac
if [ -z "$MAC_UID" ]; then
        MAC_UID=`facter | grep sp_serial_number | awk '{print $3}'`
fi

# if the MAC_UID is still null
# get the primary MAC address
if [ -z "$MAC_UID" ]; then
        MAC_UID=`facter | grep 'macaddress =>' | awk '{print $3}'`
fi

# if all the above fails, get the hostname
if [ -z "$MAC_UID" ]; then
        MAC_UID=`hostname`
fi      

# assuming we have something, write it to nvram
# getting it from nvram is much faster and is limited to this
# specific computer
if [ '$NVRAM' == 'no' ]; then
        # cert names must be lowercase
        MAC_UID=`echo $MAC_UID | tr "[:upper:]" "[:lower:]"`
        MAC_UID=${MAC_UID}.${SUFFIX}
        nvram MAC_UID=${MAC_UID}
fi

RESULTS=`puppetd -o --no-daemonize -v --certname=$MAC_UID 2>&1`
RESULTS=`echo $RESULTS | grep 'Certificate request does not match
existing certificate'`

if [ -z "$RESULTS" ]; then
        exit 0  
else
         # curl call to a CGI to clean the cert
        curl "http://${SERVER}/cgi-bin/cleanCert.rb?certname=${MAC_UID}";
fi

### end puppetd.sh script ####

(3) On the server in the CGI directory. On a Mac server you also need  
to allow CGI's in server admin.
#!/usr/bin/ruby

# clearCert.rb
# cgi to clean a cert

class Puppetca
        # removes old certificate if it exists
        # parameter is the certname to use
        # need to allow the _www user to use sudo with the puppetca command
        # added using visudo
        # _www    ALL = NOPASSWD: /usr/bin/puppetca, !/usr/bin/puppetca -- 
clean --all
        def self.clean certname, addr
                command = "/usr/bin/sudo /usr/bin/puppetca --clean #{certname}"
                # for some reason the "system" command causes Mac apache to 
crash
                # when used here
                %x{#{command}}
                %x{"logger #{addr} cleaned #{certname}"}
                return true
        end
end

=begin
CGI starts here
=end

# get the value of the passed param in the URL Query_string
require 'cgi'
cgi=CGI.new
certname = cgi["certname"]

# define the characters that are allow to avoid an injection attack
# 0-9, a-z, period, dash, and colon are allowed. All else is not
pattern = /[^a-z0-9.\-:]/
# determine if any other characters are in the certname
reject = (certname =~ pattern) ? 1 : 0

if ((reject == 0) && Puppetca.clean(certname, ENV['REMOTE_ADDR']))
        cgi.out("status" => "OK", "connection" => "close") {"OK #{certname}  
cleaned\n"}
else
        cgi.out("status" => "BAD_REQUEST", "connection" => "close") {"Not  
Processed: #{certname}\n"}
end

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to