Root-CA
Für meine Zertifikate erstelle ich mir eine eigene Certificate Authority. Server-Zertifikate und User-Zertifikate werden jeweils von einer eigenen CA erstellt.
Es ergibt sich folgende Struktur:
Root-CA / \ Server-CA User-CA | | SCert 1 UCert 1 SCert 2 UCert 2 ... ... SCert n UCert m
Es wird das Paket openssl benötigt:
apt-get install openssl
Das Konfigurationsfile für alle 3 CAs liegt unter /etc/ssl/openssl.conf:
# OpenSSL configuration file for certificates. # 2007 by neobiker # # $Id: openssl.cnf,v 1.3 2007/02/19 11:03:40 root Exp root $ # # $Log: openssl.cnf,v $ # Revision 1.3 2007/02/19 11:03:40 root # commented out crlDistributionPoints and nsBaseUrl # deleted additional subjectAltNAme and issuerAltName # # Revision 1.2 2007/02/19 08:48:50 root # initial configuration # HOME = . RANDFILE = $ENV::HOME/.rnd # Extra OBJECT IDENTIFIER info: #oid_file = $ENV::HOME/.oid oid_section = new_oids path = /etc/ssl [ new_oids ] #################################################################### [ ca ] default_ca = Server_CA # The default ca section #################################################################### [ Root_CA ] dir = $path/RootCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crls # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/private/RCAcert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crls/crl.pem # The current CRL private_key = $dir/private/RCAkey.pem # The private key default_days = 1825 # how long to certify for default_crl_days= 365 # how long before next CRL default_md = md5 # which md to use. x509_extensions = RCA_cert # The extentions to add to the cert preserve = no policy = policy_match # default policy [ Server_CA ] dir = $path/ServerCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crls # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/private/SCAcert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crls/crl.pem # The current CRL private_key = $dir/private/SCAkey.pem # The private key default_days = 1825 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = md5 # which md to use. x509_extensions = SCA_cert # The extentions to add to the cert preserve = no policy = policy_anything # default policy [ User_CA ] dir = $path/UserCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crls # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/private/UCAcert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crls/crl.pem # The current CRL private_key = $dir/private/UCAkey.pem # The private key default_days = 730 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = md5 # which md to use. x509_extensions = UCA_cert # The extentions to add to the cert preserve = no policy = policy_match # default policy [ policy_match ] countryName = match stateOrProvinceName = supplied localityName = optional organizationName = supplied organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_anything ] countryName = match stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 2048 distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extentions to add to the self signed cert string_mask = nombstr [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = DE countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Bavaria localityName = Locality Name (eg, city) localityName_default = Nuremberg 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Company XY organizationalUnitName = Organizational Unit Name (eg, section or website) organizationalUnitName_default = Company XY CA commonName = Common Name (SERVER / USER name) #commonName_default = server.name.fqdn commonName_max = 64 emailAddress = Email Address (eg, YOUR email) emailAddress_default = your-mail-account [ req_attributes ] # Das Challenge Password dient dazu, sich bei Verlust des geheimen # Schluessels gegenueber der Herausgeber-CA fuer einen # Zertifikatswiderruf auszuweisen. Wird bei der Erstellung der # Zeritifikatsanforderung erfragt. challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = neobiker.de ################################################################## [ RCA_cert ] basicConstraints = critical, CA:TRUE keyUsage = cRLSign, keyCertSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always subjectAltName = email:copy issuerAltName = issuer:copy crlDistributionPoints = URI:http://neobiker.de/RCA.crl nsCertType = sslCA, emailCA, objCA nsBaseUrl = https://neobiker.de/ nsComment = "ausgegeben von neobiker's CA" [ SCA_cert ] # basicConstraints = critical, CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always subjectAltName = email:copy issuerAltName = issuer:copy crlDistributionPoints = URI:http://neobiker.de/SCA.crl nsCertType = server nsBaseUrl = https://neobiker.de/ nsComment = "ausgegeben von neobiker's CA (Server)" [ UCA_cert ] # basicConstraints = critical, CA:FALSE keyUsage = digitalSignature, keyEncipherment, keyAgreement subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always subjectAltName = email:copy issuerAltName = issuer:copy crlDistributionPoints = URI:http://neobiker.de/UCA.crl nsCertType = client, email nsBaseUrl = https://neobiker.de/ nsComment = "ausgegeben von neobiker's CA (User)" ################################################################# [ v3_ca ] basicConstraints = critical, CA:true keyUsage = cRLSign, keyCertSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always subjectAltName = email:copy issuerAltName = issuer:copy crlDistributionPoints = URI:http://neobiker.de/RCA.crl nsCertType = sslCA, emailCA, objCA nsBaseUrl = https://neobiker.de/ nsComment = "ausgegeben von neobiker's CA" [ crl_ext ] issuerAltName = issuer:copy authorityKeyIdentifier = keyid:always,issuer:always
Jetzt lege ich unter /etc/ssl die Verzeichnisse und die CAs an:
#!/bin/sh # RootCA + Server-CA + UserCA erstellen # # $Id: mk_ca_struct,v 1.1 2007/02/19 11:44:22 root Exp root $ # # $Log: mk_ca_struct,v $ # Revision 1.1 2007/02/19 11:44:22 root # Initial revision # cd /etc/ssl rm -i certs/* private/* rm -rf RootCA ServerCA UserCA cat <<EOF Erstelle eine Root CA: EOF mkdir RootCA cd RootCA mkdir certs newcerts private chmod go-rwx private echo "01" > serial touch index.txt cd .. openssl req -newkey rsa:2048 -x509 -days 1825 \ -out RootCA/private/RCAcert.pem -outform PEM \ -keyout RootCA/private/RCAkey.pem cp RootCA/private/RCAcert.pem certs/00.pem cd certs c_rehash . cd .. cat <<EOF Erstelle eine Server CA die von Root CA signiert wurde: EOF cd /etc/ssl mkdir ServerCA cd ServerCA mkdir certs newcerts private chmod go-rwx private echo "01" > serial touch index.txt cd .. openssl req -newkey rsa:2048 -days 1825 \ -out ServerCA/private/SCAreq.pem -outform PEM \ -keyout ServerCA/private/SCAkey.pem openssl ca -name Root_CA -in ServerCA/private/SCAreq.pem \ -out ServerCA/private/SCAcert.pem cp ServerCA/private/SCAcert.pem certs/01.pem cd certs c_rehash . cd .. cat <<EOF Erstelle eine User CA die von Root CA signiert wurde: EOF cd /etc/ssl mkdir UserCA cd UserCA mkdir certs newcerts private chmod go-rwx private echo "01" > serial touch index.txt cd .. openssl req -newkey rsa:2048 -days 1825 \ -out UserCA/private/UCAreq.pem -outform PEM \ -keyout UserCA/private/UCAkey.pem openssl ca -name Root_CA -in UserCA/private/UCAreq.pem \ -out UserCA/private/UCAcert.pem cp UserCA/private/UCAcert.pem certs/02.pem cd certs c_rehash . cd ..
Im Anschluss erzeuge ich mir für den Cyrus-Imap-Server mein erstes Server-Zertifikat mit folgendem Script:
#!/bin/sh # # $Id: mk_cert_server,v 1.4 2007/01/07 15:34:54 root Exp root $ # # $Log: mk_cert_server,v $ # Revision 1.4 2007/01/07 15:34:54 root # little beatifying # # Revision 1.3 2007/01/07 15:26:38 root # chmod settings changed # pwd=`pwd` dir=/etc/ssl cd $dir echo "" echo -n "Server-Cert Name: " read cert [ -z "$cert" ] && exit 1 echo "Schluessel (Key) und Zertifikatanfrage (Req) ..." echo "" openssl req -newkey rsa:1024 -keyout ${cert}Key.pem -keyform PEM \ -out ${cert}Req.pem -outform PEM # Zum Start des Server's das Passwort aus dem Schluessel entfernen echo "" echo -n "Passwort aus Zertifikate-Schluessel entfernen [y] ? " read a if [ -z "$a" -o "$a" == "y" -o "$a" == "Y" ]; then openssl rsa < ${cert}Key.pem > ${cert}-Key.pem chmod go-rwx ${cert}-Key.pem ${cert}Key.pem mv ${cert}-Key.pem $dir/private fi mv ${cert}Key.pem $dir/private echo "" echo "Zertifikat erstellen / signieren ..." echo "" openssl ca -name Server_CA -in ${cert}Req.pem -out ${cert}Cert.pem chmod go-rwx $dir/${cert}Cert.pem mv ${cert}Cert.pem $dir/certs mv ${cert}Req.pem $dir/private echo "" ls -l $dir/certs $dir/private echo ""
xen1:/etc/ssl# ./scripts/mk_cert_server Server-Cert Name: imap Schluessel (Key) und Zertifikatanfrage (Req) ... Generating a 1024 bit RSA private key .................++++++ ...................................++++++ writing new private key to 'imapKey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [DE]: State or Province Name (full name) [Bavaria]: Locality Name (eg, city) [Nuremberg]: Organization Name (eg, company) [neobiker.de]: Organizational Unit Name (eg, section or website) [neobiker's CA]: Common Name (SERVER / USER name) []:imap.fqdn Email Address (eg, YOUR email) [yourmail]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: neobiker.de []: Passwort aus Zertifikate-Schluessel entfernen [y] ? Enter pass phrase: writing RSA key Zertifikat erstellen / signieren ... Using configuration from /usr/lib/ssl/openssl.cnf Enter pass phrase for /etc/ssl/ServerCA/private/SCAkey.pem: Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'DE' stateOrProvinceName :PRINTABLE:'Bavaria' localityName :PRINTABLE:'Nuremberg' organizationName :PRINTABLE:'neobiker.de' organizationalUnitName:PRINTABLE:'neobikers CA' commonName :PRINTABLE:'imap.fqdn' emailAddress :IA5STRING:'yourmail' Certificate is to be certified until Feb 18 11:19:49 2012 GMT (1825 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated /etc/ssl/certs: total 28 -rw-r--r-- 1 root root 2061 2007-02-19 12:15 00.pem -rw-r--r-- 1 root root 5917 2007-02-19 12:16 01.pem -rw-r--r-- 1 root root 5911 2007-02-19 12:17 02.pem lrwxrwxrwx 1 root root 6 2007-02-19 12:17 51c08bfb.0 -> 01.pem lrwxrwxrwx 1 root root 6 2007-02-19 12:17 545678ed.0 -> 00.pem lrwxrwxrwx 1 root root 6 2007-02-19 12:17 eb8ee7de.0 -> 02.pem -rw------- 1 root root 5317 2007-02-19 12:19 imapCert.pem /etc/ssl/private: total 12 -rw------- 1 root root 891 2007-02-19 12:19 imap-Key.pem -rw------- 1 root root 963 2007-02-19 12:19 imapKey.pem -rw-r--r-- 1 root root 761 2007-02-19 12:19 imapReq.pem
Das File imap-Key-pem ist dabei der private Schlüssel ohne Passwort, damit der Server ohne Passwort-Eingabe den Cyrus starten kann. Die beiden Files private/imap-Key.pem und certs/imapCert-pem kopiere ich auf meinen Imap-Server nach /etc/ssl und trage diese Zertifikate in das Konfigfile /etc/imapd.cond auf dem Imap-Server ein:
scp certs/imap.Cert.pem imap:/etc/ssl/certs scp private/imap-Key.pem imap:/etc/ssl/private
Ein Test sieht so aus:
xen1:/etc/ssl# openssl s_client -CApath /etc/ssl/certs -port 993 -host imap > /tmp/foo depth=2 /C=DE/ST=Bavaria/L=Nuremberg/O=neobiker.de/OU=neobiker's User-CA/CN=imap.fqdn/emailAddress=yourmail verify return:1 depth=1 /C=DE/ST=Bavaria/L=Nuremberg/O=neobiker.de/OU=neobiker's Server-CA/CN=imap.fqdn/emailAddress=yourmail verify return:1 depth=0 /C=DE/ST=Bavaria/L=Nuremberg/O=neobiker.de/OU=neobiker's CA/CN=imap.fqdn/emailAddress=yourmail verify return:1 CTRL-C