상호 TLS 인증

Dialogflow가 웹훅 요청용으로 발생시킨 네트워크 트래픽은 공개 네트워크를 통해 전송됩니다. 양방향에서 트래픽이 안전하고 트래픽을 신뢰할 수 있도록 Dialogflow는 상호 TLS 인증(mTLS)을 선택적으로 지원합니다. mTLS를 사용하면 클라이언트(Dialogflow)와 서버(웹훅 서버) 모두 TLS 핸드셰이크 중에 인증서를 제시하며, 이 과정을 통해 서로 ID를 증명합니다.

mTLS 요청

mTLS를 요청하려면 다음 안내를 따르세요.

  1. TLS 핸드셰이크 중에 클라이언트 인증서를 요청하도록 웹훅 HTTPS 서버를 준비합니다.
  2. 웹훅 서버는 클라이언트 인증서를 받으면 이를 확인해야 합니다.
  3. 클라이언트와 서버가 모두 신뢰할 수 있는 웹훅 서버의 인증서 체인을 설치합니다. Google Trust Services CA 1O1(GTS CA 1O1)을 사용해야 합니다. GTS CA 1O1은 Google Trust Services가 소유하고 관리하는 GlobalSign R2 루트(GS 루트 R2)를 사용합니다. 이는 https://pki.goog/에서 다운로드할 수 있습니다.

데모 Node.js 서버

다음은 Node.js 데모 서버입니다.

  1. 자체 서명 인증서 및 PEM 파일을 준비합니다.
  2. 인증서 체인 파일을 준비합니다.
        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. 다음 샘플을 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. server.js를 실행합니다.
  5. requestCert를 true로 설정합니다.
        curl https://127.0.0.1:4433 -k
            
  6. 클라이언트 인증서를 전송합니다. SSL 핸드셰이크가 완료됩니다.
        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
            

오류

클라이언트 인증이 실패하는 경우, 예를 들어 클라이언트 인증서가 클라이언트에서 전송되지 않거나 클라이언트 인증서가 올바르게 서명되지 않은 경우 TLS 핸드셰이크가 실패하고 세션이 종료됩니다.

일반적인 오류 메시지:

오류 메시지 설명
클라이언트 인증서를 확인할 수 없음: x509: 알 수 없는 기관에서 서명한 인증서 Dialogflow가 클라이언트 인증서를 외부 웹훅으로 전송하지만 외부 웹훅에서 확인할 수 없습니다. 외부 웹훅에서 CA 체인을 올바르게 설치하지 않았기 때문일 수 있습니다. Dialogflow의 현재 CA는 Google Trust Services CA 1O1입니다. GTS CA 1O1은 Google Trust Services가 소유하고 관리하는 GlobalSign R2 루트를 사용합니다.