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. Anwendungen, die eine Verbindung zu Google-Diensten herstellen, sollten allen Zertifizierungsstellen vertrauen, die unter Google Trust Services aufgeführt sind. Sie können Root-Zertifikate 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/roots.pem >> 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
        

Best Practice

Damit die Webhook-Anfragen von Ihren eigenen Dialogflow-Agents initiiert werden, prüfen Sie die Projekt-ID in den Ressourcennamen der Webhook-Anfragen (z. B. session) auf Ihrem Webhook-Server.

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. Alle Stamm-CAs von Google sollten vertrauenswürdig sein.