Gegenseitige TLS-Authentifizierung

Der von Dialogflow für Webhook-Anfragen initiierte Netzwerkverkehr wird über ein öffentliches Netzwerk gesendet. Dialogflow unterstützt optional die gegenseitige TLS-Authentifizierung (mTLS), um sicherzustellen, dass der Traffic in beide Richtungen sicher und vertrauenswürdig ist. Beim mTLS-Verfahren stellen sowohl der Client (Dialogflow) als auch der Server (Ihr Webhook-Server) während eines TLS-Handshakes ein Zertifikat zur gegenseitigen Bestätigung der Identität bereit.

mTLS anfordern

So fordern Sie mTLS an:

  1. Sie konfigurieren Ihren Webhook-HTTPS-Server so, dass er während des TLS-Handshakes das Clientzertifikat anfordert.
  2. Der Webhook-Server sollte das Clientzertifikat beim Empfang bestätigen.
  3. Sie installieren für den Webhook-Server eine Zertifikatskette, die sowohl vom Client als auch vom Server als vertrauenswürdig eingestuft werden kann. Dazu verwenden Sie Google Trust Services CA 101 (GTS CA 101). GTS CA 101 verwendet den GlobalSign R2-Root (GS Root R2), der Google Trust Services gehört und von diesem kontrolliert wird. Sie können es unter https://pki.goog/ herunterladen.

Node.js-Demoserver

Im folgenden ist ein Node.js-Demoserver dargestellt:

  1. Bereiten Sie ein selbst signiertes Zertifikat und eine PEM-Datei vor.
  2. Bereiten Sie die Datei der Zertifikatskette vor:
    curl https://pki.goog/gsr2/GTS1O1.crt | openssl x509 -inform der >> ca-crt.pem
    curl https://pki.goog/gsr2/GSR2.crt | openssl x509 -inform der >> ca-crt.pem
        
  3. Speichern Sie das folgende Beispiel als server.js:
    var https = require('https');
    const express = require('express')
    var fs = require('fs');
    var options = {
      // Specify the key file for the server
      key: fs.readFileSync('./server-key.pem'),
      // Specify the certificate file
      cert: fs.readFileSync('./server-crt.pem'),
      // Specify the Certificate Authority certificate
      ca: fs.readFileSync('./ca-crt.pem'),
      // Requesting the client to provide a certificate, to authenticate the user.
      requestCert: true,
      // As specified as "true", so no unauthenticated traffic
      // will make it to the specified route specified
      rejectUnauthorized: false
    };
    
    var app = express();
    app.use(function (req, res, next) {
      if (!req.client.authorized) {
        //return res.status(401).send('Client cert failed. User is not authorized\n');
      }
      // Examine the cert itself, and even validate based on that!
      var cert = req.socket.getPeerCertificate();
      if (cert.subject) {
        console.log('Client Certificate: ',cert);
        console.log('Client Certificate Common Name: '+cert.subject.CN);
        console.log('Client Certificate Location: '+cert.subject.L);
        console.log('Client Certificate Organization Name: '+cert.subject.O);
        console.log('Client Certificate Email Address: '+cert.subject.emailAddress);
      }
    
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end("hello world from client cert\n");
      next();
    });
    var listener = https.createServer(options, app).listen(4433, function () {
      console.log('Express HTTPS server listening on port ' + listener.address().port);
    });
         
  4. Führen Sie server.js aus.
  5. Setzen Sie requestCert auf true.
    curl https://127.0.0.1:4433 -k
        
  6. Senden Sie das Clientzertifikat. Der SSL-Handshake wurde erfolgreich abgeschlossen.
    curl -v -s -k --key client-key.pem --cert client-crt.pem https://localhost:4433
    openssl s_client -key client-key.pem -cert client-crt.pem -connect localhost:4433 -CAfile ca-crt.pem
        

Fehler

Wenn die Clientzertifizierung nicht erfolgreich ist (weil z. B. kein oder ein nicht korrekt signiertes Clientzertifikat vom Client gesendet wird), schlägt der TLS-Handshake fehl und die Sitzung wird beendet.

Häufige Fehlermeldungen:

Fehlermeldung Erklärung
Failed to verify client's certificate: x509: certificate signed by unknown authority Dialogflow sendet das Clientzertifikat an den externen Webhook, der es jedoch nicht bestätigen kann. Das kann daran liegen, dass der externe Webhook die CA-Kette nicht korrekt installiert hat. Die aktuelle CA von Dialogflow ist Google Trust Services CA 101. GTS CA 101 verwendet den GlobalSign R2-Root, der Google Trust Services gehört und von diesem kontrolliert wird.