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 configurationhttpd.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 :
- 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.
- 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.
- 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 -
}