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 연결을 허용하려면, 다음과 같은 방법들을 사용할 수 있다.
- OpenSSL 3.0 이상 버전을 사용한다.
 - TLS 1.3 으로 올리면, 안전한 해시 함수를 사용하면 된다. TLS 1.3 을 사용해야 하는 이유 (CloudFlare)
 - Node.js 의 Http Agent 의 secureOptions 에 옵션을 부여한다.
 
  // 예시
  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,
      }),
    }),
  }
- node 로 프로세스를 돌릴 경우에는, 
--openssl-legacy-provider옵션을 통해 실행하면, 안전하지 않은 알고리즘을 사용할 수 있다. 관련 공식 문서 - 머신에 OpenSSL 설정 파일을 직접 설정한다.
 
-- 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_경로}
            
            이것도 읽어보세요