programing

Ruby가 SSL 인증서를 확인할 수없는 이유는 무엇입니까?

goodcopy 2021. 1. 18. 22:03
반응형

Ruby가 SSL 인증서를 확인할 수없는 이유는 무엇입니까?


XMLRPC :: Client 라이브러리를 사용하여 원격 API와 상호 작용하는 것은 이번이 처음이며이 오류가 계속 발생합니다.

warning: peer certificate won't be verified in this SSL session

주변을 검색하다가 그 오류를 경험 한 많은 사람들을 찾았습니다. 일반적으로 자체 서명 된 인증서가 있고 그냥 사라지기를 원하므로 XMLRPC :: Client가 http 세션을 여는 방식으로 원숭이 패치와 같은 더러운 작업을 수행합니다.

나는 처음에 이것이 단순히 인증서가 유효한지 여부를 신경 쓰지 않는 클라이언트라고 생각했기 때문에 검색을 계속 하고이 gem을 발견했습니다 . 모든 SSL 인증서를 강제로 확인하고 불가능한 경우 하드 오류를 발생시킵니다. 이것이 바로 제가 원했던 것입니다. 나는 그것을 포함시키고 코드를 다시 실행했고 이제 이것을 얻었습니다.

OpenSSL:SSL::SSLError:
  SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B:
  certificate verify failed

물론이야! 인증서가 잘못되었습니다! 그러나 나는 openssl의 내장 s_client를 다음과 같이 확인하기 위해 두 번 확인합니다.

openssl s_client -connect sub.example.com:443

그리고 나는 무엇을 얻습니까?

CONNECTED(00000003)
---
Certificate chain
<snip>
Verify return code: 0 (ok)

이제 우리는 내 질문에 도달합니다. OpenSSL (명령 줄 버전)은 인증서가 양호하다고 말합니다. OpenSSL (Ruby 라이브러리)은 동의하지 않습니다. 내 웹 브라우저는 모두 인증서가 좋다고 말합니다.

유용 할 수있는 몇 가지 추가 세부 정보입니다. 인증서는 와일드 카드이지만 도메인에 유효합니다. openssl s_client는 Ruby 코드와 별도로 동일한 시스템에서 실행되었습니다. 이것은 RVM과 함께 설치된 Ruby 1.8.7 p357입니다.

Ruby는 호스트 OS에서 제공하는 CA 번들이 아닌 다른 것을 사용합니까? Ruby에게 특정 CA 번들 또는 시스템 번들을 사용하도록 지시하는 방법이 있습니까?


Ruby가 OpenSSL과 동일한 방식으로 작동하도록하는 방법에만 관심이 s_client있거나 브라우저가 수행 하는 방식에 관심이 있다면 맨 마지막 섹션으로 건너 뛸 수 있습니다. 다음 내용에서 세부 사항을 다룰 것입니다.

기본적으로 OpenSSL::X509::Store연결에 사용되는은 신뢰할 수있는 인증서를 전혀 사용하지 않습니다. 응용 프로그램 도메인에 대한 지식을 기반으로 일반적으로 응용 프로그램 X509::Store과 관련된 신뢰할 수있는 인증서로의 인스턴스 를 제공합니다. 이에 대한 몇 가지 옵션이 있습니다.

  • Store # add_file은 PEM / DER 인코딩 인증서에 대한 경로를 사용합니다.
  • Store # add_cert는 X509 :: Certificate의 인스턴스를 사용합니다.
  • Store # add_path는 신뢰할 수있는 인증서를 찾을 수있는 디렉토리 경로를 사용합니다.

"브라우저"접근 방식

이는 브라우저, Java (cacerts) 또는 신뢰할 수있는 인증서의 자체 내부 저장소가있는 Windows와는 대조적입니다. 이 소프트웨어에는 소프트웨어 공급 업체의 의견에 따라 "양호"한 것으로 간주되는 신뢰할 수있는 인증서 집합이 미리 설치되어 있습니다. 일반적으로 이것은 나쁜 생각은 아니지만 실제로 이러한 세트를 살펴보면 곧 너무 많은 인증서가 있음을 알게 될 것입니다. 개인은 이러한 모든 인증서를 맹목적으로 신뢰해야하는지 여부를 알 수 없습니다.

Ruby 접근 방식

반면에 일반적인 Ruby 애플리케이션의 요구 사항은 브라우저의 요구 사항과 많이 다릅니다. 브라우저는 TLS 인증서와 함께 제공되고 https를 통해 제공되는 "합법적 인"웹 사이트로 이동할 수 있어야합니다. 그러나 일반적인 Ruby 애플리케이션에서는 TLS를 사용하거나 인증서 유효성 검사가 필요한 몇 가지 서비스 만 처리하면됩니다.

그리고 Ruby 접근 방식의 이점이 있습니다. 더 많은 수동 작업이 필요하지만 주어진 애플리케이션 컨텍스트에서 신뢰해야하는 인증서를 정확하게 신뢰하는 맞춤형 솔루션을 얻게됩니다. 이것은 지루하지만 공격 표면이 훨씬 적기 때문에 보안이 훨씬 더 높습니다. 최근 이벤트를 살펴보십시오. DigiNotar 또는 기타 손상된 루트를 신뢰 세트에 포함 할 필요가 없었다면 그러한 위반이 귀하에게 영향을 미칠 수있는 방법은 없습니다.

그러나 이것의 단점은 이미 알고 있듯이 기본적으로 신뢰할 수있는 인증서를 적극적으로 추가하지 않으면 OpenSSL 확장이 피어 인증서의 유효성을 전혀 검사 할 수 없다는 것 입니다. 작업을 수행하려면 구성을 수동으로 설정해야합니다.

이러한 불편 함으로 인해이를 우회하기위한 모호한 조치가 많이 발생했으며, 최악의 상황은 전 세계적으로 설정되었습니다 OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE. 이러지 마세요. 우리는 해킹이 발생하면 응용 프로그램이 무작위로 충돌하도록하는 코드를 추가하는 것에 대한 농담도했습니다. :)

수동 신뢰 설정이 너무 복잡해 보인다면 이제 OpenSSL 확장이 .NET과 같은 OpenSSL CLI 명령과 똑같이 작동하도록하는 쉬운 대안을 제공하겠습니다 s_client.

s_client가 인증서를 확인할 수있는 이유

OpenSSL은 브라우저와 Windows에 유사한 접근 방식을 사용합니다. 일반 설치에서는 신뢰할 수있는 인증서 번들 (예 :)이 하드 디스크 어딘가에 배치 /etc/ssl/certs/ca-bundle.crt되며 이는 신뢰할 수있는 기본 인증서 집합으로 사용됩니다. 이것이 s_client피어 인증서를 확인해야 할 때 보이는 이며 실험이 성공한 이유입니다.

Ruby가 s_client처럼 작동하도록 만들기

Ruby로 인증서의 유효성을 검사 할 때 동일한 편안함을 유지하려면을 호출하여 시스템에서 사용 가능한 경우 신뢰할 수있는 인증서의 OpenSSL 번들을 사용하도록 지시 할 수 있습니다 OpenSSL::X509::Store#set_default_paths. 추가 정보는 여기 에서 찾을 수 있습니다 . 이것을와 함께 사용하려면 사용 XMLRPC::Client하는 set_default_paths호출이 있는지 확인 X509::Store하십시오.


ca-certificates 파일이있는 경우 다음을 수행하십시오.

http.ca_file = <YOUR CA-CERT FILE PATH>
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.verify_depth = 5

참조 URL : https://stackoverflow.com/questions/9199660/why-is-ruby-unable-to-verify-an-ssl-certificate

반응형