본문 바로가기
MiddleWare(미들웨어)/WebtoB

[WebtoB] MTLS 설정하기

by wonkidoki 2024. 2. 19.
반응형

MTLS(Mutual TLS) 란?

- 상호 인증을 위한 방법으로 간단히 말해 양방향 TLS 통신을 하는 것이라고 보면 된다.

- WebtoB *SSL 절, ReverseProxy를 사용한다면 *ProxySSL 절을 통해 설정할 수 있다.

- 기존 WebtoB에 등록된 SSL 인증서 + MTLS를 사용할 대상 CA 인증서가 필요하다.

 

*SSL 절 설정 가이드

 

ssl1     CertificateFile="/tmax/webtob/ssl/aaa.bbb.com.crt",
          CertificateKeyFile="/tmax/webtob/ssl/aaa.bbb.com.key",
          CACertificateFile="/tmax/webtob/ssl/chainca.crt",
          CertificateChainFile="/tmax/webtob/ssl/tossca.crt", // 토스 CA 인증서 추가
          CACertificatePath="/tmax/webtob/ssl/",
          VerifyClient = 2,
          VerifyDepth = 3,
          Options = "ExportClientCert",
          Protocols="-SSLv3, -SSLv2, -TLSv1, TLSv1.1, TLSv1.2, TLSv1.3"

VerifyClient 값에 따라 인증 절차가 달라진다. 해당 값에 대한 설명은 아래 내용을 참고한다.

CertificateChainFile 의 경우 인증서를 1개 밖에 설정 할 수 없다. 

mTLS 인증서를 추가적으로 설정한다면 SSL절을 하나 더 만들어야 한다.

VerifyClient

  • 종류: Numeric
  • 기본값: 0
  • 사용자에게 요청할 인증 레벨을 설정한다.
  • 다음은 인증 레벨에 대한 설명이다.
    레벨설명
    0 아무런 인증 요청을 하지 않는다.
    1 사용자는 사용 가능한 인증을 서버에게 보여 주어야 한다.
    2 사용 가능한 인증을 반드시 서버에게 보여 주어야 한다.
    3 사용자는 사용 가능한 인증을 보여 주어야 하며 만일 서버가 인증서를 가지고 있지 않은 상황에서는 인증서 인증 과정이 필요 없다.

VerifyDepth

  • 종류: Numeric
  • 범위: 0 ~ INT_MAX
  • 기본값: 0
  • 실제 업무에 적용되는 경우에 인증에서 개입할 부분은 순서대로 다른 CA에 의해서 서로를 인증하는 CA에 관한 것이다. VerifyDepth 항목은 얼마나 깊은 레벨로 연결된 CA들을 추적하여 인증할 것인지를 설정한다. 단 하나의 인증 CA만 필요하다면 1로 설정한다.

Options

  • 종류: Literal
  • 범위: 255자 이내
  • 다음은 설정 가능한 옵션에 대한 설명이다.
  • 옵션내용
    StdEnvVars SSL Handshake 과정에 사용된 기본 정보를 CGI/PHP, JEUS, Reverse Proxy 내부 서버에서 사용 가능하도록 SSL 환경변수 또는 HTTP Request Header 값을 생성한다.
    • CGI/PHP 서버에서 사용 가능한 환경변수: SSL_SESSION_ID(SSL session id), SSL_CIPHER(사용된 cipher), SSL_CIPHER_USEKEYSIZE(사용된 cipher bit)이다.
    • JEUS 또는 Reverse Proxy 내부 서버에서 사용 가능한 HTTP Request Header: WJP-SSL-SESSION-ID(SSL session id), WJP-SSL-CIPHER(사용된 cipher), WJP-SSL-CIPHER-USEKEYSIZE(사용된 cipher bit)이다.

    다음은 각 언어별 예이다.
    • CGI
    • PHP
    • JSP
    ExportClientCert 클라이언트 인증을 실행하는 경우(VerifyClient = 2 설정을 적용한 경우) 클라이언트 인증서를 CGI/PHP, JEUS, Reverse Proxy 내부 서버에서 사용 가능하도록 SSL 환경변수 또는 HTTP Request Header 값을 생성한다. 클라이언트 인증서의 확장필드(Extension Fields - Key Usage, Certificate Policies, CRL Distribution Points 등)를 처리하기 위해서는 해당 설정으로 클라이언트 인증서 정보를 얻어 파싱 후 사용해야 한다.
    • CGI/PHP 서버에서 사용 가능한 환경변수: SSL_CLIENT_CERT(클라이언트 인증서-PEM 인코딩된 String 값)이다.
    • JEUS 서버 또는 Reverse Proxy 내부 서버에서 사용가능한 HTTP Request Header: WJP-SSL-CLIENT-CERT(클라이언트 인증서-PEM 인코딩된 String 값)이다.

    다음은 각 언어별 예이다.
    • CGI
    • PHP
    • JSP

 

호출 테스트 (--cert, --key 옵션을 통해 인증서를 넘겨야 함, MTLS)

curl https://aaa.bbb.com -v --resolve aaa.bbb.com:443:127.0.0.1 --cert /tmp/tls.crt --key /tmp/tls.key -k

* Added aaa.bbb.com:443:127.0.0.1 to DNS cache

* Hostname aaa.bbb.com was found in DNS cache

*   Trying 127.0.0.1:443...

* Connected to aaa.bbb.com (127.0.0.1) port 443

* ALPN: curl offers h2,http/1.1

* (304) (OUT), TLS handshake, Client hello (1):

* (304) (IN), TLS handshake, Server hello (2):

* (304) (IN), TLS handshake, Unknown (8):

* (304) (IN), TLS handshake, Request CERT (13):

* (304) (IN), TLS handshake, Certificate (11):

* (304) (IN), TLS handshake, CERT verify (15):

* (304) (IN), TLS handshake, Finished (20):

* (304) (OUT), TLS handshake, Certificate (11):

* (304) (OUT), TLS handshake, CERT verify (15):

* (304) (OUT), TLS handshake, Finished (20):

* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256

* ALPN: server did not agree on a protocol. Uses default.

* Server certificate:

*  subject: C=KR; ST=Seoul; L=Jung-gu; O=SHINSEGAE DF Inc.; CN=*.bbb.com

*  start date: Dec 13 00:00:00 2023 GMT

*  expire date: Jan  3 23:59:59 2025 GMT

*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=Thawte RSA CA 2018

*  SSL certificate verify ok.

* using HTTP/1.x

> GET / HTTP/1.1

> Host: aaa.bbb.com

> User-Agent: curl/8.4.0

> Accept: */*

>

< HTTP/1.1 400 Bad Request

< Connection: Close

< Transfer-Encoding: chunked

< Set-Cookie: JSESSIONID=UrMCYaU56vL7AKPwYnlPDPJ3MkXDd33v1d1RzGSxfSpFRN5WnthkERS5WPPQXPrl.amV1c19kb21haW4vZGV2X29wZW5BcGlfMw==; Path=/; HttpOnly

< cache-control: no-store

< pragma: no-cache

< Date: Mon, 05 Feb 2024 05:32:12 GMT

< Content-Type: text/html;charset=UTF-8

<

* Closing connection

02 request

 

400코드는 AP 로직에 의해 발생하는 것으로 정상 호출이다.

VerifyClient 값이 2 인 경우 TLS 호출은 Error가 발생 한다.

 

인증서를 태우지 않은 경우(TLS 통신 시도)

curl https://aaa.bbb.com -v --resolve aaa.bbb.com:443:127.0.0.1 -k

* Added aaa.bbb.com:443:127.0.0.1 to DNS cache

* Hostname aaa.bbb.com was found in DNS cache

*   Trying 127.0.0.1:443...

* Connected to aaa.bbb.com (127.0.0.1) port 443

* ALPN: curl offers h2,http/1.1

* (304) (OUT), TLS handshake, Client hello (1):

* (304) (IN), TLS handshake, Server hello (2):

* (304) (IN), TLS handshake, Unknown (8):

* (304) (IN), TLS handshake, Request CERT (13):

* (304) (IN), TLS handshake, Certificate (11):

* (304) (IN), TLS handshake, CERT verify (15):

* (304) (IN), TLS handshake, Finished (20):

* (304) (OUT), TLS handshake, Certificate (11):

* (304) (OUT), TLS handshake, Finished (20):

* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256

* ALPN: server did not agree on a protocol. Uses default.

* Server certificate:

*  subject: C=KR; ST=Seoul; L=Jung-gu; O=SHINSEGAE DF Inc.; CN=*.bbb.com

*  start date: Dec 13 00:00:00 2023 GMT

*  expire date: Jan  3 23:59:59 2025 GMT

*  issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=Thawte RSA CA 2018

*  SSL certificate verify ok.

* using HTTP/1.x

> GET / HTTP/1.1

> Host: aaa.bbb.com

> User-Agent: curl/8.4.0

> Accept: */*

>

* LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0

* Closing connection

curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0

 

* 참고 사항

- 호출 시 /etc/ssl/cert.pem 파일을 OS 에서 기본적으로 보는 것으로 확인되어 해당 경로에 파일을 생성해줘야 한다. (ROOT 계정 필요)

/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem 파일을 복사하여 사용

curl https://aaa.bbb.com -v --resolve aaa.bbb.com:443:127.0.0.1 --cert toss.pem --key toss.key -k

* Added aaa.bbb.com:443:127.0.0.1 to DNS cache

* Hostname aaa.bbb.com was found in DNS cache

*   Trying 127.0.0.1:443...

* Connected to aaa.bbb.com (127.0.0.1) port 443 (#0)

* ALPN, offering h2

* ALPN, offering http/1.1

* successfully set certificate verify locations:

 CAfile: /etc/ssl/cert.pem

*  CApath: none