---
# System prepended metadata

title: Mise en place d'une autorité de certification racine

---

<style>
.blue {
  color: #4287f5;
}
.red {
  color: #f5425d;
}
.green {
  color: #63f542;
}
</style>

[TOC]

# Contexte


# Concepts

## HTTPS
![image](https://hackmd.io/_uploads/H1tk5_CdT.png)
Une connexion HTTP est une connection HTTP encapsulée au sein d'un tunnel chiffrée SSL/TLS
Ce chiffrement est en partie asymétrique : un transfert de clée publique est necessaire pour initier la connection.
Il est alors indispensable de fournir une preuve d'authenticité de la clé publique utilisée par le client (afin d'éviter les attaques type ["*Man in the middle*"](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)): c'est le rôle des certificats

## Certificats
Un certificat est un fichier contenant :
- Au moins <span class="blue">**une clée publique**</span> du/des service(s) web(s)
- Des <span class="green">informations/**métadonnées sur le service web**</span> : nom, email à contacter, localisation, etc...
- Des <span class="red">informations/**métadonnées sur le certificat**</span> : date de valitité, CA à l'origine de son émission (champs *Issued by*), ...
- Une **signature éléctronique**

Il est émis par une authorité de certification, se portant garante de sa **validité** et de son **integrité** via la **signature éléctronique**.

### La signature électronique
C'est la combinaison des métadonnées et de la clé publique su service web à securiser chiffrée par la clée privée de l'**autorité de certification**

## Autorité de certification (i.e. CA)
C'est l'institution responsable d'émettre des certificats. Elle est dite **de confiance** et permet d'assurer que les information contenues dans ces derniers sont valides.

:::info
Exemples : [Let's Encrypt](https://letsencrypt.org/), [EJBCA](https://www.ejbca.org/), [OpenXPKI](https://www.openxpki.org/), ...
On parle de [Public key infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure)
:::

### Génération d'un certificat par une CA
![image](https://hackmd.io/_uploads/HksiUK0_T.png)

La CA utilise un certificat racine **auto-signé** pour générer et signer des certificat pour les services web. (i.e. la clé privé du certificat à été utilisée pour chiffre les infos et la clé publique associée)
:::info
Certificat **auto-signé** : Certificat ayant été signé par sa propre clé privée.

Utilisé tel quel, ce type de certificat n'apporte **aucune garantie sur les informations** contenues dans le certificat.
Il est cependant necessaire au démarrage d'une **chaine de confiance**.
Il devient **"de confiance"** uniquement lorsqu'il est émis par un **tier de confiance** (typiquement une CA)
:::

### Chaine de confiance
Une chaine de confiance est l'élément clé permettant de s'assurer que la clé publique fournie par un service web est authentique

![image](https://hackmd.io/_uploads/By_PG6A_T.png)

- Le ***Root certificate*** est auto-signé et edité par une autoritée de confiance racine
- Chaque certificat peut servir à editer et signer un autre certificat via sa clé privé. La verification de l'authenticité du certificat édité se fait en dechriffrant sa signature via la clé publique du certificat editeur (connue du sytèeme ou recupérée)
:::info
Chaque certificat est donc **édité par** une autorité, **pour** une autre autoritée ou un service.
On parle alors des champs **"*Issued by*"** et **"*Issued for*"** d'un certificat
Ces champs sont égaux dans le cas d'un *root certificate* :
![image](https://hackmd.io/_uploads/B1TTXTCO6.png)
:::
- Des autorités de confiance intemediaires éditent des ***certificats intermediaires***, menant jusqu'au ***End-entity certificate***, utilisés en pratique pour communiquer de manière chiffrée avec les services utilisateur.

La chaine de confiance **transmet la confiance** accordée à l'autorité de confiance racine jusqu'au service webs utilisées par l'utilisateur.
Ce mode de fonctionnement par autorité de confiance intermediaire permet de decentraliser les responsabilités de validation des certificats.
Il suffit ainsi d'avoir confiance en un des maillons de la chaine pour la valider entièrement.

Cette confiance se traduit par le stockage en local d'une copie du certificat (donc de la clé publique) de l'autorité.
Ces certificats sont stockés au sein du **magasin de certificats** de l'OS.
![image](https://hackmd.io/_uploads/SJ30PTR_a.png)


# Contexte MERIO : HTTPS sur LAN
Dans notre cas, le serveur GitLab est hébergé sur le réseau privée de MERIO. Plusieurs choix nous sont possibles pour instaurer une communication chiffrée avec ce dernier :
- Le premier consiste à utiliser un certificat auto-signé. Il permettra le chiffrement des communications avec le serveur GitLab, mais sera vu comme non sécurisé par les navigateurs web, car il n'est signé par aucune authotorité de confiance racine.
:::warning
Il s'agit de la procédure décrite [ici](https://hackmd.io/GTcrRsdWReCqfPcI4O45QA)
:::
- La deuxième méthode consiste à générer un *root certificate*, et de le faire lui même signer un *end-entity certificate* utilisable par la suite par GitLab.
Cela necessite alors d'ajouter le *root certificate* ainsi generé au sein du **magasin de certificats** de l'OS pour **rendre légitime son auto-signature**.
Il pourra également servir à générer autant de certificats que nécessaire pour les autres services web hébergés sur le LAN MERIO.

## Génération d'un root certificate

**Sur `support@192.168.10.102`** :
- Création sur d'un repertoire dédié au stockage des certificats :
`mkdir ~/certs`
`cd ~/certs`
- Génération de la clé privée du *root certificate* :
    `openssl genrsa -des3 -out merioCA.key 2048`
:::danger
Passphrase définie : **`lh3UR3D3SS1n932`**
:::
- Génération du *root certificate* via la clé privée :
`openssl req -x509 -new -nodes -key merioCA.key -sha256 -days 3650 -out merioCA.pem`
    - Infos saisies (Les champs peuvent êtres laissés vide) :
    ```
    Enter pass phrase for merioCA.key: lh3UR3D3SS1n932
    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) [AU]:FR
    State or Province Name (full name) [Some-State]:Drome
    Locality Name (eg, city) []:Saint Restitut
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:MERIO
    Organizational Unit Name (eg, section) []:
    Common Name (e.g. server FQDN or YOUR name) []:MERIO BESoft
    Email Address []:
    ```
Le root certificate **`merioCA.pem`** est donc signé par **`merioCA.key`**, il est **auto-signé**.

:::info
**`merioCA.pem`** et **`merioCA.key`** sont récuperables sur le serveur au chemin :
`\\192.168.10.100\serveurM\ECHANGES\COMMUN\MERIO_Root_Certificate.zip`
Mot de passe **`merio`**
:::

## Génération d'un *end-entity certificate* signé par le *root certificate*
Nous souhaitons maintenant signer un *end-entity certificate* via le *root certificate* de MERIO afin de le fournir à un service web.

**Sur `support@192.168.10.102`** :
- Création de la clé privée du *end-entity certificate* :
    `openssl genrsa -out <hostname>.key 2048`
:::warning
Il est préférable de donner le hostname (nom de domaine ou IP) du service à la clé privée et au *end-entity certificate*
:::
- Création d'une [*certificate signing request*](https://en.wikipedia.org/wiki/Certificate_signing_request) :
`openssl req -new -key <hostname>.key -out <hostname>.csr`
Il s'agit du message demandant à l'autorité de certification la signature des éléments qu'elle contient (la clé publique et des métadonnées)
Elle est **toujours auto-signée**
Il convient donc la completer avec les informations du service à sécuriser (Les champs peuvent aussi êtres laissés vide):

```
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) [AU]:FR
State or Province Name (full name) [Some-State]:Drome
Locality Name (eg, city) []:Saint Restitut
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MERIO
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:MERIO BESoft
Email Address []:

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

Avant de generer le *end-entity certificate* par cette *certificate signing request*, nous créons un fichier de configuration `<hostname>.ext`

```
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = merio.besoft.com
IP.1 = 192.168.10.102
```
Il permet d'éditer plus finement les paramettres du *end-entity certificate*. En particulier, la section `[alt_names]` permet de lister les [**`Subject Alternative Name`**](https://en.wikipedia.org/wiki/Subject_Alternative_Name), c'est à dire les noms de domaine et IPs du service à sécuriser.

- Création du *end-entity certificate*, configuré par la `CSR` et le fichier `<hostname>.ext`, puis signé par le *root certificate* `merioCA.pem`
```BASH
openssl x509 -req -in <hostname>.csr -CA myCA.pem -CAkey myCA.key \
-CAcreateserial -out <hostname>.crt -days 825 -sha256 -extfile <hostname>.ext
```

Nous obtenons au final les fichiers suivants :
- `<hostname>.crt` le *end-entity certificate*
- `<hostname>.key` la clée privée du *end-entity certificate*

Ce sont ces deux fichiers qui sont à fournir au services web à securiser.

:::info
Pour le serveur **GitLab**
**`192.168.10.102.crt`** et **`192.168.10.102.key`**sont récuperables sur le serveur au chemin :
`\\192.168.10.100\serveurM\ECHANGES\COMMUN\GitLab_end-entity_Certificates.zip`
Mot de passe **`merio`**
:::

### Installation du *end-entity certificate* sur GitLab

**Sur `support@192.168.10.102`** :
- Télécharger l'archive :
`\\192.168.10.100\serveurM\ECHANGES\COMMUN\GitLab_end-entity_Certificates.zip`
- Extraire l'archive dans `/etc/gitlab/ssl/`
:::warning
Mot de passe **`merio`**
:::
- Reconfigurer GitLab :
`sudo gitlab-ctl reconfigure`
- Faire recharger la configuration et les nouveaux certificats à NGNIX :
```
sudo gitlab-ctl hup nginx
sudo gitlab-ctl hup registry
```

## Installation du *root certificate* sur le poste de développement

> Le présent paragraphe décrit la procédure à suivre pour ajouter l'autorité de certification racine (Et donc le *Root certificate*) générée sur un poste de dev afin de securiser les connexions aux services web de MERIO.
> 
> :::danger
> Le dossier `C:\Users\user\ssl_cert` décrit par [ce guide](https://hackmd.io/GTcrRsdWReCqfPcI4O45QA), contenant le certificat auto-signé, peut être supprimé
> :::
### Windows 10
- Télécharger l'archive depuis le serveur
`\\192.168.10.100\serveurM\ECHANGES\COMMUN\MERIO_Root_Certificate.zip`
- Décompresser l'archive dans `C:\Users\user\certs` (créer le dossier `certs` si besoin)
    :::warning
    Mot de passe `merio`
    :::
- Supprimer le fichier **`merioCA.key`** (la clé privée du certificat ne doit pas être diffusée)
- Saisir `mmc` dans le menu *Executer* (Win + R) pour ouvrir la `Microsoft Management Console`
    ![image](https://hackmd.io/_uploads/rkXFyipua.png)
- `Fichier` -> `Ajouter/supprimer un composant logiciel enfichage...`
    ![image](https://hackmd.io/_uploads/B1LokjTdT.png)
- `Certificats` -> `Ajouter >`
    ![image](https://hackmd.io/_uploads/BytRkop_6.png)
- Sélectionner `Un compte d'ordinateur`
    ![image](https://hackmd.io/_uploads/SJU-lip_p.png)
- Sélectionner `L'ordinateur local`
    ![image](https://hackmd.io/_uploads/BkWkSsadT.png)
- Cliquer sur `Terminer`
    ![image](https://hackmd.io/_uploads/ryYBSjaO6.png)
- Cliquer sur `OK`
    ![image](https://hackmd.io/_uploads/B1kKHipdT.png)
- Selectionner `Certificats` puis clique droit sur `Autorités de certification racines de confiance` -> `Toutes les tâches` -> `Importer`
    ![image](https://hackmd.io/_uploads/Sk9k8o6uT.png)
- Cliquer sur `Suivant`
    ![image](https://hackmd.io/_uploads/SyYVIj6uT.png)
- `Parcourir` -> Sélectionner `C:\Users\user\certs\merioCA.pem`, puis `Ouvrir`
    ![image](https://hackmd.io/_uploads/rkJPOs6da.png)
:::info
Il peut être necessaire de selectionner `Tous les fichiers (*.*)` dans le menu deroulant indiquant l'extension du fichier pour rendre `merioCA.pem` visible.
![image](https://hackmd.io/_uploads/rk7gFop_T.png)
:::
- Cliquer sur `Suivant`
    ![image](https://hackmd.io/_uploads/S1gNYsp_p.png)
- Cliquer sur `Suivant`, puis `Terminer`
    ![image](https://hackmd.io/_uploads/r1Mcto6_6.png)
    ![image](https://hackmd.io/_uploads/S1KTti6up.png)
- Le certificat `MERIO BESoft` doit maintenant être visible dans le sous menu `Certificats`
![image](https://hackmd.io/_uploads/BJr-5op_a.png)
- Enregistrer la Console dans `C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools`, puis quitter la `Microsoft Management Console` 
- Supprimer la configuration par certificat auto-signé précedente du fichier `C:\Users\user\.gitconfig`
![image](https://hackmd.io/_uploads/BygXuk1Ya.png)
- Lancer dans un `Git BASH` la commande :
`git config --global http.sslBackend schannel`
:::info
Cette commande indique à git d'utiliser le magasin de certificats de Windows.
:::

Le fichier`C:\Users\user\.gitconfig` a desormais la forme suivante :
![image](https://hackmd.io/_uploads/HyZq_JktT.png)



L'accès à l'interface web du GitLab est désormais reconnu comme sécurisé par le navigateur.
![image](https://hackmd.io/_uploads/rk4xn6ROp.png)
Les echanges en HTTPS avec le serveur git sont égalements fonctionnels.

# Sources
- [Create Your Own SSL Certificate Authority for Local HTTPS Development](https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/)
- [How to generate a self-signed SSL certificate for an IP address](https://medium.com/@antelle/how-to-generate-a-self-signed-ssl-certificate-for-an-ip-address-f0dd8dddf754)
- [Creating a Self-Signed Certificate With OpenSSL](https://www.baeldung.com/openssl-self-signed-cert)
- [How do I configure Git to trust certificates from the Windows Certificate Store?](https://stackoverflow.com/questions/16668508/how-do-i-configure-git-to-trust-certificates-from-the-windows-certificate-store)
