상호 TLS 인증

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

mTLS 요청

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

  1. TLS 핸드셰이크 중에 클라이언트 인증서를 요청하도록 웹훅 HTTPS 서버를 준비합니다.
  2. 웹훅 서버는 클라이언트 인증서를 받으면 이를 확인해야 합니다.
  3. 클라이언트와 서버가 모두 신뢰할 수 있는 웹훅 서버의 인증서 체인을 설치합니다. Google 서비스에 연결하는 애플리케이션은 Google Trust Services에 등록된 모든 인증 기관을 신뢰해야 합니다. 루트 인증서는 https://pki.goog/에서 다운로드할 수 있습니다.

데모 Node.js 서버

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

  1. 자체 서명 인증서 및 PEM 파일을 준비합니다.
  2. 인증서 체인 파일을 준비합니다.
    curl https://pki.goog/roots.pem >> 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
        

권장사항

웹훅 요청이 자체 Dialogflow 에이전트에서 시작되도록 하려면 웹훅 서버의 웹훅 요청 리소스 이름(예: session)에서 프로젝트 ID를 확인해야 합니다.

오류

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

일반적인 오류 메시지:

오류 메시지 설명
클라이언트 인증서를 확인할 수 없음: x509: 알 수 없는 기관에서 서명한 인증서 Dialogflow가 클라이언트 인증서를 외부 웹훅으로 전송하지만 외부 웹훅에서 확인할 수 없습니다. 외부 웹훅에서 CA 체인을 올바르게 설치하지 않았기 때문일 수 있습니다. Google의 모든 루트 CA는 신뢰할 수 있어야 합니다.