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
-~----------~----~----~----~------~----~------~--~---

Reply via email to