Root-CA: Unterschied zwischen den Versionen

Aus Neobikers Wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
 
(8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 17: Zeile 17:
</pre>
</pre>


Folgendes Script '''mk_ca_struct''' legt in einem beliebigen Verzeichnis obige CA-Struktur an. Es benötigt eine angepasste '''openssl.cnf.tpl''' Datei, welche im gleichen Verzeichnis wie das Script selbst liegen muss: '''./scripts'''
Folgendes Script '''[[CA mk_ca_struct|mk_ca_struct]]''' legt in einem beliebigen Verzeichnis obige CA-Struktur im Filesystem an. Es benötigt eine angepasste '''[[CA openssl.cnf.tpl|openssl.cnf.tpl]]''' Datei, welche im gleichen Verzeichnis wie das Script selbst liegen muss: '''./scripts'''


<pre>
<pre>
Zeile 27: Zeile 27:
-rwxr-xr-x root/root      1564 2008-06-26 22:35 ca/scripts/mk_cert_user
-rwxr-xr-x root/root      1564 2008-06-26 22:35 ca/scripts/mk_cert_user
-rwxr--r-- root/root      2892 2008-06-26 22:49 ca/scripts/mk_ca_struct
-rwxr--r-- root/root      2892 2008-06-26 22:49 ca/scripts/mk_ca_struct
</pre>
'''./scripts/openssl.cnf.tpl'''
<pre>
# OpenSSL configuration file for certificates.
# 2007 by neobiker
#
# $Id: openssl.cnf.tpl,v 1.1 2008/06/26 20:35:28 root Exp root $
#
# $Log: openssl.cnf.tpl,v $
# Revision 1.1  2008/06/26 20:35:28  root
# Initial revision
#
[ 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    = Bayern
localityName                    = Locality Name (eg, city)
localityName_default            = Nuernberg
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = OrganisationName
organizationalUnitName          = Organizational Unit Name (eg, section or website)
organizationalUnitName_default  = OrganisationUnit
commonName                      = Common Name (SERVER / USER name)
#commonName_default            = server.company.de
commonName_max                  = 64
emailAddress                    = Email Address (eg, YOUR email)
emailAddress_default            = webmaster@company.de
[ 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                = company.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://company.homeip.net/RCA.crl
nsCertType              = sslCA, emailCA, objCA
#nsBaseUrl              = https://company.de/
nsComment              = "issued by company.de 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://company.homeip.net/SCA.crl
nsCertType              = server
nsBaseUrl              = https://company.de/
nsComment              = "issued by company.de (Server CA)"
[ 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://company.homeip.net/UCA.crl
nsCertType              = client, email
#nsBaseUrl              = https://company.de/
nsComment              = "issued by company.de (User CA)"
#################################################################
[ v3_ca ]
basicConstraints        = critical, CA:true
keyUsage                = cRLSign, keyCertSign
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer:always
subjectAltName          = email:copy
issuerAltName          = issuer:copy
#crlDistributionPoints  = URI:http://company.de/RCA.crl
nsCertType              = sslCA, emailCA, objCA
#nsBaseUrl              = https://company.de/
nsComment              = "issued by company.de CA"
[ crl_ext ]
issuerAltName          = issuer:copy
authorityKeyIdentifier  = keyid:always,issuer:always
</pre>
'''./scripts/mk_ca_struct'''
<pre>
#!/bin/sh
# RootCA + Server-CA + UserCA erstellen
#
# $Id: mk_ca_struct,v 1.2 2008/06/26 20:49:58 root Exp root $
#
# $Log: mk_ca_struct,v $
# Revision 1.2  2008/06/26 20:49:58  root
# *** empty log message ***
#
# Revision 1.1  2008/06/26 20:35:28  root
# Initial revision
#
#
absolute_dir ()
{
    [ -d "$1" ] || exit 1
    pushd "$1" >/dev/null
    pwd
    popd >/dev/null
}
bdir=`dirname $0`
pwd=`pwd`
echo -n "Where to install the CA directories [$pwd] "
read a
if [ -z "$a" ]; then
    CA_DIR=$pwd
else
    [ -d "$1" ] || mkdir $a
    CA_DIR=`absolute_dir $a`
fi
if [ -d $CA_DIR/certs ]; then
    echo -n "Warning: $CA_DIR/certs found - delete all [n] "
    read b
    if [ -z "$b" -o "$b" == "n" -o "$b" == "N" ]; then
        echo "OK, exiting"
        exit 0
    fi
else
    [ -d $CA_DIR ] || mkdir $CA_DIR
fi
cp -r $bdir $CA_DIR
pushd $CA_DIR
rm -rf certs private RootCA ServerCA UserCA 2>/dev/null
mkdir certs private
cat <<EOF > openssl.cnf
# openssl.cnf by neobiker
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
path = $CA_DIR
EOF
cat scripts/openssl.cnf.tpl >> openssl.cnf
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 -config openssl.cnf \
            -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 (signiert von Root CA):
EOF
cd $CA_DIR
mkdir ServerCA
cd ServerCA
mkdir certs newcerts private
chmod go-rwx private
echo "01" > serial
touch index.txt
cd ..
openssl req -config openssl.cnf \
            -newkey rsa:2048 -days 1825 \
            -out    ServerCA/private/SCAreq.pem -outform PEM \
            -keyout ServerCA/private/SCAkey.pem
openssl ca -config openssl.cnf \
          -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 (signiert von Root CA):
EOF
cd $CA_DIR
mkdir UserCA
cd UserCA
mkdir certs newcerts private
chmod go-rwx private
echo "01" > serial
touch index.txt
cd ..
openssl req -config openssl.cnf \
            -newkey rsa:2048 -days 1825 \
            -out    UserCA/private/UCAreq.pem -outform PEM \
            -keyout UserCA/private/UCAkey.pem
openssl ca -config openssl.cnf \
          -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 ..
popd
</pre>
</pre>


Zeile 568: Zeile 189:
</pre>
</pre>


 
Im Anschluss erzeuge mein Server Zertifikat mit '''[[CA mk_cert_server|mk_cert_server]]''' z.B. für einen Imap-Server (analog mit '''[[CA mk_cert_user|mk_cert_user]]''' für User):
'''./scripts/mk_cert_server'''
<pre>
#!/bin/sh
#
# $Id: mk_cert_server,v 1.1 2008/06/26 20:35:28 root Exp root $
#
# $Log: mk_cert_server,v $
# Revision 1.1  2008/06/26 20:35:28  root
# Initial revision
#
 
absolute_dir ()
{
    pushd $1 >/dev/null
    pwd
    popd >/dev/null
}
 
dir=`dirname $0`
dir=`absolute_dir $dir/..`
pushd $dir
 
echo ""
echo -n "Server-Cert Name: "
read cert
 
[ -z "$cert" ] && popd && exit 1
 
if [ -e private/${cert}Key.pem ]; then
    echo "Error: private/${cert}Key.pem exists!"
    ls -l */${cert}*
    exit 1
fi
 
echo "--------"
echo "${cert}Key.pem & ${cert}Req.pem ..."
echo ""
 
openssl req -config openssl.cnf \
            -newkey rsa:1024 \
            -keyout ${cert}Key.pem -keyform PEM \
            -out    ${cert}Req.pem -outform PEM
 
echo ""
echo -n "Passwort aus ${cert}Key.pem 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
    cp ${cert}-Key.pem private
    mv ${cert}-Key.pem ServerCA/private
fi
cp ${cert}Key.pem private
mv ${cert}Key.pem ServerCA/private
 
echo "===================="
echo "${cert}Cert.pem  ..."
echo "===================="
 
openssl ca -config openssl.cnf \
          -name Server_CA \
          -in  ${cert}Req.pem \
          -out  ${cert}Cert.pem
 
chmod go-rwx ${cert}Cert.pem
cp ${cert}Cert.pem certs
mv ${cert}Cert.pem ServerCA/certs
mv ${cert}Req.pem  ServerCA/private
 
echo "----------------------------------------------"
echo ""
ls -l certs private
echo ""
 
popd
</pre>
 
Im Anschluss erzeuge ich mir für z.B. Cyrus-Imap-Server mein erstes Server-Zertifikat mit folgendem Script:


<pre>
<pre>
Zeile 656: Zeile 195:
~/ca ~/ca
~/ca ~/ca


Server-Cert Name: imap
Server-Cert Name: apache
--------
--------
imapKey.pem & imapReq.pem ...
apacheKey.pem & apacheReq.pem ...


Generating a 1024 bit RSA private key
Generating a 1024 bit RSA private key
....................++++++
...............................++++++
......................................++++++
.....................++++++
unable to write 'random state'
unable to write 'random state'
writing new private key to 'imapKey.pem'
writing new private key to 'apacheKey.pem'
Enter PEM pass phrase:
Enter PEM pass phrase: >>apache Passwort<<
Verifying - Enter PEM pass phrase:
Verifying - Enter PEM pass phrase: >>apache Passwort<<
-----
-----
You are about to be asked to enter information that will be incorporated
You are about to be asked to enter information that will be incorporated
Zeile 680: Zeile 219:
Organization Name (eg, company) [OrganisationName]:
Organization Name (eg, company) [OrganisationName]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Common Name (SERVER / USER name) []:imap.company.de
Common Name (SERVER / USER name) []:apache
Email Address (eg, YOUR email) [webmaster@company.de]:
Email Address (eg, YOUR email) [webmaster@company.de]:


Zeile 688: Zeile 227:
company.de []:
company.de []:


Passwort aus imapKey.pem entfernen [y] ?
Passwort aus apacheKey.pem entfernen [y] ?
Enter pass phrase:
Enter pass phrase: >>apache Passwort<<
writing RSA key
writing RSA key
====================
====================
imapCert.pem  ...
apacheCert.pem  ...
====================
====================
Using configuration from openssl.cnf
Using configuration from openssl.cnf
Enter pass phrase for /root/ca/ServerCA/private/SCAkey.pem:
Enter pass phrase for /root/ca/ServerCA/private/SCAkey.pem: >>ServerCA Passwort<<
Check that the request matches the signature
Check that the request matches the signature
Signature ok
Signature ok
Zeile 704: Zeile 243:
organizationName      :PRINTABLE:'OrganisationName'
organizationName      :PRINTABLE:'OrganisationName'
organizationalUnitName:PRINTABLE:'OrganisationUnit'
organizationalUnitName:PRINTABLE:'OrganisationUnit'
commonName            :PRINTABLE:'imap.company.de'
commonName            :PRINTABLE:'apache'
emailAddress          :IA5STRING:'webmaster@company.de'
emailAddress          :IA5STRING:'webmaster@company.de'
Certificate is to be certified until Jun 26 18:20:44 2013 GMT (1825 days)
Certificate is to be certified until Jun 27 16:58:02 2013 GMT (1825 days)
Sign the certificate? [y/n]:y
Sign the certificate? [y/n]:y


Zeile 717: Zeile 256:


certs:
certs:
total 28
total 36
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 00.pem
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 00.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
Zeile 723: Zeile 262:
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 47efd334.0 -> 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 47efd334.0 -> 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 9c05fe89.0 -> 00.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 9c05fe89.0 -> 00.pem
-rw------- 1 root root 4888 2008-06-28 18:58 apacheCert.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 b99e5d4b.0 -> 01.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 b99e5d4b.0 -> 01.pem
-rw------- 1 root root 4909 2008-06-27 20:20 imapCert.pem


private:
private:
total 8
total 24
-rw------- 1 root root 887 2008-06-27 20:20 imap-Key.pem
-rw------- 1 root root 887 2008-06-28 18:57 apache-Key.pem
-rw------- 1 root root 963 2008-06-27 20:20 imapKey.pem
-rw------- 1 root root 963 2008-06-28 18:57 apacheKey.pem


~/ca
~/ca
scx:~/ca#
</pre>
</pre>


Ein Test sieht so aus:
Das Zertifikat verwende ich für den Apache Webserver und teste es anschliessend.
Es gibt zwei Key-Files für das Zertifikat '''apacheCert.pem''', eins mit Passwort ('''apacheKey.req'''), das andere ('''apache-Key.req''') ohne Passwort, damit der Server automatisch starten kann, ohne das ein Passwort erfragt wird.
<pre>
<pre>
scx:/root/ca# openssl s_client -CApath /root/ca/certs -port 993 -host imap > /tmp/foo
scx:~/ca# cat /etc/apache2/sites-enabled/default-ssl
...
NameVirtualHost *:443
 
<VirtualHost *:443>
        ServerName apache.company.de
        ServerAdmin webmaster@company.de
 
        SSLEngine On
        SSLCipherSuite HIGH:MEDIUM
        SSLCertificateFile /root/ca/certs/apacheCert.pem
        SSLCertificateKeyFile /root/ca/ServerCA/private/apache-Key.pem
 
        # SSLProxyEngine On
 
        CustomLog /var/log/apache2/access_https.log combined
        ErrorLog  /var/log/apache2/error_https.log
 
        # debug, info, notice, warn, error, crit, alert, emerg
        LogLevel warn
 
        ServerSignature Off
 
        DocumentRoot /var/www/
 
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
 
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride AuthConfig
                Order allow,deny
                allow from all
                RedirectMatch ^/$ /apache2-default/
        </Directory>
 
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
 
        Alias /debian-doc/ /usr/share/doc/
        <Directory /usr/share/doc/>
                Options Indexes MultiViews FollowSymLinks
                AllowOverride None
                Order deny,allow
                Allow from all
        </Directory>
 
</VirtualHost>
</pre>
<pre>
scx:~/ca# /etc/init.d/apache2 restart
</pre>
 
Ein Test (nach der Installation des Zertifikates auf dem lokalem Webserver) sieht dann so aus, man sieht die mehrstufige Hierarchie der Zertifikate bzw. CA inkl. ServerCA und rootCA.
<pre>
scx:~/ca# openssl s_client -CApath /root/ca/certs -port 443 -host localhost > /tmp/foo
depth=2 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=rootCA/emailAddress=webmaster@company.de
verify return:1
depth=1 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=serverCA/emailAddress=webmaster@company.de
verify return:1
depth=0 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=apache/emailAddress=webmaster@company.de
verify return:1
 
>>CTRL-C<<
</pre>
 
Im Anschluss habe ich folgende Verzeichnisstruktur:
<pre>
scx:~/ca# ls -lR
.:
total 32
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 certs/
-rw-r--r-- 1 root root 6657 2008-06-27 20:03 openssl.cnf
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 private/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 RootCA/
drwxr-sr-x 2 root root 4096 2008-06-27 19:57 scripts/
drwxr-xr-x 5 root root 4096 2008-06-27 20:20 ServerCA/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 UserCA/
 
./certs:
total 28
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 00.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 47efd334.0 -> 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 9c05fe89.0 -> 00.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 b99e5d4b.0 -> 01.pem
-rw------- 1 root root 4909 2008-06-27 20:20 apacheCert.pem
 
./private:
total 8
-rw------- 1 root root 887 2008-06-27 20:20 apache-Key.pem
-rw------- 1 root root 963 2008-06-27 20:20 apacheKey.pem
 
./RootCA:
total 36
drwxr-xr-x 2 root root 4096 2008-06-27 20:03 certs/
-rw-r--r-- 1 root root  280 2008-06-27 20:04 index.txt
-rw-r--r-- 1 root root  20 2008-06-27 20:04 index.txt.attr
-rw-r--r-- 1 root root  21 2008-06-27 20:04 index.txt.attr.old
-rw-r--r-- 1 root root  141 2008-06-27 20:04 index.txt.old
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:03 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial.old
 
./RootCA/certs:
total 0
 
./RootCA/newcerts:
total 16
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 02.pem
 
./RootCA/private:
total 8
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 RCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:03 RCAkey.pem
 
./scripts:
total 20
-rwxr--r-- 1 root root 2892 2008-06-26 22:49 mk_ca_struct*
-rwxr-xr-x 1 root root 1550 2008-06-27 20:19 mk_cert_server*
-rwxr-xr-x 1 root root 1555 2008-06-27 20:31 mk_cert_user*
-rw-r--r-- 1 root root 6500 2008-06-27 19:11 openssl.cnf.tpl
 
./ServerCA:
total 28
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 certs/
-rw-r--r-- 1 root root  148 2008-06-27 20:20 index.txt
-rw-r--r-- 1 root root  21 2008-06-27 20:20 index.txt.attr
-rw-r--r-- 1 root root    0 2008-06-27 20:03 index.txt.old
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:20 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:20 serial
-rw-r--r-- 1 root root    3 2008-06-27 20:03 serial.old
 
./ServerCA/certs:
total 8
-rw------- 1 root root 4909 2008-06-27 20:20 apacheCert.pem
 
./ServerCA/newcerts:
total 8
-rw-r--r-- 1 root root 4909 2008-06-27 20:20 01.pem
 
./ServerCA/private:
total 28
-rw------- 1 root root  887 2008-06-27 20:20 apache-Key.pem
-rw------- 1 root root  963 2008-06-27 20:20 apacheKey.pem
-rw-r--r-- 1 root root  737 2008-06-27 20:20 apacheReq.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 SCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:04 SCAkey.pem
-rw-r--r-- 1 root root 1082 2008-06-27 20:04 SCAreq.pem
 
./UserCA:
total 16
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 certs/
-rw-r--r-- 1 root root    0 2008-06-27 20:04 index.txt
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:04 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial
 
./UserCA/certs:
total 0
 
./UserCA/newcerts:
total 0
 
./UserCA/private:
total 16
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 UCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:04 UCAkey.pem
-rw-r--r-- 1 root root 1078 2008-06-27 20:04 UCAreq.pem
</pre>
</pre>

Aktuelle Version vom 28. Juni 2008, 18:28 Uhr

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

Folgendes Script mk_ca_struct legt in einem beliebigen Verzeichnis obige CA-Struktur im Filesystem an. Es benötigt eine angepasste openssl.cnf.tpl Datei, welche im gleichen Verzeichnis wie das Script selbst liegen muss: ./scripts

scx:~# tar tvjf ca-scripts.tgz
drwxr-xr-x root/root         0 2008-06-27 19:00 ca/
drwxr-sr-x root/root         0 2008-06-27 19:57 ca/scripts/
-rw-r--r-- root/root      6500 2008-06-27 19:11 ca/scripts/openssl.cnf.tpl
-rwxr-xr-x root/root      1559 2008-06-26 22:35 ca/scripts/mk_cert_server
-rwxr-xr-x root/root      1564 2008-06-26 22:35 ca/scripts/mk_cert_user
-rwxr--r-- root/root      2892 2008-06-26 22:49 ca/scripts/mk_ca_struct

Zuerst lege ich die CA Struktur mit den entsprechenden Zertifikaten an:

scx:~/ca# ./scripts/mk_ca_struct
Where to install the CA directories [/root/ca] /root/ca
mkdir: cannot create directory `/root/ca': File exists
cp: `./scripts' and `/root/ca/scripts' are the same file
~/ca ~/ca

----------------------
Erstelle eine Root CA:

Generating a 2048 bit RSA private key
..................................................................+++
...........+++
unable to write 'random state'
writing new private key to 'RootCA/private/RCAkey.pem'
Enter PEM pass phrase: >>rootCA-Password<<
Verifying - Enter PEM pass phrase: >>rootCA-Password<<
-----
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) [Bayern]:
Locality Name (eg, city) [Nuernberg]:
Organization Name (eg, company) [OrganisationName]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Common Name (SERVER / USER name) []:rootCA
Email Address (eg, YOUR email) [webmaster@company.de]:
Doing .
00.pem => 9c05fe89.0


----------------------------------------------
Erstelle eine Server CA (signiert von Root CA):

Generating a 2048 bit RSA private key
.+++
....................................................................+++
unable to write 'random state'
writing new private key to 'ServerCA/private/SCAkey.pem'
Enter PEM pass phrase: >>ServerCA-Password<<
Verifying - Enter PEM pass phrase: >>ServerCA-Password<<
-----
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) [Bayern]:
Locality Name (eg, city) [Nuernberg]:
Organization Name (eg, company) [OrganisationName]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Common Name (SERVER / USER name) []:serverCA
Email Address (eg, YOUR email) [webmaster@company.de]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
company.de []:
Using configuration from openssl.cnf
Enter pass phrase for /root/ca/RootCA/private/RCAkey.pem: >>rootCA-Password<<
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'Bayern'
localityName          :PRINTABLE:'Nuernberg'
organizationName      :PRINTABLE:'OrganisationName'
organizationalUnitName:PRINTABLE:'OrganisationUnit'
commonName            :PRINTABLE:'serverCA'
emailAddress          :IA5STRING:'webmaster@company.de'
Certificate is to be certified until Jun 26 18:04:15 2013 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
unable to write 'random state'
Doing .
00.pem => 9c05fe89.0
01.pem => b99e5d4b.0


---------------------------------------------
Erstelle eine User CA (signiert von Root CA):

Generating a 2048 bit RSA private key
.................................................................+++
..........................................................................................+++
unable to write 'random state'
writing new private key to 'UserCA/private/UCAkey.pem'
Enter PEM pass phrase: >>UserCA-Password<<
Verifying - Enter PEM pass phrase: >>UserCA-Password<<
-----
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) [Bayern]:
Locality Name (eg, city) [Nuernberg]:
Organization Name (eg, company) [OrganisationName]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Common Name (SERVER / USER name) []:userCA
Email Address (eg, YOUR email) [webmaster@company.de]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
company.de []:
Using configuration from openssl.cnf
Enter pass phrase for /root/ca/RootCA/private/RCAkey.pem: >>rootCA-Password<<
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'Bayern'
localityName          :PRINTABLE:'Nuernberg'
organizationName      :PRINTABLE:'OrganisationName'
organizationalUnitName:PRINTABLE:'OrganisationUnit'
commonName            :PRINTABLE:'userCA'
emailAddress          :IA5STRING:'webmaster@company.de'
Certificate is to be certified until Jun 26 18:04:42 2013 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
unable to write 'random state'
Doing .
00.pem => 9c05fe89.0
01.pem => b99e5d4b.0
02.pem => 47efd334.0
~/ca

scx:~/ca# l
total 32
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 certs/
-rw-r--r-- 1 root root 6657 2008-06-27 20:03 openssl.cnf
drwxr-xr-x 2 root root 4096 2008-06-27 20:03 private/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 RootCA/
drwxr-sr-x 2 root root 4096 2008-06-27 19:57 scripts/
drwxr-xr-x 5 root root 4096 2008-06-27 20:03 ServerCA/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 UserCA/

Im Anschluss erzeuge mein Server Zertifikat mit mk_cert_server z.B. für einen Imap-Server (analog mit mk_cert_user für User):

scx:~/ca# ./scripts/mk_cert_server
~/ca ~/ca

Server-Cert Name: apache
--------
apacheKey.pem & apacheReq.pem ...

Generating a 1024 bit RSA private key
...............................++++++
.....................++++++
unable to write 'random state'
writing new private key to 'apacheKey.pem'
Enter PEM pass phrase: >>apache Passwort<<
Verifying - Enter PEM pass phrase: >>apache Passwort<<
-----
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) [Bayern]:
Locality Name (eg, city) [Nuernberg]:
Organization Name (eg, company) [OrganisationName]:
Organizational Unit Name (eg, section or website) [OrganisationUnit]:
Common Name (SERVER / USER name) []:apache
Email Address (eg, YOUR email) [webmaster@company.de]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
company.de []:

Passwort aus apacheKey.pem entfernen [y] ?
Enter pass phrase: >>apache Passwort<<
writing RSA key
====================
apacheCert.pem  ...
====================
Using configuration from openssl.cnf
Enter pass phrase for /root/ca/ServerCA/private/SCAkey.pem: >>ServerCA Passwort<<
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'DE'
stateOrProvinceName   :PRINTABLE:'Bayern'
localityName          :PRINTABLE:'Nuernberg'
organizationName      :PRINTABLE:'OrganisationName'
organizationalUnitName:PRINTABLE:'OrganisationUnit'
commonName            :PRINTABLE:'apache'
emailAddress          :IA5STRING:'webmaster@company.de'
Certificate is to be certified until Jun 27 16:58:02 2013 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
unable to write 'random state'
----------------------------------------------

certs:
total 36
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 00.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 47efd334.0 -> 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 9c05fe89.0 -> 00.pem
-rw------- 1 root root 4888 2008-06-28 18:58 apacheCert.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 b99e5d4b.0 -> 01.pem

private:
total 24
-rw------- 1 root root 887 2008-06-28 18:57 apache-Key.pem
-rw------- 1 root root 963 2008-06-28 18:57 apacheKey.pem

~/ca

Das Zertifikat verwende ich für den Apache Webserver und teste es anschliessend. Es gibt zwei Key-Files für das Zertifikat apacheCert.pem, eins mit Passwort (apacheKey.req), das andere (apache-Key.req) ohne Passwort, damit der Server automatisch starten kann, ohne das ein Passwort erfragt wird.

scx:~/ca# cat /etc/apache2/sites-enabled/default-ssl
NameVirtualHost *:443

<VirtualHost *:443>
        ServerName apache.company.de
        ServerAdmin webmaster@company.de

        SSLEngine On
        SSLCipherSuite HIGH:MEDIUM
        SSLCertificateFile /root/ca/certs/apacheCert.pem
        SSLCertificateKeyFile /root/ca/ServerCA/private/apache-Key.pem

        # SSLProxyEngine On

        CustomLog /var/log/apache2/access_https.log combined
        ErrorLog  /var/log/apache2/error_https.log

        # debug, info, notice, warn, error, crit, alert, emerg
        LogLevel warn

        ServerSignature Off

        DocumentRoot /var/www/

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>

        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride AuthConfig
                Order allow,deny
                allow from all
                RedirectMatch ^/$ /apache2-default/
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        Alias /debian-doc/ /usr/share/doc/
        <Directory /usr/share/doc/>
                Options Indexes MultiViews FollowSymLinks
                AllowOverride None
                Order deny,allow
                Allow from all
        </Directory>

</VirtualHost>
scx:~/ca# /etc/init.d/apache2 restart

Ein Test (nach der Installation des Zertifikates auf dem lokalem Webserver) sieht dann so aus, man sieht die mehrstufige Hierarchie der Zertifikate bzw. CA inkl. ServerCA und rootCA.

scx:~/ca# openssl s_client -CApath /root/ca/certs -port 443 -host localhost > /tmp/foo
depth=2 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=rootCA/emailAddress=webmaster@company.de
verify return:1
depth=1 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=serverCA/emailAddress=webmaster@company.de
verify return:1
depth=0 /C=DE/ST=Bayern/L=Nuernberg/O=OrganisationName/OU=OrganisationUnit/CN=apache/emailAddress=webmaster@company.de
verify return:1

>>CTRL-C<<

Im Anschluss habe ich folgende Verzeichnisstruktur:

scx:~/ca# ls -lR
.:
total 32
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 certs/
-rw-r--r-- 1 root root 6657 2008-06-27 20:03 openssl.cnf
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 private/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 RootCA/
drwxr-sr-x 2 root root 4096 2008-06-27 19:57 scripts/
drwxr-xr-x 5 root root 4096 2008-06-27 20:20 ServerCA/
drwxr-xr-x 5 root root 4096 2008-06-27 20:04 UserCA/

./certs:
total 28
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 00.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 47efd334.0 -> 02.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 9c05fe89.0 -> 00.pem
lrwxrwxrwx 1 root root    6 2008-06-27 20:04 b99e5d4b.0 -> 01.pem
-rw------- 1 root root 4909 2008-06-27 20:20 apacheCert.pem

./private:
total 8
-rw------- 1 root root 887 2008-06-27 20:20 apache-Key.pem
-rw------- 1 root root 963 2008-06-27 20:20 apacheKey.pem

./RootCA:
total 36
drwxr-xr-x 2 root root 4096 2008-06-27 20:03 certs/
-rw-r--r-- 1 root root  280 2008-06-27 20:04 index.txt
-rw-r--r-- 1 root root   20 2008-06-27 20:04 index.txt.attr
-rw-r--r-- 1 root root   21 2008-06-27 20:04 index.txt.attr.old
-rw-r--r-- 1 root root  141 2008-06-27 20:04 index.txt.old
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:03 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial.old

./RootCA/certs:
total 0

./RootCA/newcerts:
total 16
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 01.pem
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 02.pem

./RootCA/private:
total 8
-rw-r--r-- 1 root root 1911 2008-06-27 20:03 RCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:03 RCAkey.pem

./scripts:
total 20
-rwxr--r-- 1 root root 2892 2008-06-26 22:49 mk_ca_struct*
-rwxr-xr-x 1 root root 1550 2008-06-27 20:19 mk_cert_server*
-rwxr-xr-x 1 root root 1555 2008-06-27 20:31 mk_cert_user*
-rw-r--r-- 1 root root 6500 2008-06-27 19:11 openssl.cnf.tpl

./ServerCA:
total 28
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 certs/
-rw-r--r-- 1 root root  148 2008-06-27 20:20 index.txt
-rw-r--r-- 1 root root   21 2008-06-27 20:20 index.txt.attr
-rw-r--r-- 1 root root    0 2008-06-27 20:03 index.txt.old
drwxr-xr-x 2 root root 4096 2008-06-27 20:20 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:20 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:20 serial
-rw-r--r-- 1 root root    3 2008-06-27 20:03 serial.old

./ServerCA/certs:
total 8
-rw------- 1 root root 4909 2008-06-27 20:20 apacheCert.pem

./ServerCA/newcerts:
total 8
-rw-r--r-- 1 root root 4909 2008-06-27 20:20 01.pem

./ServerCA/private:
total 28
-rw------- 1 root root  887 2008-06-27 20:20 apache-Key.pem
-rw------- 1 root root  963 2008-06-27 20:20 apacheKey.pem
-rw-r--r-- 1 root root  737 2008-06-27 20:20 apacheReq.pem
-rw-r--r-- 1 root root 5643 2008-06-27 20:04 SCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:04 SCAkey.pem
-rw-r--r-- 1 root root 1082 2008-06-27 20:04 SCAreq.pem

./UserCA:
total 16
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 certs/
-rw-r--r-- 1 root root    0 2008-06-27 20:04 index.txt
drwxr-xr-x 2 root root 4096 2008-06-27 20:04 newcerts/
drwx------ 2 root root 4096 2008-06-27 20:04 private/
-rw-r--r-- 1 root root    3 2008-06-27 20:04 serial

./UserCA/certs:
total 0

./UserCA/newcerts:
total 0

./UserCA/private:
total 16
-rw-r--r-- 1 root root 5641 2008-06-27 20:04 UCAcert.pem
-rw-r--r-- 1 root root 1751 2008-06-27 20:04 UCAkey.pem
-rw-r--r-- 1 root root 1078 2008-06-27 20:04 UCAreq.pem