All posts in PKI

 

 

 

 

 

Hallo zusammen,

um einen nginx Webserver installieren zu können, benötigt es ein paar Vorbereitungen.
In diesen Beispiel verwende wir einen Ubuntu 16.04 LTS Server in einer Virtuellen Umgebung.

Nach der Grundinstallation des Servers, muss der Server auf den neusten Stand gebracht werden.
Nach dem Login, wechselt man zum root Benutzer mit:

sudo -i oder sudo su -
apt update -y && apt upgrade -y
reboot

Nach dem das System up to date ist, konfiguriert man den Server mit einer statischen IP-Adresse.

vim /etc/network/interfaces

auto enp0s3
iface enp0s3 inet static
  address 192.168.xxx.xxx
  netmask 255.255.255.0
  gateway 192.168.xxx.xxx
  dns-search htdom.local
  dns-nameservers 192.168.xxx.xxx 192.168.xxx.xxx

systemctl restart networking.service
systemctl status networking.service

nginx Webserver installation und überprüfen

apt-get install nginx apache2-utils ssh
dpkg -l | grep nginx

Standardverzeichnisse nach der Installation

tree /etc/nginx

/etc/nginx/
├── conf.d
├── fastcgi.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── nginx.conf
├── proxy_params
├── scgi_params
├── sites-available
│   └── default
├── sites-enabled
│   └── default -> /etc/nginx/sites-available/default
├── snippets
│   ├── fastcgi-php.conf
│   └── snakeoil.conf
├── uwsgi_params
└── win-utf


tree /var/www

/var/www/
└── html
    └── index.nginx-debian.html

Grundlegende nginx Befehle

## Mit folgenden Befehlen kann man den nginx Server starten/stoppen/reloaden/configtest durchführen bzw. den Status abfragen
##
service nginx {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}

## Der wichtigste Befehl nach jeder Konfigurationsanpassung ist immer.
##
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

oder

service nginx configtest
* Testing nginx configuration
  ...done.

Mit folgenden Befehl überprüft man, ob der nginx Server auf Port 80 lauscht

netstat -antlp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4236/nginx -g daemo
tcp6       0      0 :::80                   :::*                    LISTEN      4236/nginx -g daemo

PID File Anpassung in der nginx.service Datei

## Nach jedem Neustart des nginx Services, wird eine Fehlermeldung ausgegeben, das die nginx.pid nicht gelesen/gefunden wird.
## Daher wurde hier eine kleine Anpassung an der nginx.service & nginx.conf Datei vorgenommen.
##
systemctl status nginx.service
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   ...
Jan 19 16:08:53 web01 systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 19 16:08:53 web01 systemd[1]: nginx.service: Failed to read PID from file /run/nginx.pid: Invalid argument


vim /lib/systemd/system/nginx.service
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
...
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /var/run/nginx.pid
. . .

vim /etc/nginx/nginx.conf
http {
    # pid /var/run/nginx.pid;
    . . .
}

systemctl restart nginx.service
systemctl daemon-reload

systemctl status nginx.service
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   ...
Jan 19 16:10:00 web01 systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 19 16:10:00 web01 systemd[1]: Started A high performance web server and a reverse proxy server.

Erste Webseite konfigurieren

## Als erstes entfernen wir den Standardlink unter sites-enabled und machen eine Sicherungskopie der /etc/nginx/default Datei.

unlink /etc/nginx/sites-enabled/default
mv /etc/nginx/sites-available/default{,.old}

mv /var/www/html/index.nginx-debian.html /var/www/html/index.html
mv /var/www/html/ /var/www/mysite_htdom_local

vim /etc/nginx/sites-available/mysite.htdom.local

## Default Server Konfiguration ohne https und rewrite
##
server {
  listen 80;
  listen [::]:80;

  server_name mysite.htdom.local;
  root /var/www/mysite_htdom_local;
  index index.html;

  access_log /var/log/nginx/access_mysite_htdom_local.log;
  error_log /var/log/nginx/error_mysite_htdom_local.log;
}

ln -s /etc/nginx/sites-available/mysite.htdom.local /etc/nginx/sites-enabled/

systemctl reload nginx.service

 

 

 

 

 

Virtuellen Host konfigurieren

mkdir -p /var/www/site1_htdom_local
sudo chown -R root:root /var/www/site1_htdom_local

vim /etc/nginx/sites-available/site1.htdom.local

## Default Server Konfiguration ohne https und rewrite
##
server {
  listen 80;
  listen [::]:80;

  server_name site1.htdom.local;
  root /var/www/site1_htdom_local;
  index index.html;

  access_log /var/log/nginx/access_site1_htdom_local.log;
  error_log /var/log/nginx/error_site1_htdom_local.log;
}

ln -s /etc/nginx/sites-available/site1.htdom.local /etc/nginx/sites-enabled/

systemctl reload nginx.service

ls -la /etc/nginx/sites-enabled/
...
lrwxrwxrwx 1 root root   45 Jan 19 18:45 mysite.htdom.local -> /etc/nginx/sites-available/mysite.htdom.local
lrwxrwxrwx 1 root root   44 Jan 20 15:58 site1.htdom.local -> /etc/nginx/sites-available/site1.htdom.local

 

 

 

 

 

Webserver SSL Zertifikat erstellen

cd /opt/ca/IssuingCA/

openssl genrsa -aes256 -out private/mysite.htdom.local.key 2048 -rand private/.randIssuingCA
chmod 0400 private/mysite.htdom.local.key

openssl req -new -key private/mysite.htdom.local.key -out newcerts/mysite.htdom.local.csr -config ca-config.cnf

Enter pass phrase for private/mysite.htdom.local.key:
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 (Bayern) [Bayern]:
Locality Name (Muenchen) [Muenchen]:
Organization Name (Company name or your Name) [HTDOM Company GmbH]:
Organizational Unit Name (Department) [IT]:IT-Support
Common Name (Server FQDN or your Name) []:mysite.htdom.local
...

-----------------------------------------------------------------------
openssl ca -name IssuingCA -in newcerts/mysite.htdom.local.csr -out certs/mysite.htdom.local.crt -extensions server_cert -config ca-config.cnf

Using configuration from ca-config.cnf
Enter pass phrase for /opt/ca/IssuingCA/private/IssuingCA.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jan 22 13:14:33 2017 GMT
            Not After : Jan 20 13:14:33 2027 GMT
        Subject:
            countryName               = DE
            stateOrProvinceName       = Bayern
            organizationName          = HTDOM Company GmbH
            organizationalUnitName    = IT-Support
            commonName                = mysite.htdom.local
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            Authority Information Access:
                CA Issuers - URI:http://mysite.htdom.local/cert/IssuingCA.html

            X509v3 CRL Distribution Points:

                Full Name:
                  URI:http://mysite.htdom.local/cert/IssuingCA.crl

Certificate is to be certified until Jan 20 13:14:33 2027 GMT (3650 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

-----------------------------------------------------------------------

## Keydatei erstellen mit Passwort (Ansonsten muss bei jeden Neustart des Servers die Passphrase eingegeben werden)
##
openssl rsa -in private/mysite.htdom.local.key | cat

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEArbdXG8+BUxm0NvO2pWXdx/0L3z/Nb+enAWqL59PzOuL63vXv
...
WyYHO6o4iUROOuJ9I0t0KsEDqkgh+VEOtcVfh8/gZ9IXyfXFyRhu09Q=
-----END RSA PRIVATE KEY-----

vim private/mysite.htdom.local.with.pwd.key
chmod 0400 private/mysite.htdom.local.with.pwd.key

-----------------------------------------------------------------------

## Zertifikat auslesen und auf dem Webserver importieren
##
cat /opt/ca/IssuingCA/certs/mysite.htdom.local.crt | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p'
cat /opt/ca/IssuingCA/private/mysite.htdom.local.with.pwd.key

-----------------------------------------------------------------------

## Ansicht auf dem Webserver
##
ls -la certs/mysite.htdom.local.crt
-rw-r--r-- 1 root root 1866 Jan 22 14:21 certs/mysite.htdom.local.crt

ls -la private/mysite.htdom.local.with.pwd.key
-rw-r----- 1 root root 1675 Jan 22 14:22 private/mysite.htdom.local.with.pwd.key

chmod 0640 /etc/ssl/private/mysite.htdom.local.with.pwd.key

tree /var/www/mysite_htdom_local/
/var/www/mysite_htdom_local/
├── cert
│   ├── IssuingCA.crl
│   ├── IssuingCA.crt
│   ├── RootCA.crl
│   └── RootCA.crt
└── index.html

mysite.htdom.local Konfiguration anpassen

vim /etc/nginx/sites-available/mysite.htdom.local

## Default Server Konfiguration mit https und rewrite
##
server {
  listen 80 default_server;
  listen [::]:80 default_server;

## Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
  return 301 https://$host$request_uri;

  access_log /var/log/nginx/access_mysite_htdom_local.log;
  error_log /var/log/nginx/error_mysite_htdom_local.log;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  root /var/www/mysite_htdom_local;
  index index.html;
    location / {
        try_files $uri $uri/ /index.html;
    }
  
## SSL Zertifikate
  ssl_certificate /etc/ssl/certs/mysite.htdom.local.crt;
  ssl_certificate_key /etc/ssl/private/mysite.htdom.local.with.pwd.key;
}

nginx -t
systemctl restart nginx.service
systemctl status nginx.service

Mit folgenden Befehl überprüft man, ob der nginx Server auf Port 80 und 443 lauscht

netstat -antlp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3776/nginx -g daemo
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3776/nginx -g daemo
tcp6       0      0 :::80                   :::*                    LISTEN      3776/nginx -g daemo
tcp6       0      0 :::443                  :::*                    LISTEN      3776/nginx -g daemo

 

 

 

 

 

 

Um noch mehr Sicherheit in die TLS Verbindung zu bekommen, sollte man das TLS Protokoll und den Schlüsselaustausch (Chiper) eingrenzen.
Dazu gibt es eine sehr gute Webseite von Mozilla, mit dieser Mozilla SSL Configuration Generator kann man sich die passende Konfiguration für seinen Webserver zusammenklicken.

https://mozilla.github.io/server-side-tls/ssl-config-generator/

Modern: Ist Stand heute die sicherste Einstellung, hier wird nur noch TLSv1.2 verwendet
Intermediate: Ist ein kompromiss aus Sicherheit und Kompatibilität, hier wird noch TLSv1 TLSv1.1 TLSv1.2 verwendet.
Old: Ist die schlechterste Wahl, hier wird sogar noch das veraltete SSLv3 verwendet.

Alle heutigen Browser unterstützen bereits TLSv1.2 daher sollte man, wenn möglich Intermediate oder Modern benutzen.
Um die Konfiguration auf der Webseite vornehmen zu können, müssen wir erst die nginx und openssl Version herausfinden, dies funktioniert mit folgenden Befehl.

nginx -V
nginx version: nginx/1.10.0 (Ubuntu)
built with OpenSSL 1.0.2g  1 Mar 2016

Und so sieht meine Modern Konfiguration aus

## Default Server Konfiguration mit https/rewrite und Modern Konfiguration
##
server {
  listen 80 default_server;
  listen [::]:80 default_server;

## Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
  return 301 https://$host$request_uri;

  access_log /var/log/nginx/access_mysite_htdom_local.log;
  error_log /var/log/nginx/error_mysite_htdom_local.log;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  root /var/www/mysite_htdom_local;
  index index.html;
    location / {
        try_files $uri $uri/ /index.html;
    }
  
## certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/ssl/certs/mysite.htdom.local.crt;
    ssl_certificate_key /etc/ssl/private/mysite.htdom.local.with.pwd.key;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

## modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

## HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;
}

SSL/TLS Verbindungstest kann man auf folgender Webseite durchführen
https://www.ssllabs.com/ssltest/index.html

Wenn man nun die Variante Modern nutzt, könnte die Handshake Simulation wie folgt aussehen.
Alle Browser die kein TLSv1.2 unterstützen, werden abgewiesen, bzw. können keine Verbindung zum Webserver aufbauen.

 

 

 

 

 

 

 

Viel Spaß beim ausprobieren

Gruß Helmut

 

 

 

 

 

In diesen Beitrag möchte ich kurz zeigen, wie man sich für eine Testumgebung oder vielleicht einen späteren Live Betrieb eine zweistufige PKI mit OpenSSL einrichtet.
Hierzu wurde ein Standard Ubuntu 16.04 LTS Server installiert.

Das wichtigste für eine CA ist die OpenSSL-Konfigurationsdatei, diese liegt Standardmäßig jeder openssl Installation bei, diese Datei wurde kopiert und auf die Testumgebung angepasst.
Wenn Ihr andere Installationspfade nutzen wollt, dann bitte dementsprechend die ca-config.cnf Datei nach euren Bedürfnisse anpassen.

locate *.cnf
/etc/ssl/openssl.cnf
/usr/lib/ssl/openssl.cnf

Was sehr wichtig ist, sind die Sektionen. Die URLs müssen unbedingt für die Testumgebung angepasst werden. Damit im Zertifikat später die richtigen URLs stehen.
Die Certification Revocation List (*.crl) muss über http:// erreichbar sein, wenn das nicht der Fall ist, kann es zu unnötigen Fehlern kommen.

[root_ca]
[issuingca_cert]
[user_cert]
[server_cert]

authorityInfoAccess = caIssuers;URI:http://server.domain.de/RootCA.html
crlDistributionPoints=URI:http://server.domain.de/RootCA.crl

authorityInfoAccess = caIssuers;URI:http://server.domain.de/IssuingCA.html
crlDistributionPoints=URI:http://server.domain.de/IssuingCA.crl

ca-config.cnf

# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd

# Extra OBJECT IDENTIFIER info:
oid_section = new_oids

[new_oids]
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7

####################################################################
[ca]
default_ca = RootCA        # The default ca section
####################################################################
[RootCA]

dir = /opt/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.
new_certs_dir = $dir/newcerts         # default place for new certs.
certificate = $dir/RootCA.crt         # 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 = $crl_dir/RootCA.crl             # The current CRL
private_key = $dir/private/RootCA.key # The private key
RANDFILE = $dir/private/.randRootCA   # private random number file
x509_extensions = user_cert           # The extentions to add to the cert
name_opt = ca_default                 # Subject Name options
cert_opt = ca_default                 # Certificate field options
default_days = 3650                   # how long to certify for
default_crl_days = 30                 # how long before next CRL
default_md = sha512                   # use public key default MD
preserve = no                         # keep passed DN ordering
policy = policy_anything              # CHANGE THIS
####################################################################
[IssuingCA]

dir = /opt/ca/IssuingCA               # 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.
new_certs_dir = $dir/newcerts         # default place for new certs.
certificate = $dir/IssuingCA.crt      # 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 = $crl_dir/IssuingCA.crl              # The current CRL
private_key = $dir/private/IssuingCA.key  # The private key
RANDFILE = $dir/private/.randIssuingCA    # private random number file
x509_extensions = user_cert               # The extentions to add to the cert
name_opt = ca_default                     # Subject Name options
cert_opt = ca_default                     # Certificate field options
default_days = 3650                       # how long to certify for
default_crl_days = 30                     # how long before next CRL
default_md = sha512                       # use public key default MD
preserve = no                             # keep passed DN ordering
policy = policy_match
####################################################################
[policy_match]

countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[policy_anything]

countryName = optional
stateOrProvinceName = optional
localityName  = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[req]

default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = root_ca
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 (Bayern)
stateOrProvinceName_default = Bayern
localityName = Locality Name (Muenchen)
localityName_default = Muenchen
0.organizationName = Organization Name (Company name or your Name)
0.organizationName_default = HTDOM Company GmbH
organizationalUnitName = Organizational Unit Name (Department)
organizationalUnitName_default = IT
commonName = Common Name (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_req]

# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

## Key Usage (Schlüsselverwendung)
# decipherOnly: Ist keyAgreement gesetzt, darf der Public-Key innerhalb eines Schlüsselaustausche zur Entschlüsselung von Daten verwendet werden. Andernfalls undefiniert.
# encipherOnly: Ist keyAgreement gesetzt, darf der Public-Key innerhalb eines Schlüselaustausches zur Verschlüsselung von Daten verwendet werden. Andernfalls undefiniert.
# cRLSign: Public-Key kann verwendet werden, um CRLs zu verifizieren.
# keysCertSign: Public-Key kann verwendet werden, um Zertifikate zu verifizieren.
# keyAgreement: Zur Verwendung beim Schlüsselaustausch.
# dataEncipherment: Zur Verwendung von „normalen“ Daten, also kein Schlüsseln.
# keyEncipherment: Public-Key wird zum Schlüsselmanagement verwendet.
# nonRepudiation: Key zur Prüfung von „bewußten“ Signaturen (außer CRLs und bei Zertifikaten).
# digitalSignature: Key zur Prüfung von „automatischen“ Signaturen (außer CRLs und bei Zertifikaten).
## keyUsage = [critical,] [decipherOnly,] [encipherOnly,] [cRLSign,] [keysCertSign,] [keyAgreement,] [dataEncipherment,] [keyEncipherment,] [nonRepudiation,] [digitalSignature]

## Extended Key Usage (Erweiterte Schlüsselverwendung)
# serverAuth: Authentisierung von Web-Servern durch Web-Clients
# clientAuth: Authentisierung von Web-Clients durch Web-Server
# codeSigning: Key zur Signierung von Programm-Code
# emailProtection: Key zur Verwendung mit S/MIME-Software
# timStamping: Signierung von Objekt-Hashwerten und zugehörigen vertrauenswürdigen Zeitstempeln

## Microsoft-Extensions
# msCodeInd: Individual Code Signing
# msCodeCom: Commercial Code Signing
# msCTLSign: Trust List Sign
# msSGC: Server-Zertifikat mit „Global Server ID“
# msEFS: Verschlüsselung von symmetrischen Keys zur Dateisystem-Verschlüselung

## Netscape-Extensions
# nsSGC: Server-Zertifikat mit "Global Server ID"
## keyUsage = [critical,] [serverAuth,] [clientAuth,] [codeSigning,] [emailProtection,] [timeStamping,] [msCodeInd,] [msCodeCom,] [msCTLSign,] [msSGC,] [msEFS,] [nsSGC,] [OID]

# [v3_req]
# Extensions to add to a certificate request
# basicConstraints = CA:FALSE
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# subjectAltName = @alt_names

# [alt_names]
# DNS.1 = servername.domain.de
# DNS.2 = servername
# DNS.3 =
# IP.1 = 192.168.xxx.yyy
# IP.2 = 192.168.yyy.zzz
# IP.3 =
####################################################################
[root_ca]

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:1
keyUsage = cRLSign, keyCertSign
subjectAltName=email:copy

# URI of the CA certificate 
authorityInfoAccess = caIssuers;URI:http://server.domain.de/RootCA.html
crlDistributionPoints=URI:http://server.domain.de/RootCA.crl
####################################################################
[issuingca_cert]

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = cRLSign, keyCertSign
subjectAltName=email:copy

# URI of the CA certificate 
authorityInfoAccess = caIssuers;URI:http://server.domain.de/IssuingCA.html
crlDistributionPoints=URI:http://server.domain.de/IssuingCA.crl
####################################################################
[user_cert]

basicConstraints=CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName=email:copy
extendedKeyUsage = clientAuth, emailProtection, codeSigning

# URI of the CA certificate 
authorityInfoAccess = caIssuers;URI:http://server.domain.de/IssuingCA.html
crlDistributionPoints=URI:http://server.domain.de/IssuingCA.crl 
####################################################################
[server_cert]

basicConstraints=CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth

# URI of the CA certificate 
authorityInfoAccess = caIssuers;URI:http://server.domain.de/IssuingCA.html 
crlDistributionPoints=URI:http://server.domain.de/IssuingCA.crl
####################################################################
[crl_ext]

authorityKeyIdentifier=keyid:always
####################################################################

Root Certificate Authority einrichten

## Ordnerstruktur für die RootCA anlegen
##
mkdir -p /opt/ca/RootCA
cd /opt/ca/RootCA

# certs - werden kopien der ausgestellten Zertifikate gespeichert
# crl -  wird eine kopie aller erstellen CRL’s gespeichert
# newcerts - wird eine kopie aller Zertifikats Requeste gespeichert
# private - Wird der private Schlüssel der Zertifizierungsstelle gespeichert
# revoke - hierhin werden alle gesperrten Zertifikate verschoben

mkdir certs crl newcerts private revoke

touch index.txt
echo "01" > serial
echo "01" > crlnumber

chmod 0600 private/

## Hier wird ein Random Nummer für die spätere Schlüsselerstellung generiert
##
openssl rand -out private/.randRootCA 8192
chmod 0400 private/.randRootCA

## Privaten Key für RootCA erstellen
##
openssl genrsa -aes256 -out private/RootCA.key 4096 -rand private/.randRootCA
2 x Passphrase eingeben (Hier sollte in einer Live Umgebung ein sehr komplexes Kennwort von min. 15-20 Stellen verwendet werden)
chmod 0400 private/RootCA.key

## Erstelle das Selbssignierte RootCA Zertifikat
##
openssl req -new -x509 -days 3650 -sha512 -key private/RootCA.key -out RootCA.crt -config ca-config.cnf
2 x Passphrase eingeben

Country Name (2 letter code) [DE]:DE
State or Province Name (Bayern) [Some-State]:Bayern
Locality Name (eg, Muenchen) []:Muenchen
Organization Name (eg, company) [Example Organisation]:HTDOM Company GmbH
Organizational Unit Name (eg, section) []:IT-Security
Common Name (e.g. server FQDN or YOUR name) []:HTDOM Root Certificate Authority
Email Address []:

Issuing Certificate Authority einrichten

## Ordnerstruktur für die IssuingCA anlegen
##
mkdir /opt/ca/IssuingCA
cd /opt/ca/IssuingCA
cp /opt/ca/RootCA/ca-config.cnf .

# certs - werden kopien der ausgestellten Zertifikate gespeichert
# crl -  wird eine kopie aller erstellen CRL’s gespeichert
# newcerts - wird eine kopie aller Zertifikat Requeste gespeichert
# private - wird der private Schlüssel der Zertifizierungsstelle gespeichert
# revoke - hier werden alle gesperrten zertifikate verschoben

mkdir certs crl newcerts private revoke

touch index.txt
echo "01" > serial
echo "01" > crlnumber

chmod 0600 private/

## Hier wird ein Random Nummer für die spätere Schlüsselerstellung generiert
##
openssl rand -out private/.randIssuingCA 8192
chmod 0400 private/.randIssuingCA

## Privaten Key für IssuingCA erstellen
##
openssl genrsa -aes256 -out private/IssuingCA.key 4096 -rand private/.randIssuingCA
2 x Passphrase eingeben (Hier sollte in einer Live Umgebung ein sehr komplexes Kennwort von min. 15-20 Stellen verwendet werden)
chmod 0400 private/IssuingCA.key

## Ertselle einen Zertifikat Request, der von der RootCA signiert wird.
##
openssl req -new -key private/IssuingCA.key -out newcerts/IssuingCA-Request.csr -config ca-config.cnf
2 x Passphrase eingeben

Country Name (2 letter code) [DE]:DE
State or Province Name (Bayern) [Some-State]:Bayern
Locality Name (eg, Muenchen) []:Muenchen
Organization Name (eg, company) [Example Organisation]:HTDOM Company GmbH
Organizational Unit Name (eg, section) []:IT-Security
Common Name (e.g. server FQDN or YOUR name) []:HTDOM Issuing Certificate Authority
Email Address []:

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

Issuing Certificate Request genemigen

cd /opt/ca/RootCA

## Zertifikats Request der IssuingCA bei der RootCA signieren
##
openssl ca -name RootCA -in /opt/ca/IssuingCA/newcerts/IssuingCA-Request.csr -out /opt/ca/RootCA/certs/IssuingCA.crt -extensions issuingca_cert -config ca-config.cnf

Using configuration from ca-config.cnf
Enter pass phrase for /opt/ca/RootCA/private/RootCA.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep 19 20:19:10 2016 GMT
            Not After : Sep 17 20:19:10 2026 GMT
        Subject:
            countryName               = DE
            stateOrProvinceName       = Bayern
            localityName              = Muenchen
            organizationName          = HTDOM Company GmbH
            organizationalUnitName    = IT-Security
            commonName                = HTDOM Issuing Certificate Authority
            emailAddress              = 
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                98:D9:DE:BB:D1:27:44:51:B3:F0:07:BD:95:59:39:3A:24:14:10:29
            X509v3 Authority Key Identifier: 
                keyid:7A:D8:D3:65:45:3F:C6:FF:7D:91:1F:15:53:6D:F8:0D:BA:E7:E3:8F

            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Key Usage: 
                Certificate Sign, CRL Sign
            X509v3 Subject Alternative Name: 
                email:
            Authority Information Access: 
                CA Issuers - URI:http://server.domain.de/RootCA.html

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://server.domain.de/RootCA.crl

Certificate is to be certified until Sep 17 20:19:10 2026 GMT (3650 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

Webserver Zertifikat erstellen

cd /opt/ca/IssuingCA

openssl genrsa -aes256 -out private/webserver01_htdom_local.key 2048 -rand private/.randIssuingCA
chmod 0400 private/webserver01_htdom_local.key
 
openssl req -new -key private/webserver01_htdom_local.key -out newcerts/webserver01_htdom_local.csr -config ca-config.cnf

openssl ca -name IssuingCA -in newcerts/webserver01_htdom_local.csr -out certs/webserver01_htdom_local.crt -extensions server_cert -config ca-config.cnf

Using configuration from ca-config.cnf
Enter pass phrase for /opt/ca/IssuingCA/private/IssuingCA.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep 19 20:54:03 2016 GMT
            Not After : Sep 17 20:54:03 2026 GMT
        Subject:
            countryName               = DE
            stateOrProvinceName       = Bayern
            organizationName          = HTDOM Company GmbH
            organizationalUnitName    = IT-Support
            commonName                = webserver01.htdom.local
            emailAddress              = 
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            Authority Information Access: 
                CA Issuers - URI:http://server.domain.de/RootCA.html

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://server.domain.de/RootCA.crl

Certificate is to be certified until Sep 17 20:54:03 2026 GMT (3650 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

Certification Revocation List erstellen

## Unabhängig ob gesperrte Zertifikate existieren oder nicht sollte eine Sperrliste für das Root/Issuing Zertifikat erstellt werden
##
cd /opt/ca/RootCA
openssl ca -config ca-config.cnf -gencrl -out RootCA.crl

cd /opt/ca/IssuingCA
openssl ca -config ca-config.cnf -gencrl -out IssuingCA.crl

Zertifikate wiederrufen

## Wird ein Zertifikat gesperrt, so ist die Sperrung in index.txt einzutragen
##
cd /opt/ca/IssuingCA
openssl ca -config ca-config.cnf -revoke certs/webserver01_htdom_local.crt

Nützliche Befehle

## Zertifikate und Private Keys überprüfen
##
## In diesen Beispiel wir der Private Key überprüft ob dieser mit dem Zertifikat zusammenpasst
## In dem Abschnitt modules, sieht man den Privaten Key
##
openssl x509 -noout -text -in /opt/ca/RootCA/RootCA.crt | less
openssl rsa -noout -text -in /opt/ca/RootCA/private/RootCA.key | less
Passphrase

modulus:
  00:ce:50:8a:8d:5e:8b:8d:47:38:b4:b0:25:d2:57:
  ...
  1b:56:ff

Modulus:
  00:ce:50:8a:8d:5e:8b:8d:47:38:b4:b0:25:d2:57:
  ...
  1b:56:ff

openssl x509 -noout -text -in /opt/ca/IssuingCA/IssuingCA.crt | less
openssl rsa -noout -text -in /opt/ca/IssuingCA/private/IssuingCA.key | less
Passphrase

## Zertifikatsrequest überprüfen, ob alle Angaben passen.
##
openssl req -noout -text -in /opt/ca/IssuingCA/newcerts/IssuingCA-Request.csr | less


## RootCA und IssuingCA Zertifikat überprüfen
##
openssl verify -CAfile /opt/ca/RootCA/RootCA.crt /opt/ca/IssuingCA/IssuingCA.crt
/opt/ca/IssuingCA/IssuingCA.crt: OK


## Zertifikat Chain aus RootCA und IssuingCA bilden
##
cat /opt/ca/IssuingCA/IssuingCA.crt /opt/ca/RootCA/RootCA.crt > /opt/ca/IssuingCA/HTDOM_IssuingCA_Chain.crt
chmod 444 /opt/ca/IssuingCA/HTDOM_IssuingCA_Chain.crt


## RootCA Zertifikat auf Windows Rechner downloaden und installieren
##
cat /opt/ca/RootCA/RootCA.crt | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p'

-----BEGIN CERTIFICATE-----
MIIGlzCCBH+gAwIBAgIJAMEh+l6C/y+PMA0GCSqGSIb3DQEBDQUAMIGPMQswCQYD
...
GPKo9XOLXNQhcWvo9J4cekWimz8z1Aj1YkEFkwKopY0+549r1W+H+OnZ1u0d77Zt
iw4t1xMigeji4qU=
-----END CERTIFICATE-----

## Zertifikat Chain auf Windows Rechner downloaden und installieren
##
cat /opt/ca/IssuingCA/HTDOM_IssuingCA_Chain.crt | sed -n -e '/BEGIN\ CERTIFICATE/,/END\ CERTIFICATE/ p'

-----BEGIN CERTIFICATE-----
MIIGmDCCBICgAwIBAgIBATANBgkqhkiG9w0BAQ0FADCBjzELMAkGA1UEBhMCREUx
...
Jt3lzRluOVcEZY4m
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGlzCCBH+gAwIBAgIJAMEh+l6C/y+PMA0GCSqGSIb3DQEBDQUAMIGPMQswCQYD
...
iw4t1xMigeji4qU=
-----END CERTIFICATE-----

Da kein Computer dieser Welt unsere CA kennt, müssen wir natürlich das Root CA Zertifikat und Issuing CA Zertifikat auf jeden Computer installieren.
Dazu lege ich mir eine RootCA.txt und eine IssuingCA.txt Datei lokal auf dem Computer an und hole mir wie oben beschrieben die Zertifikatsinformationen.

Wenn beide Text Dateien gefüllt sind, werden dies in *.crt umbenannt, danach installiere ich diese unter Windows in den passenden Zertifikatsspeicher.
Das RootCA Zertifikat wird in den „Vertrauenswürdige Stammzertifizierungsstelle“ installiert.

 

 

 

 

 

Und das Issuing CA Zertifikat wird unter „Zwischenzertifizierungsstelle“ installiert.

 

 

 

 

 

Wenn beide Zertifikate sauber installiert wurde, kann man sich das Zertifikat ansehen, in dem das man es doppelklickt und sich alle Informationen ansieht.

 

 

 

 

 

Unter Linux ist das ganze ein bisschen einfacher, hierzu kopiert man beide Zertifikate in den Zertifikatsspeicher und lässt ein Update laufen, danach sind dem Linux Server/Client die Zertifikate bekannt.

cp /opt/ca/RootCA/RootCA.crt /usr/local/share/ca-certificates/
cp /opt/ca/IssuingCA/HTDOM_IssuingCA_Chain.crt /usr/local/share/ca-certificates/
update-ca-certificates
Updating certificates in /etc/ssl/certs...
2 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

ls -la /etc/ssl/certs/RootCA*
lrwxrwxrwx 1 root root 43 Jan 22 12:57 /etc/ssl/certs/RootCA.pem -> /usr/local/share/ca-certificates/RootCA.crt

ls -la /etc/ssl/certs/HTDOM_IssuingCA_Chain.pem
lrwxrwxrwx 1 root root 58 Jan 22 12:57 /etc/ssl/certs/HTDOM_IssuingCA_Chain.pem -> /usr/local/share/ca-certificates/HTDOM_IssuingCA_Chain.crt

So nun viel Spaß beim ausprobieren.

Viele Grüße
Helmut

Hier in diesen Howto möchte ich euch zeigen, wie man die Zertifikatssperrliste(n) im Active Directory veröffentlicht. Das ganze wurde wieder in einer Virtuellen Umgebung mit Oracle – VirtualBox nachgestellt.

Die erste Frage die sich stellt, was ist eigentliche eine Zertifikatssperrliste?

  • Eine Zertifikatsperrliste (certificate revocation list, CRL) ist eine Liste, die die Ungültigkeit von Zertifikaten beschreibt. Sie ermöglicht es, festzustellen, ob ein Zertifikat gesperrt oder widerrufen wurde und warum.
  • Zertifikate werden gesperrt oder widerrufen, wenn deren zugehöriger Schlüssel z. B. nicht mehr sicher ist, weil sie in die falsche Hände geraten sind oder kompromittiert wurden – in solchen Fällen muss das Zertifikat noch vor dem eigentlichen Ablaufdatum gesperrt werden.

Hier geht es wieder zum Howto – Zertifikatssperrliste im Active Directory veröffentlichen

Viel Spaß damit

Gruß Helmut Thurnhofer

Hallo zusammen,

das wichtigste zuerst, wenn man sich nun intensiver mit PowerShell beschäftigen möchte, muss man seine Umgebung anpassen, um lokal Skripte ausführen zu können/dürfen.

Dazu dient das cmdlet „Set-ExecutionPolicy

Es gibt 5 verschieden Policy Einstellungen

Restricted = Die Powershell führt keine Skripte aus. Das ist der Defaulwert für die Powershell.
AllSigned = Die Powershell startet nur Skripte, die eine digitale Signatur haben.
RemoteSigned = Die Powershell wird keine Skripte ausführen, die aus dem Internet stammen – außer sie haben eine digitale Signatur.
Unrestricted = Die Powershell ignoriert die digitalen  Signatur, fragt aber nach, ob ein Skript, das aus dem Internet stammt, ausgeführt werden soll.
Bypass = Alle Skripte werden ohne Nachfrage ausgeführt (Sehr unsicher)

Undefined = Setzt den Defaultwert auf Restricted, sobald Gruppenrichtlinien im Einsatz sind, hat dieser Schalter keine Auswirkung.

Wenn man nun lokal Skripte ausführen möchte, setzt man dementsprechend seine ExecutionPolicy

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : Restricted
Set-ExecutionPolicy RemoteSigned

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts bei. Wenn Sie die Ausführungsrichtlinie ändern, sind Sie möglicherweise den im
Hilfethema "about_Execution_Policies" unter "http://go.microsoft.com/fwlink/?LinkID=135170" beschriebenen Sicherheitsrisiken ausgesetzt. Möchten Sie die
Ausführungsrichtlinie ändern?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): J

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : RemoteSigned
Set-ExecutionPolicy Unrestricted

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts bei. Wenn Sie die Ausführungsrichtlinie ändern, sind Sie möglicherweise den im
Hilfethema "about_Execution_Policies" unter "http://go.microsoft.com/fwlink/?LinkID=135170" beschriebenen Sicherheitsrisiken ausgesetzt. Möchten Sie die
Ausführungsrichtlinie ändern?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): J

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : Unrestricted

Sobald man aber in einen Firmenumfeld Powershell Skripte einsetzen möchte, sollte man seine fertigen Skripte mit einem Zertifikat signieren. Ob das Sinnvoll ist oder nicht, muss natürlich jeder für sich selbst entscheiden. Es gibt natürlich auch hier Mittel und Wege das ganze auszuhebeln, aber für unerfahrene Mitstreiter eine kleine Lebensaufgabe.

Hier die Vorbereitung um Firmenweit seine Powershellskripte zu signieren:
Als erstes erstelle ich eine neue Gruppenrichtlinien für die Domain, diese Gruppenrichtlinie verknüpfe ich mit der Domain.

Computerkonfiguration –> Richtlinien –> Administrative Vorlagen –> Windows-Komponenten –> Windows Powershell –> Skriptausführung aktivieren (Nur signierte Skripte zulassen)

GPO

 

 

 

 

 

GPO_Shortcut

 

 

 

 

 

Wenn man nun mit gpupdate /force die Gruppenrichtlinien aktualisiert, bekommt man beim Öffnen von PowerShell eine Fehlermeldung. (Bei mir war bereits eine PowerShell Profildatei hinterlegt)

PowershellError

 

 

 

 

 

Danach erstelle ich mir in Active Directory eine neue Rollengruppe und füge alle Mitglieder hinzu, die PowerShellSkripte signieren dürfen.

Rollengruppe

 

 

 

 

 

Jetzt öffne ich meine AD Zertifizierungsstelle und lege eine neue Zertifikatsvorlage an. Diese Zertifikatsvorlage Veröffentliche ich im Anschluss.

Zertifikatsvorlage1

 

 

 

 

 

Zertifikatsvorlage2

 

 

 

 

 

Zertifikatsvorlage3

 

 

 

 

 

Alle Benutzer die berechtigt sind, Skripte zu signieren. Öffnen nun eine neue MMC Konsole und fügen sich das SnapIn Zertifikate/Eigenes Benutzerkonto hinzu.

Unter Eigene Zertifikate –> Zertifikate –> Neu Aufgaben –> Neues Zertifikat anfordern, fordern nun die Benutzer ein Codesigning Zertifikat an.

Zertifikat_anfordern1

 

 

 

 

 

Zertifikat_anfordern2

 

 

 

 

 

Und mit folgenden beiden Befehlen kann man seine Skripte signieren

$Cert = Get-ChildItem Cert:\CurrentUser\My\ -Recurse -CodeSigningCert
Set-AuthenticodeSignature <Pfad>\PowershellScript.ps1 $Cert

Script_Signieren

 

 

 

 

 

Powershell_ohne_Error

 

 

 

 

 

Sobald die Gruppenrichtlinie AllSigned gesetzt wurde, kann man diese nicht mehr !vorübergehen! außer Kraft setzen.

keine_aenderung_moeglich

 

 

 

 

 

Viel Spaß und bis die Tage
Helmut

Hier in diesen Howto möchte ich euch zeigen, wie man die Active Directory-Zertifikatdienste Installiert und grundlegend konfiguriert. Das ganze wurde in einer Virtuellen Umgebung mit Oracle – VirtualBox nachgestellt. Diese Zertifikatstelle benötige ich für Exchange 2010 und Sharepoint 2010.

image

In den Serverrollen aktiviere ich die Active Directory-Zertifikatdienste und klicke auf Weiter

image

Aktiviere die Zertifizierungsstelle und die Zertifizierungsstelle-Webregistrierung, danach poppt der Rollen Assistent hoch dass noch der IIS zusätzlich Installiert werden muss.

image

Hier findet Ihr wieder das Howto zum folgenden Beitrag –>  Active-Directory-Zertifikatdienste (PKI) Installieren & konfigurieren

 

Viele Grüße
Helmut

Quellen:
Rachfahl IT Solution –> Link
Windows Server 2008 R2 Buch von Ulrich B. Boddenberg –> Link