Node18 과 OpenSSL, 그리고 Legacy SSL Algorithm

Node.js 환경에서 OpenSSL 보안 업데이트 이후 발생하는 SSL 알고리즘 관련 오류 해결 방법을 안내해 드립니다.

OpenSSL November Security Release (2022) 에 따라, Node.js 17 이상 버전은 기본적으로 OpenSSL 3.0.7 의 보안 규칙을 준수하는 SSL 알고리즘만을 허용한다. 그렇다면 OpenSSL 의 어떠한 문제로 인해 이러한 패치가 생겼을까 ? OpenSSL 보안이슈(SSL v3 취약점) 관련 패치에 관하여, OpenSSL Security Advisory [15 Oct 2014] 에 간략히 그 내용이 정리되어 있다.

상세한 Node.js 의 변경사항은 다음의 문서에서 확인해 볼 수 있다. 간단히 정리하자면, OpenSSL 3.0 이상 버전부터 취약하다고 판단되는 SSL 알고리즘을 사용하면, Node.js 는 에러를 발생시킨다. 소켓 연결시 Legacy Algorithm 을 통해 연결을 수립하려 하는 경우, 다음과 같은 에러가 발생한다.

write EPROTO...: SSL routines:final_renegotiate:unsafe legacy renegotiation disabled
...

OpenSSL 구버전, SSL 1.1 의 조합을 사용하면 위의 에러가 발생한다

Node.js 에서는 안전하지 않은 해시함수를 사용하려 하면, 해당 서버와 통신하지 않고 요청 자체를 보내지 않는다. 하지만 통신하고자 하는 서버의 SSL 알고리즘 관련 설정을 바꿀 수 없다면, Node.js 의 SSL 보안 관련 옵션을 변경해 주어야 한다.

 

Legacay Algorithm 을 사용한 SSL 연결을 허용하려면, 다음과 같은 방법들을 사용할 수 있다.

  // 예시
  const crypto = require('crypto')

  const options = {
    request: axios.create({
      // axios options
      httpsAgent: new https.Agent({
        // for self signed you could also add
        // rejectUnauthorized: false,

        // allow legacy server
        secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
      }),
    }),
  }
-- openssl.cnf 파일을 생성한다
nodejs_conf = openssl_init

[openssl_init]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
Options = UnsafeLegacyRenegotiation

...

-- 환경변수에 다음을 추가한다
export OPENSSL_CONF=${위에_추가한_openssl.cnf_경로}

이것도 읽어보세요