This is fantastic. I think something like this will be very useful in managing a large number of Macintosh clients. It is certainly the help and outcome that I was looking for when I started this thread. A big "Thank You" to Allan and everyone else that contributed.
I took a little different but similar approach. I may adapt my approach to mimic Allan's as time permits. But... here is what I came up with. 1) A launchd job to run puppet every hour passing the $HOSTNAME as a certname arg. 2) If the machine is re-imaged at any time, a startup job is installed that uses ssh to contact the puppetmaster and delete the cert that corresponds to the machine's $HOSTNAME. Then the startup job deletes itself. So the job is only run once on a newly imaged machine. i) The machine's hostname is its serial number as determined by facter. -kurt On Thu, Jul 9, 2009 at 6:12 PM, Allan Marcus <[email protected]> wrote: > > 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 [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en -~----------~----~----~----~------~----~------~--~---
