Ubuntu 20.04 - Certification Authority (CA) mit OpenSSL installieren
Auch können wichtige Hinweise und Erläuterungen fehlen, was die Verwendung der Dokumentation erschweren kann.
Voraussichtliche Fertigstellung: 09/2021
Vorwort
Diese Dokumentation beschreibt den Installationsvorgang von OpenSSL als Certification Authority (CA/PKI).
Bitte vergewissern Sie sich, dass Ihr System über die nötigen Voraussetzungen verfügt, wie in der Infobox beschrieben. Weiterhin sind Grundkenntnisse im Umgang mit Linux erforderlich, da die Vorgehensweise, wie sie hier beschrieben ist, in manchen Teilen abweichen kann. Kein System ist wie das Andere. Die Dokumentation wurde sorgfältig von mir geprüft. Dennoch kann ich keinerlei Haftung für Schäden an Ihrem System oder eine Gewährleistung übernehmen. Bitte verwenden Sie diese Dokumentation auf eigene Gefahr.
Verwendete Software:
Voraussetzungen:
- Ubuntu 20.04 LTS
Weitere, empfohlene Dokumentationen:
Server vorbereiten
Root-Rechte einräumen
Während der gesamten Dokumentation werden Root-Rechte benötigt. Um auf das Voranstellen von sudo
zu verzichten, verschaffen Sie sich für die gesamte Sitzung erhöhte Rechte mit:
# sudo -i
Update durchführen
Bringen Sie den Server auf den aktuellen Patchstand:
# apt update && apt upgrade
OpenSSL einrichten
Verzeichnisstruktur und Dateien erstellen
Erstellen Sie die Ordner für die RootCA und die IntermediateCA:
# mkdir /etc/ssl/private/CA # mkdir /etc/ssl/private/CA/RootCA # mkdir /etc/ssl/private/CA/Intermediate
Wechseln Sie in die entsprechenden Ordner und erstellen Sie die Verzeichnisstruktur und die benötigten Dateien:
# cd /etc/ssl/private/CA/RootCA # mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
# cd /etc/ssl/private/CA/Intermediate # mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Zufallszahlen generieren
Mit folgendem Befehl werden Zufallszahlen in den Ordnern ../private
erzeugt:
for i in `find /etc/ssl/private/CA/ -name private` do cat /dev/urandom | uuencode -m sometext | head -19 | sed "s/begin.*//g" | tail -18 | xargs | sed "s/ //g" > $i/.rand chmod 770 $i/.rand ls -l $i/.rand done
Konfiguration erstellen
Benennen Sie zunächst die /etc/ssl/openssl.cnf
um, damit Sie eine Sicherheitskopie der Original-Datei haben:
# mv /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.bak
Erstellen Sie eine neue Datei /etc/ssl/openssl.cnf
mit folgendem Inhalt:
# nano /etc/ssl/openssl.cnf
####################################################################
[ ca ]
default_ca = RootCA # The default ca section
[ RootCA ]
dir = /etc/ssl/private/CA/RootCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/RootCA.cert.pem # The CA certificate
serial = $dir/serial # The current serial number
#crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl/crl.pem # The current CRL
crl_extensions = crl_ext
default_crl_days = 30 # how long before next CRL
private_key = $dir/private/RootCA.key.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
default_days = 3650 # how long to certify for
default_md = sha512 # use public key default MD
preserve = no # keep passed DN ordering
policy = policy_strict
[ Intermediate ]
dir = /etc/ssl/private/CA/Intermediate # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/Intermediate.cert.pem # The CA certificate
serial = $dir/serial # The current serial number
#crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl/crl.pem # The current CRL
crl_extensions = crl_ext
default_crl_days = 30 # how long before next CRL
private_key = $dir/private/Intermediate.key.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
default_days = 3650 # how long to certify for
default_md = sha512 # use public key default MD
preserve = no # keep passed DN ordering
policy = policy_strict
####################################################################
[ policy_strict ]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 4096
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extensions to add to the self signed cert
string_mask = utf8only
[ 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 = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
####################################################################
[ v3_ca ]
basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
basicConstraints = critical,CA:true,pathlen:0
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ server_cert ]
basicConstraints = CA:false
nsCertType = server
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[ usr_cert ]
basicConstraints = CA:false
nsCertType = client, email
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ crl_ext ]
authorityKeyIdentifier = keyid:always
[ ocsp ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
[ alt_names ]
DNS.1 = example.tld
DNS.2 = *.example.tld
# openssl.conf
[...]
[ alt_names ]
DNS.1 = example.tld
DNS.2 = *.example.tld
CA-Zertifikate erstellen
RootCA-Zertifikat erstellen
Erstellen Sie den Private-Key und vergeben Sie eine sichere und komplexe Passphrase:
# openssl genrsa -aes256 -out /etc/ssl/private/CA/RootCA/private/RootCA.key.pem \ -rand /etc/ssl/private/CA/RootCA/private/.rand \ 4096
Erstellen Sie anschliessend das dazu passende Zertifikat (Public-Key):
Das Root-Zertifikat sollte über eine lange Laufzeit verfügen. In unserem Beispiel sind es 20 Jahre (-days 7300).
Vergeben Sie ausserdem einen eindeutigen Common Name
(z.B. Example.tld RootCA).
# openssl req -new -x509 -days 7300 \ -extensions v3_ca \ -key /etc/ssl/private/CA/RootCA/private/RootCA.key.pem \ -out /etc/ssl/private/CA/RootCA/RootCA.cert.pem
Intermediate-Zertifikat erstellen
Erstellen Sie den Private-Key und vergeben Sie eine sichere und komplexe Passphrase:
# openssl genrsa -aes256 /etc/ssl/private/CA/Intermediate/private/Intermediate.key.pem \ -rand /etc/ssl/private/CA/Intermediate/private/.rand \ 4096
Erstellen Sie anschliessend den dazu passenden Zertifikat Signing Request (CSR):
Vergeben Sie ausserdem einen eindeutigen Common Name
(z.B. Example.tld IntermediateCA).
# openssl req -new -key /etc/ssl/private/CA/Intermediate/private/Intermediate.key.pem \ -out /etc/ssl/private/CA/Intermediate/Intermediate.csr.pem
Signieren Sie das Intermediate-Zertifikat mit dem RootCA-Zertifikat:
Auch das Intermediate-Zertifikat sollte über eine lange Laufzeit verfügen. In unserem Beispiel sind es ebenfalls 20 Jahre (-days 7300).
# openssl ca -name RootCA -days 7300 \ -extensions v3_intermediate_ca \ -in /etc/ssl/private/CA/Intermediate/Intermediate.csr.pem \ -out /etc/ssl/private/CA/Intermediate/Intermediate.cert.pem
Chain-Zertifikat erstellen
Erstellen Sie das Chain-Zertifikat mit folgendem Befehl:
Verwenden Sie das Chain-Zertifikat überall dort, wo Sie SSL/TLS integrieren möchten. Nur mit dem Chain-Zertifikat wird eine komplette Zertifikats-Kette präsentiert.
# cat /etc/ssl/private/CA/Intermediate/Intermediate.cert.pem /etc/ssl/private/CA/RootCA/RootCA.cert.pem > /etc/ssl/private/CA/RootCA-chain.cert.pem
(Optional) OCSP-Service einrichten
Treffen Sie die Entscheidung, den OSCP-Service zu verwenden unbedingt bevor Sie die Endpoint-Zertifikate erstellen. Die Information, ob und wo ein OSCP-Server zur Verfügung steht, befindet sich im jeweiligen Zertifikat.
Alle Zertifikate, die ohne diese Information ausgerollt wurden, müssen neu erstellt und ausgerollt werden.
OpenSSL-Konfiguration anpassen
Fügen Sie der Datei /etc/ssl/openssl.cnf
im Bereich [ server_cert ]
folgendes hinzu:
Passen Sie die URL entsprechend Ihrer verwendeten Domain an.
# nano /etc/ssl/openssl.cnf
[...] [ server_cert ] [...] authorityInfoAccess = OCSP;URI:http://ocsp.example.tld [...]
OCSP-Zertifikat erstellen
Wechseln Sie zunächst in den Ordner /etc/ssl/private/CA/Intermediate
:
# cd /etc/ssl/private/CA/Intermediate
Erstellen Sie den Public-Key nach folgendem Syntax:
(Ersetzen Sie ocsp.example.tld
durch Ihre verwendete Domain)
# openssl genrsa -out private/ocsp.example.tld.key.pem \ -rand /etc/ssl/private/CA/Intermediate/private/.rand \ 4096
Erstellen Sie den Signing-Request für das Server-Zertifikat:
(Ersetzen Sie ocsp.example.tld
durch Ihre verwendete Domain)
# openssl req -new -sha512 \ -key private/ocsp.example.tld.key.pem \ -out ocsp.example.tld.csr.pem
Signieren Sie das Server-Zertifikat mit dem Intermediate-Zertifikat:
(Ersetzen Sie ocsp.example.tld
durch Ihre verwendete Domain)
# openssl ca -name Intermediate \ -extensions ocsp \ -days 3650 \ -notext \ -md sha512 \ -in ocsp.example.tld.csr.pem \ -out ocsp.example.tld.cert.pem
Schränken Sie die Zugriffsrechte auf dem Private-Key ein:
(Ersetzen Sie ocsp.example.tld
durch Ihre verwendete Domain)
# chmod 400 private/ocsp.example.tld.key.pem
Verschieben Sie das neue Zertifkat in den Zertifikats-Ordner und generieren die den Hashwert:
(Kontrollieren Sie vorher den Dateinamen des neuen Zertifkates im Ordner ../newcerts
und passen Sie ggf. die nachfolgenden Befehle an!)
# mv /etc/ssl/private/CA/Intermediate/newcerts/1000.pem /etc/ssl/private/CA/Intermediate/certs/ # cd /etc/ssl/private/CA/Intermediate/certs # ln -s 1000.pem `openssl x509 -hash -noout -in 1000.pem`.0
OCSP-Daemon erstellen
Erstellen Sie die neue Datei ocsp-server.service
mit folgendem Inhalt:
# nano /etc/systemd/system/ocsp-server.service
[Unit]
Description=OCSP Service
Wants=network.target
After=syslog.target network-online.target
[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=root
WorkingDirectory=
ExecStart=openssl ocsp -port 80\
-text \
-index /etc/ssl/private/CA/Intermediate/index.txt \
-CA /etc/ssl/private/CA/RootCA-chain.cert.pem \
-rkey /etc/ssl/private/CA/Intermediate/private/ocsp.example.tld.key.pem \
-rsigner /etc/ssl/private/CA/Intermediate/ocsp.example.tld.cert.pem \
-out /etc/ssl/private/CA/ocsp.log
[Install]
WantedBy=multi-user.target
Aktualisieren Sie systemd:
# systemctl daemon-reload
Führen Sie folgendes Kommando aus, damit der OCSP-Service nach einem Neustart automatisch startet:
# systemctl enable ocsp-server Created symlink /etc/systemd/system/multi-user.target.wants/ocsp-server.service → /etc/systemd/system/ocsp-server.service.
Starten Sie den Dienst:
# service ocsp-server start
Zertifikat gegen OSCP-Service prüfen
Erstellen Sie zunächst ein Server-Zertifikat, wie unter Punkt Server-Zertifikat erstellen beschrieben.
Verwenden Sie anschliessend folgenden Befehl um die Gültigkeit des Zertifikats zu überprüfen:
(Ersetzen Sie server.example.tld
durch den von Ihnen vergebenen Namen und http://ocsp.example.tld
durch Ihre verwendete Domain)
# openssl ocsp -CAfile /etc/ssl/private/CA/RootCA-chain.cert.pem \ -url http://ocsp.example.tld \ -resp_text \ -issuer /etc/ssl/private/CA/Intermediate/Intermediate.cert.pem \ -cert /etc/ssl/private/CA/Intermediate/server.example.tld.cert.pem
Die Ausgabe sollte ein gültiges Zertifikat bestätigen:
[...] Response verify OK /etc/ssl/private/CA/Intermediate/server.example.tld.cert.pem: good This Update: Jan 12:00:00 1970 GMT
Endpoint-Zertifikate erstellen
Server-Zertifikat erstellen
Allerdings ist das manuelle Erstellen der Server-Zertifikate aufwendig. Besonders dann, wenn meherer Server-Zertifikate erstellt werden sollen. In diesem Fall können Sie auch das folgende Script verwenden, in dem alle Schritte zusammengefasst sind.
Mit Script
#!/bin/bash
#
#########################################################################
# Script Name : server_cert-gen_prime256v1.sh #
# Description : generates a Server-SSL-Certificate #
# Args : #
# #
# Version : 1.00 #
# Last Update : 22.09.2021 #
# Author : Twilight #
# Email : twilight@twlnet.com #
# Web: : https://www.twilight-networks.com #
#########################################################################
# Tested with : Ubuntu 20.04 LTS #
#########################################################################
HOME="/etc/ssl/private/CA"
RANDFILE=$HOME"/Intermediate/private/.rand"
INTERMEDIATE_CA_CERT=$HOME"/Intermediate/Intermediate.cert.pem"
INTERMEDIATE_CA_KEY=$HOME"/Intermediate/private/Intermediate.key.pem"
INTERMEDIATE_CA_DIR=$HOME"/Intermediate/"
INTERMEDIATE_CA_CERTSDIR=$HOME"/Intermediate/certs/"
INTERMEDIATE_CA_NEWCERTSDIR=$HOME"/Intermediate/newcerts/"
# Normaly there is no need to change anything below this comment line!
#########################################################################
SERIAL=$( cat $INTERMEDIATE_CA_DIR"serial" )
echo "Enter Name of Certificate:"
read CERT_NAME
cd "$INTERMEDIATE_CA_DIR"
openssl ecparam -name prime256v1 -genkey -noout -rand "$RANDFILE" -out "$CERT_NAME".key.pem
openssl req -new -key "$CERT_NAME".key.pem -out "$CERT_NAME".csr.pem
openssl ca -name Intermediate -extensions server_cert -in "$CERT_NAME".csr.pem -out "$CERT_NAME".cert.pem
chmod 400 "$CERT_NAME".key.pem
mv "$INTERMEDIATE_CA_NEWCERTSDIR""$SERIAL".pem $INTERMEDIATE_CA_CERTSDIR
cd "$INTERMEDIATE_CA_CERTSDIR"
ln -s "$SERIAL".pem `openssl x509 -hash -noout -in "$SERIAL".pem`.0
exit 0
#
Vergeben Sie die benötigte Berechtigung, damit die Datei ausgeführt werden kann:
# chmod 755 server_cert-gen_prime256v1.sh
Starten Sie das Script:
# ./server_cert-gen_prime256v1.sh
Manuell per Kommandozeile
Wechseln Sie zunächst in den Ordner /etc/ssl/private/CA/Intermediate
:
# cd /etc/ssl/private/CA/Intermediate
Erstellen Sie den Public-Key nach folgendem Syntax:
(Ersetzen Sie server.example.tld
durch den FQDN Ihres gewünschten Servers)
# openssl ecparam -name prime256v1 \ -genkey \ -noout \ -rand /etc/ssl/private/CA/Intermediate/private/.rand \ -out server.example.tld.key.pem
Erstellen Sie den Signing-Request für das Server-Zertifikat:
(Ersetzen Sie server.example.tld
durch den FQDN Ihres gewünschten Servers)
# openssl req -new -key server.example.tld.key.pem \ -out server.example.tld.csr.pem
Signieren Sie das Server-Zertifikat mit dem Intermediate-Zertifikat:
(Ersetzen Sie server.example.tld
durch den FQDN Ihres gewünschten Servers)
# openssl ca -name Intermediate \ -extensions server_cert \ -in server.example.tld.csr.pem \ -out server.example.tld.cert.pem
Schränken Sie die Zugriffsrechte auf dem Private-Key ein:
(Ersetzen Sie server.example.tld
durch den FQDN Ihres gewünschten Servers)
# chmod 400 server.example.tld.key.pem
Verschieben Sie das neue Zertifkat in den Zertifikats-Ordner und generieren die den Hashwert:
(Kontrollieren Sie vorher den Dateinamen des neuen Zertifkates im Ordner ../newcerts
und passen Sie ggf. die nachfolgenden Befehle an!)
# mv /etc/ssl/private/CA/Intermediate/newcerts/1000.pem /etc/ssl/private/CA/Intermediate/certs/ # cd /etc/ssl/private/CA/Intermediate/certs # ln -s 1000.pem `openssl x509 -hash -noout -in 1000.pem`.0
User-Zertifikat erstellen
Mit Script
#!/bin/bash
#
#########################################################################
# Script Name : user_cert-gen_pkcs12.sh #
# Description : generates a User-SSL-Certificate #
# Args : #
# #
# Version : 1.00 #
# Last Update : 22.09.2021 #
# Author : Twilight #
# Email : twilight@twlnet.com #
# Web: : https://www.twilight-networks.com #
#########################################################################
# Tested with : Ubuntu 20.04 LTS #
#########################################################################
HOME="/etc/ssl/private/CA"
RANDFILE=$HOME"/Intermediate/private/.rand"
INTERMEDIATE_CA_CERT=$HOME"/Intermediate/Intermediate.cert.pem"
INTERMEDIATE_CA_KEY=$HOME"/Intermediate/private/Intermediate.key.pem"
INTERMEDIATE_CA_DIR=$HOME"/Intermediate/"
INTERMEDIATE_CA_CERTSDIR=$HOME"/Intermediate/certs/"
INTERMEDIATE_CA_NEWCERTSDIR=$HOME"/Intermediate/newcerts/"
# Normaly there is no need to change anything below this comment line!
#########################################################################
SERIAL=$( cat $INTERMEDIATE_CA_DIR"serial" )
echo "Enter Name of Certificate:"
read CERT_NAME
cd "$INTERMEDIATE_CA_DIR"
openssl genrsa -aes256 -rand "$RANDFILE" -out "$CERT_NAME".key.pem
openssl req -new -key "$CERT_NAME".key.pem -out "$CERT_NAME".csr.pem
openssl ca -name Intermediate -extensions usr_cert -in "$CERT_NAME".csr.pem -out "$CERT_NAME".cert.pem
chmod 400 "$CERT_NAME".key.pem
openssl pkcs12 -export -inkey "$CERT_NAME".key.pem -in "$CERT_NAME".cert.pem -name "PKCS12 $CERT_NAME" -out "$CERT_NAME".p12
mv "$INTERMEDIATE_CA_NEWCERTSDIR""$SERIAL".pem $INTERMEDIATE_CA_CERTSDIR
cd "$INTERMEDIATE_CA_CERTSDIR"
ln -s "$SERIAL".pem `openssl x509 -hash -noout -in "$SERIAL".pem`.0
exit 0
#
Vergeben Sie die benötigte Berechtigung, damit die Datei ausgeführt werden kann:
# chmod 755 user_cert-gen_pkcs12.sh
Starten Sie das Script:
# ./user_cert-gen_pkcs12.sh
Manuell per Kommandozeile
Wechseln Sie zunächst in den Ordner /etc/ssl/private/CA/Intermediate
:
# cd /etc/ssl/private/CA/Intermediate
Erstellen Sie den Public-Key nach folgendem Syntax:
Vergeben Sie eine sichere und komplexe Passphrase
(Ersetzen Sie user@example.tld
durch den Namen Ihres gewünschten Users)
# openssl genrsa -aes256 \ -rand /etc/ssl/private/CA/Intermediate/private/.rand \ -out user@example.tld.key.pem
Erstellen Sie den Signing-Request für das Server-Zertifikat:
(Ersetzen Sie user@example.tld
durch den Namen Ihres gewünschten Users)
# openssl req -new -key user@example.tld.key.pem \ -out user@example.tld.csr.pem
Signieren Sie das Server-Zertifikat mit dem Intermediate-Zertifikat:
(Ersetzen Sie user@example.tld
durch den Namen Ihres gewünschten Users)
# openssl ca -name Intermediate \ -extensions usr_cert \ -in user@example.tld.csr.pem \ -out user@example.tld.cert.pem
Schränken Sie die Zugriffsrechte auf dem Private-Key ein:
(Ersetzen Sie user@example.tld
durch den Namen Ihres gewünschten Users)
# chmod 400 user@example.tld.key.pem
Konvertieren Sie das User-Zertifikat in das Format PKCS12:
(Ersetzen Sie user@example.tld
durch den Namen Ihres gewünschten Users)
# openssl pkcs12 -export \ -inkey user@example.tld.key.pem \ -in user@example.tld.cert.pem \ -name "PKCS12 user@example.tld" \ -out user@example.tld.p12
Verschieben Sie das neue Zertifkat in den Zertifikats-Ordner und generieren die den Hashwert:
(Kontrollieren Sie vorher den Dateinamen des neuen Zertifkates im Ordner ../newcerts
und passen Sie ggf. die nachfolgenden Befehle an!)
# mv /etc/ssl/private/CA/Intermediate/newcerts/1000.pem /etc/ssl/private/CA/Intermediate/certs/ # cd /etc/ssl/private/CA/Intermediate/certs # ln -s 1000.pem `openssl x509 -hash -noout -in 1000.pem`.0