Mit der SNI-Technik (Server Name Indication, Wikipedia) ist es möglich, unter einer IP-Adresse mehrere virtuelle Hosts zu betreiben. Da das SSL-Zertifikat die Verbindung absichert, bevor der Zieldomainnamen übertragen wird, muss das Webserver-Zertifikat für alle Domains ausgestellt sein. Daraus ergibt sich auch der Nebeneffekt, dass www.example.com, example.com und *.example.com abgesichert werden können.
Grundlage ist das Perl-Script, dass unter http://wiki.cacert.org/VhostTaskForce#Perl_version abrufbar ist.
use strict; my $config_file = "/tmp/openssl.cnf.$$"; #Where to write the config file my $keyname; #Generally, the primary FQDN my $org_unit; #Organisational unit for csr, ie Web Services my @altnames; #Alternate dns names for csr, ie www1.example.com, www1.example.net etc my $altname; #Alternate dns names for csr, ie www1.example.com, www1.example.net etc my $altcount = 1; #Can only have 16 or less alts (when submitting to Verisign) my $altflag = 1; #flag for my while loop my @config_out; #Populate with all info for the config file. my $email_address; #email address to be tagged on the certificate my $proc_base_name; #basename of the process, simply for naming conventions my $mutual_tls = "y"; #flag for mutual tls for client app stuff my $home = `echo \$HOME`; #Get user's home directory to store files in. chomp $home; my $random_file = "$home/.rnd"; #openssl for hpux needs a .rnd file to work # If config file exists, exit and alert user if (-e $config_file) { `rm $config_file`; } if (!-e $random_file) { `dd bs=512 count=4 if=/dev/null of=$random_file` ##die ("Random file couldn't be found at $random_file\n"); } # Open config file to write ssl stuff out to open (CONFIG, ">$config_file")||die "Can't open $config_file for writing\n"; # Start getting info from user print ("Generate SSL Cert stuff for SAPI\n"); print ("FQDN/Keyname for Cert \(ie www.example.com\)\t\t:"); chomp ($keyname=); while ($altflag) { print ("Alt Names (ie www1.example.com or for none)\t\t\t:"); chomp($altname= ); if ($altcount 16) { if ($altname eq $keyname) { print (" ****** Alternate name can not equal main keyname ******\n"); } elsif ($altname ne "") { push (@altnames, "DNS:$altname"); $altcount++; } else { $altflag=0; } } else { $altflag=0; } } print ("Host short name (ie imap big_srv etc)\t\t\t\t:"); chomp ($proc_base_name= ); # Start building the config file push (@config_out, "# -------------- BEGIN custom openssl.cnf -----\n"); push (@config_out, "HOME = $home\n"); push (@config_out, "RANDFILE = $random_file\n"); push (@config_out, "oid_section = new_oids\n"); push (@config_out, "[ new_oids ]\n"); push (@config_out, "[ req ]\n"); push (@config_out, "default_bits = 2048\n"); push (@config_out, "default_days = 730 # how long to certify for\n"); push (@config_out, "default_keyfile = $home/${proc_base_name}_privatekey.pem\n"); push (@config_out, "distinguished_name = req_distinguished_name\n"); push (@config_out, "encrypt_key = no\n"); push (@config_out, "string_mask = nombstr\n"); push (@config_out, "req_extensions = v3_req # Extensions to add to certificate request\n"); push (@config_out, "[ req_distinguished_name ]\n"); push (@config_out, "commonName = Common Name (eg, YOUR name)\n"); push (@config_out, "commonName_default = $keyname\n"); push (@config_out, "commonName_max = 64\n"); push (@config_out, "[ v3_req ]\n"); if (@altnames[0] ne "") { $altname=join(',', @altnames); push (@config_out, "subjectAltName=$altname\n"); } push (@config_out, "# -------------- END OpsSec-provided openssl.cnf -----\n"); # Write shit to file print (CONFIG "@config_out"); close CONFIG; # Generate ssl stuff print ("\nAttempting openssl...\n"); system ("openssl req -batch -config $config_file -newkey rsa:2048 -out $home/${proc_base_name}_csr.pem"); print ("\nwriting csr to $home/${proc_base_name}_csr.pem...\n\n"); print ("Take the contents of $home/${proc_base_name}_csr.pem and go submit them to receive an SSL ID. When you receive your public key back, you 'should' name it something like '${proc_base_name}_server.pem'. "); `rm $config_file`;
Es kann mit folgenden Eingaben gefüttert werden:
www.example.com *.example.com example.com example.com
Damit werden im Benutzerverzeichnis die Dateien example.com_privatekey.pem und example.com_csr.pem erzeugt. Die csr-Datei ist die Zertifikatsanforderungsdatei, die nun bei einer Zertifikatsautorität eingereicht werden kann.
Von dort erhält man ein unterschriebenes Zertifikat, dass in der Apache-Datei /etc/apache2/ssl.crt/server.crt eingetragen wird.
Der private Teil des Schlüssels wird in der Datei /etc/apache2/ssl.key/server.key abgelegt.