= SSL-Zertifikate = Alternative: http://wiki.excito.org/wiki/index.php/Be_your_own_CA Quelle: http://www.howtoforge.de/anleitung/howto-selbstsigniertes-ssl-zertifikat-erstellen/ ---- Wer kennt es nicht, man möchte gerne seinen Mailserver oder Webserver absichern mit SSL, weiß aber nicht wie man die SSL Zertifikate erstellen soll. Durch das Benutzen von SSL wird die Kommunikation zwischen Client und Server verschlüsselt. Dadurch werden alle Daten verschlüsselt übertragen. Der Vorteil selbstsignierter Zertifikate gegenüber gekauften ist ganz einfach, sie kosten NICHTS! Um dies zu bewerkstelligen, benötigt man Openssl und in unserem Fall Linux. In diesem Howto wird ein Debian Lenny 64Bit benutzt. Geht aber genau so mit anderen Distribution und Debian Versionen. Theoretisch würde es auch mit Windows funktionieren - wird hier aber nicht näher behandelt :p Das Ziel dieses Howto ist es, dass man am Schluss eine Zertifizierungsstelle (Root CA) besitzt, mit der man beliebig viele selbst signierte Zertifikate erstellen kann. == Voraussetzungen == * OpenSSL * Linux System (In diesem Howto benutzt: Debian Lenny 64Bit) == Openssl installieren == Damit wir überhaupt SSL Zertifikate erstellen können, müssen wir OpenSSL installieren. Installiert OpenSSL mit folgendem Befehl: {{{ aptitude install openssl }}} == Benötigte Dateien und Ordner erstellen == Als erstes müssen wir eine Zertifizierungsstelle (Root CA) erstellen. Diese wird benötigt damit wir unsere Zertifikate mit uns selber signieren können. Nur so haben wir gültige Zertifikate. Erstellt die folgenden Ordner und Dateien in eurem home Verzeichnis. {{{ cd /home/username mkdir CA cd CA mkdir newcerts private }}} Das CA Verzeichnis hat folgenden Inhalt: * CA Zertifikat * Die Datenbank mit den signierten Zertifikaten * Die Schlüssel, Requests und Zertifikate, die wir generieren Es ist zudem unser Arbeitsverzeichnis wen wir Zertifikate erstellen und signieren. Das CA/newcerts Verzeichnis beinhaltet: Eine Kopie von jedem signierten Zertifikat Das CA/private Verzeichnis beinhaltet: Unseren privaten und geheimen CA-Schlüssel Dieser Schlüssel ist sehr wichtig! Ohne diesen Schlüssel kann man keine Zertifikate signieren oder erneuern! Verliert ihn also auf keinen Fall! Zudem passt auf das dieser Schlüssel nur durch Root gelesen werden kann und nicht in falsche Hände kommt! Ansonsten könnt ihr alle Zertifikate zurückziehen und von vorne anfangen. Beim nächsten Schritt erstellen wir 2 Dateien, die zum Signieren der Zertifikate benötigt werden: {{{ echo '01' >serial touch index.txt }}} == Konfigurationsdatei erstellen == Erstellt eine neue Konfigurationsdatei “openssl.cnf”. {{{ vim /home/username/CA/openssl.cnf }}} mit folgendem Inhalt: {{{ # # OpenSSL configuration file. # # Establish working directory. dir = . }}} == Root CA Zertifikat erstellen == Jetzt können wir mit dem Erstellen des Root CA Zertifikats beginnen. Aber zuerst noch ein paar Details zur Konfiguration. Die Konfigurationsdatei ist dazu da, dass man nicht so viele Parameter in der Kommandozeile eingeben muss. Zudem ist die Konfigurationsdatei in Sektionen aufgeteilt, sie werden je nach Angabe von Kommandozeilen Argumenten, gelesen und verarbeitet. Ein Name in “Eckigen Klammern”, z.B “[ req ]“ zeigt, dass eine Sektion beginnt. Wir benötigen nun eine Sektion zum Überprüfen der Zertifikate und eine Sektion, welche definiert welchen Typ Zertifikat wir erstellen möchten. Füge Folgendes zu der neuen “openssl.cnf” hinzu: {{{ [ req ] default_bits = 1024 # Size of keys default_keyfile = key.pem # name of generated keys default_md = md5 # message digest algorithm string_mask = nombstr # permitted characters distinguished_name = req_distinguished_name [ req_distinguished_name ] # Variable name Prompt string #---------------------- ---------------------------------- 0.organizationName = Organization Name (company) organizationalUnitName = Organizational Unit Name (department, division) emailAddress = Email Address emailAddress_max = 40 localityName = Locality Name (city, district) stateOrProvinceName = State or Province Name (full name) countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 commonName = Common Name (hostname, IP, or your name) commonName_max = 64 # Default values for the above, for consistency and less typing. # Variable name Value #------------------------------ ------------------------------ 0.organizationName_default = The Sample Company localityName_default = Basel stateOrProvinceName_default = Basel-Stadt countryName_default = CH [ v3_ca ] basicConstraints = CA:TRUE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always }}} Um sicherzustellen, dass unser CA-Zertifikat geschützt ist gegen unbefugte Nutzung, ist das Zertifikat passwortgeschützt. Jedesmal, wenn man ein Zertifikat mit dem CA- Zertifikat von uns signieren möchte, muss man ein Passwort eingeben. Jetzt können wir unser selbstsigniertes Root-Zertifikat erstellen. Benutzte Kommandzeilenoptionen: * Ein neues Selbst-signiertes Zertifikat erstellen: -new -x509 * Ein CA Zertifikat erstellen: -extensions v3_ca * Gültigkeit: -days 3650 * Ausgabe in spezifizierte Datei: -keyout, -out * Eigene Konfigurationsdatei benutzen: -config ./openssl.cnf (Ein Hinweis bezüglich der Gültigkeit des Root-Zertifikates: Wenn ein Root-Zertifikat abgelaufen ist, sind alle Zertifikate, welche mit dem Root-Zertifikat signiert sind, nicht mehr gültig! Deshalb ist unser Root-Zertifikat 10 Jahre gültig.) Führt folgenden Befehl aus. Ihr werdet nach einem neuen Passwort gefragt, welches ihr 2 mal angeben müsst. Merkt euch das Passwort! Denn es wird benötigt, um eure Zertifikate zu signieren. {{{ openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 3650 -config ./openssl.cnf }}} Ausgabe: {{{ Using configuration from ./openssl.cnf Generating a 1024 bit RSA private key .......++++++ ..........................++++++ writing new private key to 'private/cakey.pem' Enter PEM pass phrase:demo Verifying password - Enter PEM pass phrase:demo ----- 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. ----- Organization Name (company) [Meine Firma]: Organizational Unit Name (department, division) []:CA Division Email Address []:ca@sample.com Locality Name (city, district) [Basel]: State or Province Name (full name) [Basel-Stadt]: Country Name (2 letter code) [CH]: Common Name (hostname, IP, or your name) []:Mein Root CA }}} Dies erstellt 2 Dateien: * Ein Privater Schlüssel in “private/cakey.pem” * Ein Root CA Zertifikat in “cacert.pem” cacert.pem ist die Datei, welche man den Clients verteilt, damit sie das Root-CA-Zertifikat manuell importieren können. Weiter unten gibt es noch eine Methode, wie man das CA-Zertifikat als Datei mit der Dateiendung “.crt” als Downloadlink anbieten kann. Dazu aber später mehr. Um einzelne Ausschnitte aus dem Zertifkat anzusehen, kann man das mit folgenden Befehlen tun: {{{ openssl x509 -in cacert.pem -noout -text }}} oder {{{ openssl x509 -in cacert.pem -noout -dates }}} oder {{{ openssl x509 -in cacert.pem -noout -purpose }}} == Serverzertifikat erstellen == Da wir jetzt ein Root-Zertifikat haben, können wir mit dem Erstellen des SSL-Server-Zertifikats für unsere SSL-Applikationen, wie z.B https, spop, simap oder stunnel beginnen. Zuerst erstellen wir einen privaten Schlüssel und ein Zertifikat-Request, diese signieren wir mit dem Root-Zertifikat, dadurch erhalten wir ein gültiges Zertifikat. Unsere “openssl.cnf” benötigt jetzt ein paar weitere Sektionen, um Nicht-CA Zertifikate erstellen zu können. Füge Folgendes ans Ende der Datei: {{{ [ v3_req ] basicConstraints = CA:FALSE subjectKeyIdentifier = hash }}} Um zu verhindern, dass wir jedesmal das Gleiche auf der Kommandozeile wiederholen müssen, füge Folgendes in die “[ req ]” Sektion nach “distinguished_name” ein: {{{ distinguished_name = req_distinguished_name req_extensions = v3_req }}} Jetzt sind wir bereit, um unseren ersten Zertifikatrequest zu erstellen. In diesem Beispiel erstellen wir ein Zertifikat für einen sicheren Webserver mit der Domain secure.yourdomain.de. Alles sieht ziemlich ähnlich aus wie beim Root CA Zertifikat, abgesehen von 3 Eingaben, welche sich ändern im Zertifikatsrequest. * Organizational Unit: ein Hinweis für was das Zertifikat ist * Email Address: die Email Addresse des Webserver Administrators * Common Name: Hostname/Domainname für welches das Zertifikat giltet. Zwingend notwendig! Der Common Name muss zwingend gleich sein wie der Server Name oder Domain Name, mit welchem die Clients auf die sichere Website zugreifen möchten. Wenn dieser Name nicht zusammenpasst, bekommen alle Clients, die sich mit der SSL-geschützen Webseite verbinden möchten, eine Warnung! Die Warnung weißt euch darauf hin, ob ihr diesem Server vertraut und trotzdem nutzen möchtet! Die Fehlermeldung, die beim Client erscheint: “Warning! You asked for mail.sample.com; the responding machine’s certificate is for secure.yourdomain.de. Are you sure you want to continue?” Es ist auch möglich, ein sogenanntes Wildcard Zertifikat zu erstellen für alle Subdomains einer Domain, zum Beispiel “*.yourdomain.de”; somit sind alle Subdomains gültig für diese Domain. Dies wird jedoch in der Regel eher in Reverse-Proxy-Lösungen benötigt. == Zertifikat Request erstellen (CSR - Certificate Signing Request) == {{{ openssl req -new -nodes -out req.pem -config ./openssl.cnf }}} Dies erstellt 2 Dateien: * Ein privater Schlüssel in key.pem * Ein Zertifikats signier Request in req.pem Diese Dateien sollten aufbewahrt werden. Wenn das zu erstellende Zertifkat mal abläuft, kann der Request benutzt werden, um erneut ein Zertifikat zu erstellen. Der private Schlüssel ist natürlich wichtig für die SSL-Verschlüsselung. Wenn man die Dateien irgendwo abspeichert, ist es wichtig, dass man Dateinamen verwendet, durch die man erkennen kann, für was das Zertifikat erstellt wurde; als Beispiel, secure.yourdomain.de.key.pem und secure.yourdomain.de.req.pem. Wir können den Inhalt überprüfen um sicher zu sein, dass unser Request Inhaltlich stimmt bevor wir ihn signieren: {{{ openssl req -in req.pem -text -verify -noout }}} == Server Zertifikat signieren == Jetzt müssen wir noch eine Konfigurationssektion hinzufügen, damit wir eine Zertifizierungsstelle sind. Ansonsten können wir den Zertifikatsrequest nicht signieren. Diese Sektion beinhaltet die Pfade zu den verschiedenen Dateien, wie z.B die Datenbank, das Root-CA-Zertifikat, der private Schlüssel usw. Es beinhaltet zudem ein paar Standardwerte. Kopiere den folgenden Inhalt vor die “[ req ]” Sektion in der “openssl.cnf”: {{{ [ ca ] default_ca = CA_default [ CA_default ] serial = $dir/serial database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/cacert.pem private_key = $dir/private/cakey.pem default_days = 365 default_md = md5 preserve = no email_in_dn = no nameopt = default_ca certopt = default_ca policy = policy_match [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional }}} Um den Request zu signieren, führe den folgenden Befehl aus und beantworte die Ausgaben. Achtung: Das abgefragte Passwort ist das Root CA Passwort, welches wir weiter oben eingegeben haben: {{{ openssl ca -out cert.pem -config ./openssl.cnf -infiles req.pem }}} Dies updatet die CA Datenbank und erstellt 2 Dateien: * Ein Zertifikat in cert.pem * Eine Kopie des Zertifikates in newcerts/.pem Wir können das Zertifikat wieder anzeigen um den Inhalt zu überprüfen: {{{ openssl x509 -in cert.pem -noout -text -purpose | more }}} Wie man erkennen kann, enthält das Zertifikat beides, die encodierte Version und die menschenlesbare Version in der gleichen Datei. Wir können den menschenlesbaren Teil wie folgt herauslöschen: {{{ mv cert.pem tmp.pem openssl x509 -in tmp.pem -out cert.pem }}} == Server-Zertifikat und -Key installieren == Dies hängt von der Applikation ab, für die man das Zertifikat erstellt hat. Einige Applikationen möchten den Schlüssel und das Zertifikat in der gleichen Datei, während andere Applikationen lieber separate Dateien benutzen für den Schlüssel und das Zertifikat. Um den Schlüssel mit dem Zertifikat zu vereinen, kann man diesen Befehl nutzen: {{{ cat key.pem cert.pem >key-cert.pem }}} Nach diesem Schritt haben wir 3 installierbare Komponenten: * Ein Privater Schlüssel in key.pem * Ein Zertifikat in cert.pem * Ein kombinierter Privater Schlüssel und ein Zertifikat in key-cert.pem Diese Dateien müssen je nach Applikation in andere Verzeichnisse kopiert werden und üblicherweise in der Konfiguration angegeben werden. Ich werde hier nicht weiter auf die einzelnen Applikationen eingehen. == Zertifikat erneuern == Es gibt zwei Möglichkeiten, warum ihr Zertifikat erneuert werden muss: * Das signierte Zertifikat ist abgelaufen. * Das Root-Zertifikat, mit dem das Zertifikat signiert wurde, ist abgelaufen. == Zertifikat widerrufen == Das Zertifikat muss zuerst widerrufen werden, ansonsten kann kein Zertifikat mit dem gleichen “Common Name” erneut ausstellen. Das Zertifikat findet ihr im “newcerts” Verzeichnis; Den Dateinamen kann man herausfinden, in dem man in der “index.txt” nach dem “Common Name (CN)” sucht. Der Dateiname ist der Index plus die Dateiendung “.pem”, als Beispiel “02.pem”. Um das Zertifikat zurückzuziehen, benutzt den folgenden Befehl: {{{ openssl ca -revoke newcerts/02.pem -config ./openssl.cnf }}}