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 Friedrich-net.DE 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://friedrich-net.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