Pratique de TLS et des certificats

1. OpenSSL

1.1. Récupérer, visualiser, transcoder, vérifier manuellement un certificat

Visualiser un certificat :

cat /etc/pki/tls/certs/localhost.crt

Mieux présenté avec openssl :

openssl x509 -text -noout -in /etc/pki/tls/certs/localhost.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 28890 (0x70da)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=--, ST=SomeState, L=SomeCity, O=SomeOrganization, OU=SomeOrganizationalUnit, CN=localhost.localdomain/emailAddress=root@localhost.localdomain
        Validity
            Not Before: Sep 26 13:57:53 2016 GMT
            Not After : Sep 26 13:57:53 2017 GMT
        Subject: C=--, ST=SomeState, L=SomeCity, O=SomeOrganization, OU=SomeOrganizationalUnit, CN=localhost.localdomain/emailAddress=root@localhost.localdomain
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9d:fd:05:7b:39:c2:75:62:ac:41:9b:96:5d:af:
                    94:2e:80:d2:50:99:1a:9e:ad:6c:2b:ce:1a:6f:e5:
                    4c:2e:51:f2:13:13:b5:05:2f:f6:ac:42:97:96:a2:
                    52:3e:55:8b:70:fa:bb:af:93:7a:f7:a3:8f:a4:2e:
                    6e:cc:eb:53:1d:81:ed:58:8d:69:c1:6e:0e:e9:22:
                    89:46:55:e8:8a:fc:46:1a:c3:28:f3:38:c5:e4:8a:
                    4b:83:9a:96:79:e7:e4:53:4f:75:d9:5b:47:4f:5e:
                    88:e9:7a:a6:30:ef:a4:e0:ed:8e:02:6d:70:79:ea:
                    17:84:dc:41:75:7e:95:94:9f:dd:2b:fc:1b:15:a0:
                    5d:71:b1:5f:29:51:4a:0c:d4:0b:2e:8b:f8:4c:d8:
                    40:d1:b4:f9:1c:e7:18:d4:43:49:6b:81:f0:87:73:
                    b6:1c:a5:95:52:65:f8:72:33:1f:ad:3f:07:8f:7c:
                    44:3c:3d:64:e4:3f:7c:ea:79:db:a4:d7:ef:64:1f:
                    84:d6:81:cc:cc:1c:87:da:61:33:96:41:4b:7a:02:
                    84:a3:f0:ee:82:e0:93:e3:d5:fd:26:45:bc:f0:a1:
                    24:fc:d3:74:1e:8e:96:60:f7:4d:77:92:ca:a1:5a:
                    dc:26:6c:52:d9:d7:ea:3b:30:bc:67:36:1f:24:83:
                    6a:df
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
    Signature Algorithm: sha256WithRSAEncryption
         0c:06:72:8d:6d:29:ae:a5:5b:bf:8d:57:6e:7b:ff:82:98:ad:
         30:39:5f:6c:dc:cb:58:84:cc:ca:bc:cb:01:db:6f:e0:05:98:
         50:e0:88:8a:69:e7:7e:75:26:89:60:a8:ec:c7:b6:62:ef:b0:
         7e:9a:93:72:f6:89:d9:ef:f5:e8:33:a0:d2:92:b0:9a:95:5c:
         ee:21:83:d6:5f:88:df:89:b4:9d:3b:27:02:5d:b4:34:b8:00:
         e0:75:32:1e:77:71:3d:0b:62:82:43:a5:8a:71:30:9c:f2:56:
         e1:69:6f:25:a6:84:7b:b8:57:0a:f7:14:a1:f4:aa:0d:39:0e:
         4b:7d:5b:c9:06:d5:70:04:a4:bd:9e:e2:ca:46:80:90:36:e2:
         f0:12:f1:b5:0f:b5:da:21:d8:31:f3:c1:27:d3:47:b2:df:7b:
         9e:7c:86:2a:d2:25:57:83:70:5b:c0:c4:63:48:d8:56:f9:53:
         90:d9:7d:b0:a7:9e:38:0e:41:c9:c4:16:a5:55:5a:c3:1c:3c:
         7b:4d:51:2d:bb:a5:e0:af:96:6d:95:3d:d4:21:0f:5a:48:2c:
         83:92:a5:64:1e:57:65:8a:45:cf:5d:f2:d2:d0:d1:2d:6a:7c:
         18:df:ff:b2:bf:8f:f4:fe:78:10:b1:f4:82:31:19:96:b8:bd:
         11:b1:99:b2

Récupérer un certificat X509 en ligne :

openssl s_client -showcerts -connect www.linux.com:443
CONNECTED(00000003)
depth=2 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign CloudSSL CA - SHA256 - G3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Fastly, Inc.", CN = n.ssl.fastly.net
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=n.ssl.fastly.net
   i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
-----BEGIN CERTIFICATE-----
MIIOdjCCDV6gAwIBAgIMDvskHGiB0MJcky5oMA0GCSqGSIb3DQEBCwUAMFcxCzAJ
...
hLx9Lj/Y6X4/9l5lxjSFf5y+M9WHVWAR3VQ1dpTkkXfarj1eIRxZS2LsvBJjgw8b
XgwBVqdmBNkD0g==
-----END CERTIFICATE-----
 1 s:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
-----BEGIN CERTIFICATE-----
MIIEizCCA3OgAwIBAgIORvCM288sVGbvMwHdXzQwDQYJKoZIhvcNAQELBQAwVzEL
...
HY7EDGiWtkdREPd76xUJZPX58GMWLT3fI0I6k2PMq69PVwbH/hRVYs4nERnh9ELt
IjBrNRpKBYCkZd/My2/Q
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=n.ssl.fastly.net
issuer=/C=BE/O=GlobalSign nv-sa/CN=GlobalSign CloudSSL CA - SHA256 - G3
---
No client certificate CA names sent
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5535 bytes and written 373 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 639EF6139293984B77BA686502009FA32EE55CA40892D3772ECE1559DE411BA6
    Session-ID-ctx:
    Master-Key: 69CDFB6E8807850C181CE54D66676762FE1B6E5F8FE79B2D8E9CB6782EF6E5BA4A58835BC5BE3FFCC7EC11EABEB48EFD
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 1200 (seconds)
    TLS session ticket:
    0000 - 63 cc 77 4a 00 db 2c 42-2e 8f 76 23 dd a9 ae 53   c.wJ..,B..v#...S
    0010 - eb f3 5b 75 31 9c 7e dd-34 0e 27 9e c5 87 6f 3e   ..[u1.~.4.'...o>
    0020 - fb fd 08 7f 4c 97 d1 e6-88 67 32 e6 95 9e 70 ee   ....L....g2...p.
    0030 - 1c 8f f2 1a 98 b6 5e 20-3d b9 14 c3 c0 61 36 5b   ......^ =....a6[
    0040 - a6 05 43 fa bc 4c b3 58-8f a4 10 76 18 a0 11 12   ..C..L.X...v....
    0050 - 1b be 0d 04 48 85 a1 44-ea fb ad a0 3d 13 85 51   ....H..D....=..Q
    0060 - 1a fb f6 95 a1 1e 06 c2-e2 c7 ba 8b de 52 9e 1d   .............R..
    0070 - 64 56 db 5a c8 0b 82 43-84 6d a0 2f 0a ef 8e ef   dV.Z...C.m./....
    0080 - 73 64 b9 c7 c3 37 d0 ce-62 d5 44 0d fd cc 2f b4   sd...7..b.D.../.
    0090 - ea 34 8c a5 eb 0f 4b 0b-2b c9 bb 58 ec c8 44 e2   .4....K.+..X..D.

    Start Time: 1475086354
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Script de rapatriement en format PEM : get-certificate.sh

#!/bin/bash
host=$1
port=${2:-443}
echo | openssl s_client -connect ${host}:${port} 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Par exemple :

bash get-certificate.sh www.cisco.com 443 > cisco.pem

Affichage du certificat :

openssl x509 -in cisco.pem -text -noout

Transcodage PEM vers DER :

openssl x509 -inform PEM -in cisco.pem -outform DER -out cisco.der

Affichage du certificat encodé en format DER :

openssl x509 -inform DER -in cisco.der -text

Prise de connaissance du CA :

openssl x509 -inform DER -in cisco.pem -text | grep 'Issuer'
       Issuer: C=US, O=HydrantID (Avalanche Cloud Corporation), CN=HydrantID SSL ICA G2
                CA Issuers - URI:http://trust.quovadisglobal.com/hydsslg2.crt

Récupérer le CA :

wget http://trust.quovadisglobal.com/hydsslg2.crt

Vérifier le certificat de l’entité manuellement :

openssl verify -CAfile hydsslg2.crt cisco.crt

1.2. Créer un certificat x509 auto-signé

Création de la clé privée server.key :

openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus
.........................................+++
..................................................................................................................................................................................+++
e is 65537 (0x10001)

chmod 440 server.key

Avec la clé privée, création d’un fichier de demande de signature de certificat (CSR Certificate Signing Request) :

openssl req -new -key server.key -out server.req
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) [XX]:BE
State or Province Name (full name) []:Brussels
Locality Name (eg, city) [Default City]:Brussels
Organization Name (eg, company) [Default Company Ltd]:Linux
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

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

Auto-signature :

openssl x509 -req -days 365 -in server.req -signkey server.key -out server.crt
Signature ok
subject=/C=BE/ST=Brussels/L=Brussels/O=Linux
Getting Private key

Affichage du certificat :

openssl x509 -text -noout -in server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 10940766965370417421 (0x97d569969d3b710d)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=BE, ST=Brussels, L=Brussels, O=Linux
        Validity
            Not Before: Sep 28 18:31:12 2016 GMT
            Not After : Sep 28 18:31:12 2017 GMT
        Subject: C=BE, ST=Brussels, L=Brussels, O=Linux
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c4:1e:20:7c:04:56:ec:24:ef:df:02:d6:6e:95:
                    79:98:24:b1:76:51:3e:2d:46:e0:4a:b1:35:16:92:
                    7e:06:8d:03:2f:fd:6d:6f:e5:48:64:1c:11:d4:48:
                    40:08:27:53:a0:9c:cc:87:f9:f5:80:8a:44:9a:a6:
                    32:ba:30:a0:94:d9:0c:76:d0:db:26:a8:52:62:83:
                    2a:43:c1:c8:bf:36:49:a9:35:21:50:79:48:35:ca:
                    10:cf:15:f3:60:87:d2:f1:3e:b0:af:12:81:02:2e:
                    20:3a:29:a4:f2:8c:15:07:27:07:4c:05:27:b9:b6:
                    b3:d8:01:ff:77:13:ce:48:c7:ad:4c:08:64:af:39:
                    7d:1a:15:cf:aa:bd:7b:c3:d6:ae:21:7b:1f:d6:fa:
                    cc:af:39:ac:34:9e:fa:f7:a2:38:1e:b5:7b:d7:67:
                    c5:b2:9b:b5:08:af:55:27:08:87:16:8f:a4:5a:e4:
                    6f:ee:9f:05:0b:59:a1:d6:90:8e:96:66:d1:98:89:
                    27:43:ae:ba:60:f9:0d:9a:e9:1d:f4:07:a6:25:f3:
                    41:d5:a7:bc:78:4b:94:23:98:81:cf:32:1b:92:0a:
                    46:35:b7:1b:80:03:ca:14:f3:57:89:db:9c:3d:1e:
                    b3:79:61:8d:2c:49:0c:12:6b:22:fc:d1:44:64:cd:
                    e6:f1
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
         79:d6:0b:23:54:0b:16:cd:00:09:8a:1e:fb:cb:33:a4:8a:73:
         c8:38:54:6f:72:e6:37:81:bf:ed:18:67:18:96:93:a0:9d:d1:
         92:45:de:3f:f1:c8:16:75:fb:e1:b6:b6:e3:b8:91:a3:f8:65:
         d4:54:09:dd:e8:2a:ba:5e:23:e0:6a:e4:a1:31:61:85:f7:7a:
         7a:7a:24:4e:c9:ed:c4:ed:e1:f9:2f:d0:bd:a2:9b:ec:32:3b:
         c8:b0:2c:56:40:c7:69:ea:cd:52:1e:60:2f:31:92:3e:90:e0:
         c3:77:59:8b:a9:1e:dc:33:44:da:99:dc:3a:21:ad:df:c4:9a:
         c8:53:42:0b:9e:67:83:7f:3e:3f:82:18:07:12:5f:4b:12:ca:
         65:8c:a9:ee:00:ab:b5:39:bd:e0:33:0f:c9:d6:db:cc:d2:f3:
         1b:bb:6e:fe:bc:c4:2c:a6:e6:de:ee:e0:ba:ff:68:1b:9b:17:
         e5:3c:83:7d:c1:03:95:8a:84:44:53:1d:fc:97:a5:2c:17:74:
         41:80:39:f7:a9:18:7c:9d:6b:5c:cb:87:83:d3:aa:4b:f6:c7:
         f0:e6:5c:4a:ce:f2:a3:b5:ef:a6:4b:c4:e0:54:66:cf:e3:3e:
         42:df:e4:a8:9d:9e:97:14:6a:eb:e2:2d:5b:23:a7:68:56:82:
         ad:b3:6e:19

1.3. Tester une liaison TLS

Arrêter le pare-feu :

# systemctl stop firewalld
# iptables -X
# iptables -F
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

openssl s_server -accept 5000 -cert server.crt -key server.key -www -state

Tester la connexion :

curl ...

1.4. Créer un CA, signer des certificats (1)

1.5. Créer un CA, signer des certificats (2)

1.6. Révoquer un certificat

1.7. Créer un certificat pour une personne

2. Stunnel 4

3. Easy-RSA

easy-rsa - Simple shell based CA utilityx est un ensemble de script pour gérer les scripts d’une autorité de certification.

Terminologie utilisée

Pour éviter toute confusion, les termes suivants seront utilisés dans toute la documentation Easy-RSA. Les formulaires courts peuvent être remplacés par des formulaires plus longs si cela est pratique.

  • PKI : Infrastructure à clé publique. Cette section décrit l’ensemble des fichiers et des associations entre l’AC, les paires de clés, les requêtes et les certificats.
  • CA : Autorité de certification. C’est le “master cert” à la base d’une ICP.
  • cert : Certificat. Un certificat est une demande qui a été signée par un AC. Le certificat contient la clé publique, quelques détails décrivant le certificat lui-même et une signature numérique de l’AC.
  • request : Demande de certificat (en option’req’.) Il s’agit d’une demande de certificat qui est ensuite envoyée à une AC pour signature. Une demande contient les informations de certification souhaitées ainsi qu’une signature numérique de la clé privée.
  • paire de clés (keypair) : Une paire de clés est une paire de clés cryptographiques asymétriques. Ces clés sont divisées en deux parties : les clés publiques et les clés privées. La clé publique est incluse dans une demande et un certificat.

L’Autorité de certification (AC)

Le coeur d’une PKI est l’AC, ou Autorité de certification, et c’est aussi l’autorité la plus sensible en matière de sécurité. La clé privée de l’AC est utilisée pour signer tous les certificats émis, de sorte que sa sécurité est essentielle pour assurer la sécurité de l’ICP entière. Pour cette raison, il est fortement recommandé de conserver la structure de l’ICP de l’AC sur un système dédié à un tel usage sécurisé ; ce n’est pas une bonne idée de conserver l’ICP de l’AC mélangée à celle utilisée pour générer des certificats d’entité finale, comme des clients ou des serveurs (VPN ou serveurs Web).

Pour démarrer une nouvelle PKI, l’AC est d’abord créée sur l’environnement sécurisé. Selon les besoins de sécurité, cela peut être géré sous un compte verrouillé, un système dédié, ou même un système complètement hors ligne ou en utilisant des supports amovibles pour améliorer la sécurité (après tout, vous ne pouvez pas subir une intrusion en ligne si votre système ou PKI n’est pas en ligne). Les étapes exactes de création d’une AC sont décrites dans une section distincte. Lors de la création d’une nouvelle AC, la paire de clés de l’AC (clés privées et publiques) est créée, ainsi que la structure de fichier nécessaire à la signature des certificats émis.

Une fois qu’une AC a été créée, elle peut recevoir les demandes de certificat des entités finales. Ces certificats d’entité sont délivrés aux consommateurs de certificats X509, tels qu’un client ou un serveur d’un système VPN, Web ou de messagerie électronique. Les demandes de certificats et les certificats ne sont pas sensibles du point de vue de la sécurité et peuvent être transférés par n’importe quel moyen pratique, comme le courrier électronique, la clé USB, etc. Pour plus de sécurité, il est conseillé de vérifier que la demande reçue correspond à la copie de l’expéditeur, par exemple en vérifiant la somme de contrôle attendue par rapport à l’original de l’expéditeur.

Paires de clés et demandes

Les entités finales individuelles n’ont pas besoin d’une configuration complète de l’AC et n’auront qu’à créer une paire de clés et une demande de certificat associée. La clé privée n’est utilisée nulle part, sauf sur cette entité, et ne devrait jamais quitter ce système. Il est sage de sécuriser cette clé privée avec une phrase de passe forte, car en cas de perte ou de vol, le détenteur de la clé privée peut effectuer des connexions apparaissant comme le détenteur du certificat.

Une fois qu’une paire de clés est générée, la demande de certificat est créée et signée numériquement à l’aide de la clé privée. Cette demande sera envoyée à un AC pour signature et un certificat signé sera retourné.

Comment les demandes deviennent des certificats

Après qu’une AC ait signé la demande de certificat, un certificat signé est produit. Dans cette étape, la clé privée de l’AC est utilisée pour signer numériquement la clé publique de l’entité afin que tout système faisant confiance au certificat de l’AC puisse implicitement faire confiance au certificat nouvellement émis. Ce certificat signé est ensuite renvoyé à l’entité requérante. Le certificat émis n’est pas sensible du point de vue de la sécurité et peut être envoyé par des méthodes de transmission en texte clair.

Vérification d’un certificat délivré

Une fois que deux entités ont créé des paires de clés, envoyé leurs demandes à l’AC et reçu une copie de leurs certificats signés et du certificat de l’AC, elles peuvent s’authentifier mutuellement l’une l’autre. Ce processus n’exige pas que les deux entités aient préalablement échangé directement des renseignements sur la sécurité.

Lors du handshake TLS, chaque côté de la connexion présente sa propre chaîne de certification à l’extrémité distante. Chaque partie vérifie la validité du certificat reçu par rapport à sa propre copie du certificat de l’AC. En faisant confiance au CA root cert, le pair auquel ils s’adressent peut être authentifié.

L’extrémité distante prouve qu’il s’agit bien de l’entité identifiée par le certificat en signant un bit de données à l’aide de sa propre clé privée. Seul le détenteur de la clé privée est en mesure de le faire, ce qui permet à l’extrémité distante de vérifier l’authenticité du système auquel elle est connectée.

Etude de cas VPN “Road Warrior”

4. Mise en oeuvre d’HTTPS avec Apache 2

2.1. Installation de HTTPd Server sur Centos

Après une installation RHEL7 / Centos 7 :

yum install -y curl
yum groupinstall -y "Web Server"
echo "127.0.0.1 server.example.com" >> /etc/hosts
echo "ServerName server.example.com" >> /etc/httpd/conf/httpd.conf
systemctl enable httpd
systemctl start httpd
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --reload

Examen des emplacements du logiciel

La commande rpm -ql donne la liste des fichiers du paquetage httpd :

rpm -ql httpd

Principalement, on retouve les emplacements (pour Centos/RHEL) :

  • /etc/httpd/ avec notamment le fichier principal de configuration httpd.conf : fichiers de configuration.
  • /etc/httpd/conf.d/ : fichiers de configuration supplémentaires (vhosts).
  • /usr/lib64/httpd/ modules et librairies.
  • /usr/sbin/ binaires : httpd, apachectl, etc.
  • /usr/share/doc/httpd-*/ : documentation.
  • /var/log/httpd/ : emplacement des logs par défaut.
  • /var/www/html/ : emplacement par défaut des pages à servir.

2.2. Configurer un hôte virtuel

Fichier de configuration

cat /usr/share/doc/httpd*/httpd-vhosts.conf
# Virtual Hosts
#
# Required modules: mod_log_config

# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.

#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:@@Port@@>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "@@ServerRoot@@/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "/var/log/httpd/dummy-host.example.com-error_log"
CustomLog "/var/log/httpd/dummy-host.example.com-access_log" common
</VirtualHost>

<VirtualHost *:@@Port@@>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "@@ServerRoot@@/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "/var/log/httpd/dummy-host2.example.com-error_log"
CustomLog "/var/log/httpd/dummy-host2.example.com-access_log" common
</VirtualHost>

Mise en place d’un hôte virtuel HTTP

Mise en place pour l’hôte virtuel host1.example.com.

Le principe consiste à adapter la copie de ce fichier d’exemple dans /etc/httpd/conf.d/ sous le nom host1.example.com.

Pour rendre nos opérations plus souples, notamment si vous voulez choisir un autre nom de domaine, on propose de placer le nom de domaine en variable :

httpdomain="host1.example.com"

Résolution de nom locale

echo "127.0.0.1 ${httpdomain}" >> /etc/hosts

Création du dossier et des pages Web

mkdir -p /var/www/html/${httpdomain}
echo "${httpdomain} test page" > /var/www/html/${httpdomain}/index.html

Restauration de la policy Selinux sur le dossier créé

restorecon -Rv /var/www/html/${httpdomain}

Création du dossier et des fichiers pour les logs

mkdir -p /var/log/httpd
touch /var/log/httpd/${httpdomain}-error_log
touch /var/log/httpd/${httpdomain}-access_log

Configuration du vhost HTTP

cat << EOF > /etc/httpd/conf.d/${httpdomain}.conf
<VirtualHost *:80>
ServerAdmin webmaster@${httpdomain}
DocumentRoot /var/www/html/${httpdomain}
ServerName ${httpdomain}
ErrorLog /var/log/httpd/${httpdomain}-error_log
CustomLog /var/log/httpd/${httpdomain}-access_log common
</VirtualHost>
EOF

Redémarrage du service

apachectl restart

Diganostic

curl ${httpdomain}
httpd -D DUMP_VHOSTS
VirtualHost configuration:
*:80                   host1.example.com (/etc/httpd/conf.d/host1.example.com.conf:1)
*:443                  192.168.122.39 (/etc/httpd/conf.d/ssl.conf:56)

Script create_vhost_httpd.sh

https://gist.github.com/goffinet/33205a18152fe3a87a5cf2d46e65dc3f

bash -x create_vhost_httpd.sh host1.example.com
#!/bin/bash
#create_vhost_httpd.sh in Centos7
#Variables
host=$1
port="80"
location="/var/www/html"
error_log="/var/log/httpd/${host}-error_log"
access_log="/var/log/httpd/${host}-access_log common"
#Résolution de nom locale
echo "127.0.0.1 ${host}" >> /etc/hosts
#Création du dossier et des pages Web
mkdir -p ${location}/${host}
echo "${host} test page" > ${location}/${host}/index.html
#Restauration de la policy Selinux sur le dossier créé
restorecon -Rv ${location}/${host}
#Création du dossier et des fichiers pour les logs
mkdir -p /var/log/httpd
touch /var/log/httpd/${host}-error_log
touch /var/log/httpd/${host}-access_log
#Configuration du vhost
cat << EOF > /etc/httpd/conf.d/${host}.conf
<VirtualHost *:${port}>
ServerAdmin webmaster@${host}
DocumentRoot ${location}/${host}
ServerName ${host}
ErrorLog ${error_log}
CustomLog ${access_log}
</VirtualHost>
EOF
#Activation et lancement du service
systemctl enable httpd
systemctl start httpd
systemctl restart httpd
#Diganostic
curl ${host}
httpd -D DUMP_VHOSTS

2.3. Configuration d’un vhost en HTTPS

Trois possibilités pour faire fonctionner HTTPS avec des certificats x509 :

  1. Générer un CSR et le soumettre à un CA (Autorité de Certification) : le plus fonctionnel et sûr, mais moins souple et le plus coûteux sur le plan financier et administratif.
  2. Générer un certificat auto-signé : coût nul, mais pose un problème de sécurité qui peut devenir indépassable pour certaines applications. Utile pour des environnement de développement ou pour assurer la confidentialité simplement.
  3. Let’s Encrypt : coût nul, facile à déployer, sûr.

Aussi, il s’agit de s’intéresser à la force des certificats et aux protocoles autorisés.

Différentes méthodes sont disponibles, certaines valides dans tous les cas ou uniquement sous cette distribution RHEL7/Centos7.

Toujours pour une question de souplesse, on propose de placer le nom de domaine en variable :

httpdomain="host1.example.com"

Force des certificats

“Red Hat Keypair Generation (c)” tout-en-un

L’utilitaire ``crypto-utils` crée les configurations HTTPS pour Apache.

yum install -y crypto-utils
genkey --help
Unknown option: help
Usage: genkey [options] servername
    --test   Test mode, faster seeding, overwrite existing key
    --genreq Generate a Certificate Signing Request (CSR)
    --makeca Generate a self-signed certificate for a CA
    --days   Days until expiry of self-signed certificate (default 30)
    --renew  CSR is for cert renewal, reusing existing key pair, openssl certs only
    --cacert Renewal is for a CA certificate, needed for openssl certs only
    --nss    Use the nss database for keys and certificates
    --gdb    For package maintainers, to trace into the nss utilities
genkey ${httpdomain}

Génération du certificat public et de la clé auto-signée

openssl req -nodes -x509 -newkey rsa:4096 -days 365 \
-out /etc/pki/tls/certs/${httpdomain}.crt \
-keyout /etc/pki/tls/private/${httpdomain}.key \
-subj "/C=BE/ST=Brussels/L=Brussels/O=IT/CN=${httpdomain}"

Génération d’un CSR en manuel

  • Génération d’un clé sécurisée et non sécurisée
  • Génération du CSR

Eventuellement, auto-signer la requête CSR avec sa propre clé.

Si plusieurs certificats sont à gérér en interne, il est peut être nécessaire d’implémenter une autorité de certification (CA).

Ansible : Module command

Fonctionne mais “brut de décoffrage”.

- name: Install nginx and python-openssl
  apt:
    name:
      - nginx
      - python-openssl
    update_cache: yes
    cache_valid_time: 3600

- name: Create self-signed certificate, if configured.
  command: >
    openssl req -x509 -nodes -subj '/CN=localhost' -days 365
    -newkey rsa:4096 -sha256 -keyout  -out 
    creates=
  notify: restart nginx

- name: "fix right on key file"
  file:
    name: ""
    mode: 0600
  notify: restart nginx

Ansible : Modules openssl_privatekey, openssl_csr, openssl_certificate

Beaucoup plus élégante.

- name: Generate an OpenSSL private key.
  openssl_privatekey:
    path: ""
  notify: restart nginx

- name: Generate an OpenSSL CSR.
  openssl_csr:
    path: ""
    privatekey_path: ""
    common_name: localhost
  notify: restart nginx

- name: Generate a Self Signed OpenSSL certificate.
  openssl_certificate:
    path: ""
    privatekey_path: ""
    csr_path: ""
    provider: selfsigned
  notify: restart nginx

- name: "fix right on key file"
  file:
    name: ""
    mode: 0600
  notify: restart nginx

Fichier de configuration du vhost HTTPS par défaut

A l’installation du groupe “Web Server” sous Centos7/RHEL7, un fichier /etc/httpd/conf.d/ssl.conf active par défaut un vhost HTTPS (yum install -y mod_ssl), celui sert par défaut les pages en HTTPS.

grep -v '^$\|^\s*\#' /etc/httpd/conf.d/ssl.conf
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache         shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout  300
SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

On peut le désactiver en renommant ce fichier autrement qu’en .conf.

mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak

Nouveau vhost HTTPS

Par rapport à une configuration HTTP simple, quelques directives comme SSLCertificateFile, SSLCertificateKeyFile ainsi que d’autres paramètres comme le port d’écoute TCP 443 sont à ajouter/adapter. On ajoutera cette entrée dans le fichier de configuration.

cat << EOF >> /etc/httpd/conf.d/host1.example.com.conf
<VirtualHost *:443>
ServerAdmin webmaster@host1.example.com
DocumentRoot /var/www/html/host1.example.com
ServerName host1.example.com
ErrorLog /var/log/httpd/host1.example.com-error_log
CustomLog /var/log/httpd/host1.example.com-access_log common
    SSLEngine on
    # 128-bit mini anti-beast
    #SSLCipherSuite !EDH:!ADH:!DSS:!RC2:RC4-SHA:RC4-MD5:HIGH:MEDIUM:+AES128:+3DES
    # 128-bit mini PFS favorisé
    #SSLCipherSuite !EDH:!ADH:!DSS:!RC2:HIGH:MEDIUM:+3DES:+RC4
    # 128-bit securité maximale
    SSLCipherSuite !EDH:!ADH:!DSS:!RC4:HIGH:+3DES
    SSLProtocol all -SSLv2 -SSLv3
    SSLCertificateFile /etc/pki/tls/certs/host1.example.com.crt
    SSLCertificateKeyFile /etc/pki/tls/private/host1.example.com.key
</VirtualHost>
EOF

Vérifier la configuration.

apachectl configtest

Redémarrer le service et adapter le pare-feu.

apachectl reload
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Vérifications

httpd -D DUMP_VHOSTS
VirtualHost configuration:
*:80                   host1.example.com (/etc/httpd/conf.d/host1.example.com.conf:1)
*:443                  is a NameVirtualHost
         default server host1.example.com (/etc/httpd/conf.d/host1.example.com.conf:9)
         port 443 namevhost host1.example.com (/etc/httpd/conf.d/host1.example.com.conf:9)
         port 443 namevhost 192.168.122.38 (/etc/httpd/conf.d/ssl.conf:56)

Vérification client/serveur HTTP.

curl http://host1.example.com
host1.example.com test page

Vérification client/serveur HTTPS.

curl -k https://host1.example.com
host1.example.com test page

Vérification du certificat.

openssl s_client -connect host1.example.com:443 -state
...

Script create_vhost_httpds.sh

Source : https://gist.github.com/goffinet/935c79afaffb6860386880e8bbfb7287

bash -x create_vhost_httpds.sh host1.example.com
#!/bin/bash
#create_vhost_httpds.sh in Centos7
#Variables
host=$1
port="443"
location="/var/www/html"
error_log="/var/log/httpd/${host}-error_log"
access_log="/var/log/httpd/${host}-access_log common"
#Résolution de nom locale
echo "127.0.0.1 ${host}" >> /etc/hosts
#Création du dossier et des pages Web
mkdir -p ${location}/${host}
echo "${host} test page" > ${location}/${host}/index.html
#Restauration de la policy Selinux sur le dossier créé
restorecon -Rv ${location}/${host}
#Création du dossier et des fichiers pour les logs
mkdir -p /var/log/httpd
touch ${error_log}
touch ${access_log}
#Configuration du vhost HTTPS
cat << EOF >> /etc/httpd/conf.d/${host}.conf
<VirtualHost *:${port}>
ServerAdmin webmaster@${host}
DocumentRoot ${location}/${host}
ServerName ${host}
ErrorLog ${error_log}
CustomLog ${access_log} common
    SSLEngine on
    SSLCipherSuite !EDH:!ADH:!DSS:!RC4:HIGH:+3DES
    SSLProtocol all -SSLv2 -SSLv3
    SSLCertificateFile /etc/pki/tls/certs/${host}.crt
    SSLCertificateKeyFile /etc/pki/tls/private/${host}.key
</VirtualHost>
EOF
#Génération du certificat auto-signé
openssl req -nodes -x509 -newkey rsa:4096 \
-out /etc/pki/tls/certs/${host}.crt \
-keyout /etc/pki/tls/private/${host}.key \
-days 365 \
-subj "/C=BE/ST=Brussels/L=Brussels/O=webteam/CN=${host}"
#Activation et lancement du service
systemctl enable httpd
systemctl start httpd
systemctl restart httpd
#Diganostic
curl https://${host}
httpd -D DUMP_VHOSTS

Redirection HTTP vers HTTPS

Voir Let’s Encrypt.

Script vhost-creator

Pour la curiosité.

Source : https://github.com/mattmezza/vhost-creator.

1.8. Let’s Encrypt en Centos 7 pour Apache

Source : https://certbot.eff.org/all-instructions/#centos-rhel-7-apache

Installation du logiciel (Centos 7)

sudo yum - y install epel-release
sudo yum - y install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Démarrage rapide

certbot --apache
certbot --apache certonly
certbot renew --dry-run

Fonction Let’s Encrypt pour une installation silencieuse

site_name="www.mondomainepublic.fr"
https_installation() {
# Three times if DNS failure
certbot --apache --register-unsafely-without-email --agree-tos -d "${site_name}" -n || \
certbot --apache --register-unsafely-without-email --agree-tos -d "${site_name}" -n || \
certbot --apache --register-unsafely-without-email --agree-tos -d "${site_name}" -n
(crontab -l 2>/dev/null; echo "0 0,12 * * * python -c "import random; import time; time.sleep(random.random() * 3600)" && certbot renew") | crontab -
}