openssl 명령은 호스트 이름 대신 IP로 NGINX를 쿼리합니다.

openssl 명령은 호스트 이름 대신 IP로 NGINX를 쿼리합니다.

이건 제가 이해하기 힘든 상황이에요. 아래와 같이 nginx에 대해 두 개의 호스트 블록을 설정했습니다.

server {
    server_name _;
    listen *:443 default_server deferred;
    return 444;
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.ca;

}

All-inclusive에는 자체 생성된 SSL 인증서가 있고 내 애플리케이션의 블록에는 유효한 SSL 인증서가 있습니다. 이 설정은 웹 브라우저에 적용됩니다. 웹 브라우저가 액세스 https://www.example.com하면 내 애플리케이션에 액세스하지만 액세스하면 htpps://123.123.123.123아무것도 반환하지 않습니다. 그런데 지금 나는 매우 이상한 상황에 직면해 있습니다. (스크립트에서) 실패한 도메인 요청을 받아서 디버깅하려고 합니다. 먼저 URL을 컬링해 보았습니다.

$ curl https://www.example.ca
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

브라우저 모두 인증서가 작동 중임을 표시하고 www.ssllabs.com이 작동 중임을 표시하기 때문에 이것이 이상하다고 생각합니다. 다음으로 시도한 것은 명령줄에서 SSL 인증서를 보는 것이었습니다.

echo | openssl s_client -showcerts -connect www.example.ca:443

이 명령은 실제로 해당 블록에 대한 SSL 인증서 대신 모든 서버 차단을 표시합니다 example.ca. 두 번째 nginx 블록에 IP 주소를 추가하면 가 표시됩니다 example.ca. 이제 openssl과 컬이 잘못된 인증서를 받고 있기 때문에 잘못된 SSL 인증서를 받고 있다는 것을 알 수 있지만 그 이유는 무엇입니까?

나는 openssl에 대해 잘 모르지만 openssl/curl이 호스트 이름을 IP 주소로 잘못 변환하거나 올바른 헤더를 추가하는 것을 잊었다는 것뿐입니다. 이것은 매우 이상합니다. 누구든지 더 자세히 알고 계시다면 감사하겠습니다.

답변1

여러 인증서(및 키)가 있는 nginx와 같은 가상 호스트 서버는 SNI(서버 이름 표시) 확장을 사용하여 올바른(가상 호스트 및) 인증서를 선택하지만SNI는 기본적으로 openssl s_client전송되지 않습니다.이제 기본 인증서가 생겼습니다. -servername $hostname매뉴얼 페이지(바로 다음 -connect)에 설명된 대로 추가하세요. 다른 여러 스택에 이 섹션의 중복 항목이 많이 있지만 여기서는 찾을 수 없습니다. (업데이트: 2018년 OpenSSL 1.1.1은 이 문제를 해결합니다. 이제 지정하지 않는 한 SNI가 기본값입니다 -noservername.)

OTOH curlSNI는 매우 오래된 버전의 컬 자체나 컬에서 사용하는 미들웨어(예:아니요항상 OpenSSL을 사용하십시오 curl -V. 추가하여 -v수행 중인 작업과 가져오는 작업에 대한 자세한 내용을 확인하고, 충분하지 않은 경우 tcpdump/Wireshark/etc를 사용하여 회선 추적을 가져옵니다.

관련 정보