Description technique

Bus de communication

RabbitMQ

Certificats de sécurité

X.509 Système, usager

Chiffrage en transit

Chiffrage entre modules externes

Tous les modules serveurs qui passent par internet communiquent entre-eux en utilisant une forme ou une autre de chiffrage.

Le bus de communication MQ est uniquement disponible avec le protocole amqps (ssl) et requiert un certificat ssl client.

Les autres connexions faites de l’extérieur doivent passer par nginx qui supporte https sur les ports 443 (certificat client optionnel) et 444 (certificat client obligatoire). Les connexions via nginx peuvent être converties en websocket lorsque l’application derrière le proxy le supporte.

Chiffrage entre modules internes

Pour l’instant, seul le module certissuer utilise une connexion http non sécurisée à l’interne. Tous les autres modules utilisent une connexion ssl généralement avec certificat client pour se connecter.

Connexions sécurisées via ssl avec certificat client obligatoire :

  • rabbitmq
  • mongodb
  • nginx (port 444)

Connexions sécurisées via ssl avec certificat client optionnel :

  • redis
  • nginx (port 443)

Connexions non sécurisées à l’interne:

  • certissuer: la requête de certificat (CSR) et le nouveau certificat généré sont passés par HTTP. Ceci simplifie la configuration d’un nouveau système ou récupération d’un système avec certificats expirés.

Chiffrage au repos

Fichiers, archives de backup.

Algorithmes cryptographiques

Utilisation de Chacha20Poly1305, Blake2 et Ed25519.

Algorithmes alternatifs. Pas de AES, SHA ni RSA.

Authentification

Webauthn et certificats X.509.

Accès système

Les composants système se font attribuer des certificats X.509 qui contiennent l’information requise pour se faire attribuer un compte sur le bus de communication MQ et si approprié dans une base de données.

Un composant peut se faire créer les comptes auxquels il a droit en émettant une commande HTTPS POST vers /administration/ajouterCompte sur le port 444 du serveur ciblé. Il doit utiliser son certificat client X.509 comme méthode d’authentification HTTPS. Le module midcompte, s’il est configuré sur le serveur ciblé, va vérifier que le certificat est présentemant valide et automatiquement créer les comptes appropriés. La réponse HTTP 200 est émise par midcompte pour confirmer que tous les comptes sont prêts. En cas de refus, la réponse est HTTP 403.

Accès usagers

Les usagers doivent utiliser webauthn (passkeys) pour correctement sécuriser leur compte. Il est aussi possible de donner accès aux navigateurs avec des codes d’activation qui expirent après 31 jours. Ces codes ne peuvent être activé que par webauthn sur un autre appareil avec le même compte usager ou par un administrateur.

Lorsque l’accès usager est vérifié, un certificat X.509 incluant le userId vérifié est émis et conservé localement par le navigateur. Ce certificat est nécessaire pour signer les messages émis au nom de l’usager sur le bus MilleGrilles. Ceci permet de garantir qu’il n’y a pas d’altération du contenu d’une commande ou un exploit qui changerait le userId des messages en transit puisque le userId n’est pas un paramètre du message.

Attributs conventionels des certificats X.509

  • Common Name (CN): nom du serveur ou nom de l’usager
  • Organizational Unit (OU): domaine (optionnel)
  • Organization (O): Identificateur de la MilleGrille

Attributs spéciaux ajoutés au certificats X.509

  • UserId
  • Roles
  • Domaines
  • Délégations (e.g administrateur)

Autorisation

Pas de OAuth, utilisation de valeurs locales dans la base de données et de paramètres custom dans les certificats X.509.

Tokens JWT générés par un serveur autorisé au besoin (e.g. streaming video ou fichiers). Permet fonctionnement entre plusieurs MilleGrilles.

Logiciels infrastructure

  • Docker
  • Nginx
  • RabbitMQ
  • MongoDB
  • Solr
  • Redis

Bus MilleGrilles et messages

MilleGrilles supporte plusieurs types de documents signés avec les certificats X.509. De ces documents, les types suivants sont des messages qui peuvent être émis directement sur le bus avec routage :

  • Requête
  • Commande
  • Événement
  • Réponse

Note: il existe d’autre types de documents signés (document et transaction) mais il ne peuvent pas transiter directement sur le bus MilleGrilles.

Requête

La requête sert à demander de l’information à un composant système qui génère une réponse. La requête doit être lecture-seulement et ne doit pas modifier le contenu du système (aucun effet de bord).

Commande

Une commande est une opération qui va modifier l’état du système. Si la modification est permanente, la commande va être convertie en transaction(s) et conservée dans les archives des domaines concernés.

Une commande ne fournit pas toujours de réponse, ceci est laissé à la discrétion de l’implémentation.

Événement

Un énévement est un message qui est émis sur le bus MilleGrilles sans être sollicité et qui peut être capturé par n’importe quel module avec le niveau de sécurité approprié. L’événement peut servir à générer de nouvelles transactions au besoin.

Réponse

La réponse est un message émis suite à une sollicitation via une requête ou une commande.

Note : Une réponse peut être chiffrée en utilisant l’information du certificat du demandeur. Tous les modules connectés au bus MilleGrilles doivent être capables de déchiffrer une réponse de manière transparente.

Routage

Les messages de type requete, commande et evenement vont sur un des 4 exchanges sécurisés (1.public, 2.prive, 3.protege ou 4.secure). Le certificat du module détermine les exchanges disponibles.

Formats de la routing key MQ pour un message sur un des exchanges sécurisés.

  • message kind.domaine ou role.action
  • message kind.domaine ou role.partition.action

Exemples sans partition :

  • requete.CoreTopologie.listeUserappsDeployees
  • requete.CoreMaitreDesComptes.chargerUsager
  • commande.media.transcoderVideo
  • commande.instance.transmettreCatalogues
  • evenement.filecontroler.status

Exemples avec partition :

  • commande.instance.f3a68d38-1ce6-4c51-a628-fb88a95d22ae.installerApplication
  • evenement.GrosFichiers.ff7db38a-111a-4df5-8e96-69648f0d55ba.newFuuid
  • evenement.instance.f3a68d38-1ce6-4c51-a628-fb88a95d22ae.presenceInstanceApplications

Le routage des réponses fonctionne avec les champs header reply_to et correlation_id du protocole MQ.

Sécurité du routage

Pour qu’un module puisse se connecter à MQ, un compte doit être créé en connectant le module en utilisant son certificat X.509 (client ssl) avec la commande HTTPS POST sur /administration/ajouterCompte sur le port 444 du serveur MQ.

Le compte du module est lié à son subject X.509 (CN,OU et O). Le compte se fait donner accès aux exchanges listés dans son certificat. Sur chaque exchange, le certificat se fait donner accès ou routage de messages de la manière suivante :

Write routing sur exchange

  • evenement.certificat.infoCertificat
  • requete.*
  • commande.*
  • evenement.global.*
  • evenement.ROLES.* (pour chaque role)
  • evenement.DOMAINES.* (pour chaque domaine)

Read routing sur exchange

  • requete.certificat.*
  • evenement.*
  • requete.global.*
  • requete.ROLE.*
  • requete.DOMAINES.*
  • commande.global.*
  • commande.ROLES.* (pour chaque role)
  • commande.DOMAINES.* (pour chaque domaine)

Règles

Le compte permet :

  • d’émettre des requêtes et commandes vers n’importe quel role ou domaine,
  • d’émettre des événements uniquement pour les roles et domaines enregistrés dans le certificat,
  • d’écouter des requêtes ou commandes uniquement pour les roles et domaines enregistrés dans le certificat,
  • d’écouter des événements de n’importe quel role et domaine,
  • émettre / écouter certains messages globaux et requêtes/réponses pour les certificats.

Par exemple :

Compte MQ: O=zbaTeMFXpvuALGcPLx7UYFjW2oCz8fbDpyyse5boZB22VX8NvSQfMaSR,OU=core,CN=f3a68d38-1ce6-4c51-a628-fb88a95d22ae

Permissions

Write routing sur exchange

  • evenement.certificat.infoCertificat
  • requete.*
  • commande.*
  • evenement.core.*
  • evenement.global.*
  • evenement.CoreBackup.*
  • evenement.CoreCatalogues.*
  • evenement.CoreMaitreDesComptes.*
  • evenement.CorePki.*
  • evenement.CoreTopologie.*

Read routing sur exchange

  • requete.certificat.*
  • evenement.*
  • requete.core.*
  • requete.global.*
  • requete.CoreBackup.*
  • requete.CoreCatalogues.*
  • requete.CoreMaitreDesComptes.*
  • requete.CorePki.*
  • requete.CoreTopologie.*
  • commande.core.*
  • commande.global.*
  • commande.CoreBackup.*
  • commande.CoreCatalogues.*
  • commande.CoreMaitreDesComptes.*
  • commande.CorePki.*
  • commande.CoreTopologie.*

Gestion de clés de chiffrage

Maître des clés, fiche et chiffrage X25519.

File controler et file hosts

Les fichiers d’une MilleGrille sont gérés par le composant CoreTopology qui synchronise tous les sites d’hébergement des fichiers. Le serveur de fichier de base de MilleGrilles est le file host.

Noter qu’un file host est un serveur indépendant des MilleGrilles qu’il héberge. Un nombre illimité de MilleGrilles peuvent utiliser le même file host. Chaque MilleGrille peut uniquement accéder et gérer ses propres fichiers sur le file host.

Le file controler récupère les événements émis par le file host pour une MilleGrille et fait le relai vers le bus. Il s’assure de distribuer les fichiers entre tous les file hosts pour que ces derniers agissent comme miroir les uns des autres. Régulièrement (à tous les jours), une vérification complète de la liste des fichiers conservés sur chaque file host est générée par le file host, téléchargée par le file controler et réconciliée dans CoreTopology.

Les modules systèmes et usagers (e.g. navigateurs) peuvent récupérer et uploader des fichiers directement via commandes GET/PUT https sur n’importe quel file host utilisé par une MilleGrille en utilisant leur certificat X.509 pour s’authentifier.

Les archives de transactions sont téléchargées vers tous les file hosts régulièrement, généralement dès qu’ils sont crées par les domaines. Ceci augmente les chances de récupérer le contenu de la MilleGrille en cas de problèmes.

Les fichiers hébergés sont vérifiés régulièrement par le filehost. Le hachage du contenu fait parti du nom de chaque fichier hébergé, c’est cette valeur qui est utilisée par le file host pour s’assurer de l’intégrité de chaque fichier. Pour une site avec moins de 10 téra-octets, la vérification complète devrait être complétée au moins 1 fois par mois par chaque file host.

Si un fichier est corrompu, il est déplacé vers le répertoire dumpster et un message est émis via le file controler. Tant qu’il y a au moins une autre copie valide du fichier sur un autre file host, il sera retransféré automatiquement dès que possible.

Noms de fichiers

Le fichiers conservés pour les usagers sont gérés par CoreTopology. Le nom d’un fichier correspond à son hachage blake2b encodé avec multihash et multibase en base58btc.

Exemple : zSEfXUAcuo5Fmvbr7oQVpagXtLqgAxzLi5cfEPN5NP34RJf6wAvwD3v8ENoVKj8TsYcVBqp8K1A255DUk1y2n3Su3b7iuP

Cette valeur est aussi appelée le fuuid (file unique id).

Les modules qui utilisent les fichiers vérifient le contenu en utilisant le fuuid.

Un fichier doit être chiffré. Le format courant de chiffrage MilleGrille est mgs4.

Chiffrage

Clés symétriques

Les clés symétriques sont générées à partir de la clé publique de la MilleGrille (celle du certificat CA). Ceci permet de récupérer la version X25519 de la clé et de la conserver dans les archives du Maitre des clés comme référence pour récupération du système au besoin.

La clé symétrique peut devoir être re-chiffrée pour être transmise à un composant tiers, généralement la clé active du maitre des clés.

En cas de traitement de plusieurs clés symétriques à transférer en même temps, il est préférable de créer une clé d’échange X25519 temporaire qui sera utilisable par le composant visé uniquement.

TODO - algorithme de chiffrage asymétrique vers plusieurs destinataires d’une même clé symmétrique.

mgs4

Implémentation libsodium chacha20poly1305 en blocks de 64 kilo-octets. Le header est conservé sous le nom de nonce en base64-nopad. La clé symmétrique est conservée dans les méta-données distinctes ou par le maître des clés de la MilleGrille.

Exemple de contenu d’une commande avec chiffrage

Exemple avec élément distinct pour le contenu chiffré

{
  "cuuid": null,
  "favoris": true,
  "metadata": {
    "cle_id": "z8to4MmYhygtNNnobkBsWPj34v5rcd5sxnhZDajvusF8M",
    "data_chiffre": "ILeP1TYQi/YTwbSwBczPPRN6r+nyWb1zQm8eq7PBClOR8QVKs09om3Al",
    "format": "mgs4",
    "nonce": "g2T9vcNqGOoBKLeCXISoppmJnzD9n2vZ",
    "verification": "zSEfXUCcmhoXqqL1aov9raWjyN2M2146yPwqPSWwAHftNiVxkD5uRprzJkjjjhUvmwfAcbbtXLcfXX8wRnRfcKmnC7fRDH"
  }
}

Exemple avec le contenu chiffré au même niveau que le contenu non-chiffré

{
  "doc_id": "b869d126abc14fde632b8c24194fd99342082aab66d255c66adcf2c78d5156a6",
  "groupe_id": "5ad2d74b3162dd0d9abe8d91dcc05ec02d385135ae9d17cb1ed0af359531dabc",
  "categorie_version": 1,
  "data_chiffre": "FHvvcILdLXYm5WkVeZebPmwR6lm2HBkdmZ3SIE9sIrNtz ... LpiyU662R/fGg+V/kEGV",
  "cle_id": "z6YHaBrzGQzvnZova6FzjfdkYuXCo44CujMD1pNwqHXCN",
  "format": "mgs4",
  "nonce": "48n7Aw23rxf2TIutgT4ovh21i1dlj4qQ",
  "compression": "gz"
}

Champs :

  • cuuid, favoris, doc_id, group_id, categorie_version - data non chiffré,
  • metadata : contient la structure du contenu chiffré et metadata de déchiffrage,
  • cle_id : identificateur à fournir au Maître des clés pour demander la clé,
  • data_chiffre : contenu chiffré (optionnellement compressé) en base64-nopad
  • format : format du chiffrage - mgs4 indique l’algorithme (chacha20poly1305 avec blocks de 64ko) et paramètre requis (header sous nonce)
  • nonce : header libsodium chacha20poly1305 encodé en base64-nopad, requis pour initialiser le déchiffrage
  • verification : (optionnel) digest de data_chiffre encodé avec multihash + multibase, ici blake2b,
  • compression : (optionnel) deflate ou gz lorsque le contenu est compressé avant le chiffrage.

Fichiers chiffrés avec mgs4

Pour chiffrer un fichier avec mgs4, les mêmes méta-données sont requises pour le déchiffrage et doivent être stockées par le domaine responsable du fichier. Le nom du fichier (fuuid) correspond à la valeur de vérification - c’est le digest blake2b encodé an multihash + multibase. Le contenu du fichier est équivalent au contenu de data_chiffre mais n’est pas limité à 10 méga-octets (limite des documents). Cette approche fonctionne présentement avec des fichiers de plus de 100 giga-octets.