Custom CA Certificate

From SME Server
Jump to navigationJump to search

Is this article helpful to you?
Please consider donating or volunteering
Thank you!

Introduction

From wikipedia


CAcert.org is a community-driven certificate authority that issues free public key certificates to the public (unlike other certificate authorities which are commercial and sell certificates). CAcert has over 200,000 verified users and has issued nearly 800,000 certificates as of January 2012. These certificates can be used to digitally sign and encrypt email, authenticate and authorize users connecting to websites and secure data transmission over the Internet. Any application that supports the Secure Socket Layer (SSL) can make use of certificates signed by CAcert, as can any application that uses X.509 certificates, e.g. for encryption or code signing and document signatures.

Prerequisites

  • An account on cacert.org
    • Your domain(s) registered on your CAcert.org account


creating .csr and .key files

As root do the following:

mkdir ~/cacert
cd ~/cacert 
  • Create a file named cacert_csr_request
nano -w cacert_csr_request
#!/usr/bin/perl

use strict;
use esmith::util;
use esmith::ConfigDB;
use esmith::DomainsDB;

# variable to edit
my $keycrypt = 2048;
my $KEYLIFEINDAYS = 730;
my $COUNTRYCODE = "US";  ## <===================== change to your country code !
# end of modifications

my $config   = esmith::ConfigDB->open;
my $domainsdb = esmith::DomainsDB->open_ro;

my $domain = $config->get('DomainName')->value;
my %domain_names = map { $_->{key} => 1 } grep { $_->key ne $domain } $domainsdb->domains;

my @domains = ($domain, keys %domain_names);

open(CONFIG, ">$domains[0].config") or die "Can't open openssl config file: $!";
print CONFIG "HOME = .\nRANDFILE = \$ENV::HOME/.rnd\n\n";
print CONFIG "[ req ]\ndefault_bits = $keycrypt\ndistinguished_name = req_distinguished_name\n";
# if you need a SHA1 csr, uncomment the following row
#print CONFIG "default_md  = sha1\n";
print CONFIG "req_extensions = v3_req\nprompt = no\n\n";
print CONFIG "[ req_distinguished_name ]\nCN = $domains[0]\n";
print CONFIG "countryName = $COUNTRYCODE\n";
print CONFIG "[ v3_req ]\nbasicConstraints = CA:FALSE\nkeyUsage = nonRepudiation,digitalSignature,keyEncipherment\n";
print CONFIG "subjectAltName = critical,", join ",", map { "DNS:$_,DNS:*.$_" } @domains;
print CONFIG "\n";
close(CONFIG) or die "Closing openssl config file reported: $!";


unless ( -f "$domains[0].key" )
{
    open(KEY, ">$domains[0].key") or die "Can't open key file: $!";
    unless (open(SSL,"-|"))
    {
        exec("/usr/bin/openssl",
            qw(genrsa -rand),
            join(':',
            qw(
                /proc/apm
                /proc/cpuinfo
                /proc/dma
                /proc/filesystems
                /proc/interrupts
                /proc/ioports
                /proc/bus/pci/devices
                /proc/rtc
                /proc/uptime
                )),
            $keycrypt)
            || die "can't exec program: $!";
    }
    while (<SSL>)
    {
        print KEY $_;
    }
    close(SSL) or die "Closing openssl pipe reported: $!";
    close(KEY) or die "Closing key file reported: $!";
}

open(CSR, ">$domains[0].csr") or die "Can't open csr $!";
unless (open(SSL,"-|"))
{
    exec("/usr/bin/openssl",
        qw(req -config), "$domains[0].config",
        qw(-new -key), "$domains[0].key",
        qw(-days $KEYLIFEINDAYS -set_serial), time())
        || die "can't exec program: $!";
}
while (<SSL>)
{
    print CSR $_;
}
close(SSL) or die "Closing openssl pipe reported: $!";
close(CSR) or die "Closing csr file reported: $!";


  • modify the 3 variables in the script according to your needs
# variable to edit
my $keycrypt = 2048; #<= must be a 1024 multiple; some CA authorities ask for at least 2048
my $KEYLIFEINDAYS = 730; # <= validity of the Certificate in days must be greater (or at least equal)than the validity of the one you are buying
my $COUNTRYCODE = "US";  ## <===================== change to your country code !
# end of modifications
  • Change permissions
chmod u+x cacert_csr_request
  • Execute the file
./cacert_csr_request

From here replace the {domain} tag with your Primary domain name. Also you will need to have all domains registered with your cacert.org account. This will create a certificate that includes all domains that exists on your sme box as both simple domain.com and wildcard *.domain.com.

footnotes

This script is helpful but incomplete. Some configurations info are missing in order to obtain a cert from some CA Authorities (http://www.flatmtn.com/article/setting-openssl-create-certificates) .Some of the information needed are missing in the smeserver database like countrycode you have to insert them in the code for the moment...

obtain .crt file from cacert

  • Log into you account on the cacert.org and Add your FQDN under domains
  • and paste the output of the belowcommand under new server certificate
cat {domain}.csr

configuring your sme with your new certificate

Then save your CA certificate in a file named ~/cacert/{domain}.crt

  • Copy to final location
cp {domain}.crt /home/e-smith/ssl.crt/{domain}.crt 
cp {domain}.key /home/e-smith/ssl.key/{domain}.key

you might have to add an Intermediate certificate from the SSL authority

cp {CA}.crt /home/e-smith/ssl.crt/{CA}.crt
  • Configure SME database
config setprop modSSL crt /home/e-smith/ssl.crt/{domain}.crt
config setprop modSSL key /home/e-smith/ssl.key/{domain}.key

If you have to add an Intermediate certificate from the SSL authority

config setprop modSSL CertificateChainFile /home/e-smith/ssl.crt/{CA}.crt
  • and apply the changes
signal-event post-upgrade
signal-event reboot

or if you do not want to reboot your server:

signal-event domain-modify
signal-event email-update

Once you have created/installed this certificate then if the client has the cacert.org root certificate installed then they should be able to go to any domain on your box and not get a warning.

References