makecert

Revised: 2006-09-22 richard

Download Script – ZIP-File, 2.2 KB

Introduction

This script automates the creation of openssl certificates or use with radmind.

Script

makecert
#!/usr/bin/perl -w

# makecert
#
# A script to automate the creation of openssl certificates
# for use with radmind.
# Must be run as root.
# usage is:  makecert hostname
#
# Greg Neagle, Walt Disney Feature Animation

use strict;

# some things specific to your environment
# set $domain to "" if you don't have your hostnames in DNS
my $domain = ".fas.fa.disney.com";
# to automate things, we have to supply the CAkey passphrase.
# This could be a security issue in your environment.
my $ca_password = "(INSERT CA KEY PASSPHRASE HERE)";

my $hostname = $ARGV[0];
if ($hostname) {
   my @hostparts = split /\./, $hostname;
   #get the short version of the hostname
   my $hostname = $hostparts[0];
   if ($hostname =~ /^d+$/) {
      print "Please use a host name, not an IP address.\n";
      exit 0;
   }

   # check to see if this is a valid hostname in local DNS
   # again, you should set $domain to "" if you don't have
   # your hostnames in DNS
   if ($domain ne "") {
      my $hostresult = `host $hostname`;
      if ($hostresult =~ /not found/) {
         print "$hostname doesn't appear to be a valid hostname.\n";
         print "Do you want to create a certificate anyway (y/n)? ";
         my $response = <STDIN>;
         unless ($response =~ m/^y/i) { exit 0; }
      }
   }

   # check to see if there's already a cert for this host in /var/radmind/special
   my $special_dir = "/var/radmind/special";
    if (-d "$special_dir/$hostname" ) {
      print "It looks like there's already a certificate for $hostname.\n";
      exit 0;
   }

   print "Creating certificate for $hostname...\n";

   my $ca_dir = "/var/radmind/CA";
   # generate a config file that will tell openssl req
   # how to construct the cert without prompting us
   writeConfigFile($hostname);

   # Create a certificate request and an unencrypted private key.
   # Note I make the cert valid for 3650 days, since I don't want
   # to worry about expired certs any time soon.
   `openssl req -batch -new -keyout $ca_dir/key.pem -out $ca_dir/req.pem -days 3650 -config /tmp/openssl/$hostname.cfg -nodes`;

   if ($? == 0) {
   # Sign the certificate request with the CA’s certificate and private key
      `cat $ca_dir/req.pem $ca_dir/key.pem > $ca_dir/new-req.pem`;
      `openssl ca -batch -policy policy_match -key $ca_password -out $ca_dir/out.pem -config $ca_dir/openssl.cnf -infiles $ca_dir/new-req.pem`;

      if ($? == 0) {
      # Combine the certificate and key into one file
         `cat $ca_dir/out.pem $ca_dir/key.pem > $ca_dir/$hostname-cert.pem`;
      }
   }

   # Remove temporary files
   `rm -f $ca_dir/req.pem $ca_dir/new-req.pem $ca_dir/out.pem`;

   # Make the directories radmind needs to store the cert and copy them there.
   # You will need to modify to match your environment.
   `mkdir -p /var/radmind/special/$hostname/private/var/radmind/cert/`;
   `mv $ca_dir/$hostname-cert.pem /var/radmind/special/$hostname/private/var/radmind/cert/cert.pem`;
   if ($domain ne "") {
      `ln -s /var/radmind/special/$hostname /var/radmind/special/$hostname$domain`;
   }
} else {
   print "Need a hostname!\n";
}

sub writeConfigFile {
   # this subroutine writes out a temporary openssl config file
   # to be used by openssl req to generate the certificate request
   # it must be modified for your environment

   my $hostname = $_[0];
   unless (-d "/tmp/openssl") { `mkdir "/tmp/openssl"`; }

   open CFG, ">/tmp/openssl/$hostname.cfg";

   print CFG "HOME       = .\n";
   print CFG "RANDFILE        = \$ENV::HOME/.rnd\n";
   print CFG "\n";
   print CFG "[ req ]\n";
   print CFG "default_bits    = 1024\n";
   print CFG "default_keyfile      = privkey.pem\n";
   print CFG "distinguished_name   = req_distinguished_name\n";
   print CFG "attributes      = req_attributes\n";
   print CFG "prompt          = no\n";
   print CFG "\n";
   print CFG "[ req_distinguished_name ]\n";
   # change the next line to reflect your country's 2-letter ISO code
   print CFG "C          = US\n";
   # change the next line to reflect your state or province
   print CFG "ST         = California\n";
   # change the next line to reflect your city or locality
   print CFG "L          = Burbank\n";
   # change the next line to reflect your organization
   print CFG "O          = Disney\n";
   # change the next line to reflect your organizational unit
   print CFG "OU         = Feature Animation\n";
   print CFG "CN         = $hostname\n";
   # change the next line to reflect the appropriate email address
   print CFG "emailAddress    = root\@fa.disney.com\n";
   print CFG "\n";
   print CFG "[ req_attributes ]\n";

   close CFG;
}