makecert
Revised: 2006-09-22 richard
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;
}