2016-07-01 2 views
0

a WebSocket client (안드로이드에서)을 사용하여 보안 wss를 통해 NGINX 프록시에 연결하려고합니다.javax.net.ssl.SSLHandshakeException 디버깅 : java.security.cert.CertPathValidatorException : 인증 경로에 대한 신뢰 앵커를 찾을 수 없음

두 대의 서버가 있습니다. 하나는 인트라넷에 있고 다른 하나는 AWS입니다. AWS에서 서버에 접속을 할 때

로컬 서버에 연결을 시도, 연결이 내가 AWS에 Nginx의 인스턴스가되지 않았기 때문에 예상 할 수있는 com.neovisionaries.ws.client.OpeningHandshakeException: The status code of the opening handshake response is not '101 Switching Protocols'. The status line is: HTTP/1.1 404 Not Found을 얻을 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

실패 프로토콜을 전환하고 업스트림 websocket 서버에 연결하도록 구성됩니다. 이것은 로컬 서버에서 개발 중입니다. 그러나 이것은 TLS/SSL이 AWS에서 작동하고 있다는 표시입니다.

또한 wss://echo.websocket.org에 대한 연결이 성공하고 메시지가 다시 표시됩니다.

이제는 이상한 점이 있습니다. : 도커 컨테이너 내에서 실행되는 AWS의 NGINX 인스턴스는 로컬 시스템과 동일한 코드베이스를 사용합니다. 둘 다 도커 컨테이너에서 실행되는 NGINX이며, 볼륨은 매우 유사한 구성 파일과 동일한 방식으로 탑재됩니다. 유일한 차이점은 도메인 이름과 관련 SSL 인증서입니다.

이들은 Comodo (긍정적 인 SSL)의 DV 인증서입니다. 또한 LetsEncrypt 인증서를 동일한 결과로 시도했습니다.

두 개의 컨테이너가 너무 다르게 행동 이유를 이해하지 않고, 내가 고정 표시기 서비스 (모두 우분투 14.04)를 호스팅하는 서버를 비난 할 이유를 찾을 수 없습니다

그래서 해부 꿔 인증서 (및 해당 체인)를 Android 클라이언트 애플리케이션에 추가합니다.

인증서 체인의 내용을 인쇄하려면 어떻게해야합니까?

Chrome 브라우저 JavaScript는 Android 서버뿐만 아니라 PC에서도 로컬 서버에 연결할 수 있습니다.

~~~~ 업데이트 ~~~~ 내가

좋아 별도의 질문으로 분할되므로, 아래의 물건에 대답하지 마십시오, 내가 @CommonsWare에서 도움을 을 진행 . 여기 흥미로운 새로운 질문이 있습니다.

인트라넷의 서버는 자체 서명 된 인증서를 catchall https 응답으로 호스트합니다. 인터넷의 누군가가 https://<IP-INTRANET-GATEWAY>을 통해 해당 인트라넷의 공용 IP 주소를 방문하면 더미 인증서가 제공된다는 논리가 뒤 따른다. 그 이유는 인트라넷 인증서 (https://intranet.example.com)를 반환해서는 안됩니다.다른 인증서를

여러 도메인 이름은 IP 주소 https://intranet.example.com, https://testing.intranet.example.com를 가리, 그래서 거기에 여러 SSL 인증서는 Nginx에에서

가 될 것이라고이 IP에 대한 봉사 :

server {  
    listen 443; 
    server_name _; 
    ssl on; 
    ssl_certificate  /etc/nginx/self-signed-dummy.pem; 
    ssl_certificate_key /etc/nginx/self-signed-dummy.key; 
    location/{ 
    return 404; 
    } 
} 

server {  
    listen 443; 
    server_name intranet.example.com; 
    ssl on; 
    ssl_certificate  /etc/nginx/intranet.example.com.pem; 
    ssl_certificate_key /etc/nginx/intranet.example.com.key; 
    location/{ 
    ... 
    } 
} 

server {  
    listen 443; 
    server_name testing.intranet.example.com; 
    ssl on; 
    ssl_certificate  /etc/nginx/testing.intranet.example.com.pem; 
    ssl_certificate_key /etc/nginx/testing.intranet.example.com.key; 
    location/{ 
    ... 
    } 
} 

이 차이입니다 자체 서명 된 인증서가없는 AWS의 서버로 전송합니다.

클라이언트가 더미 인증서를 제공받을 수있는 이유는 무엇입니까?

또한 AWS 서버가 반환 한 인증서 (+ 체인)를 분석하기 위해 인증서를 예외없이 덤프하는 방법은 무엇입니까?

https가있는 일반 HttpURLConnection을 사용하면 문제없이 작동합니다.

+2

''SSLHandshakeException'의'getCause()'는 아마도'CertPathValidatorException'을 리턴합니다. 이 메소드는 체인을 나타내는'getCertificates()'메소드를 가지는'CertPath'를 리턴하는'getCertPath()'메소드를 가지고 있습니다. – CommonsWare

+0

예, 고마워요! "Internet Widgits Pty Ltd"와 나는 그것이 왜 도움이되는지 궁금해. 너 내가 도와 줬어. 대답을하면 받아 들일 것입니다. –

답변

2

getCause()SSLHandshakeException은 아마도 오류 텍스트를 받아 CertPathValidatorException을 반환합니다. 그것은 getCertPath() 메서드를 가지고 있으며, CertPath을 반환합니다.이 메서드는 체인을 나타내는 getCertificates() 메서드를가집니다. 필요한 경우 해당 인증서는 X509Certificate 개체로 전송 될 수 있어야하며 이는 인증서에 대한 다양한 세부 정보를 제공합니다.

"인터넷 Widgits Pty 주식 회사"와 그

모르겠어요 제공지고 있지만, 해당 문자열에 대한 인터넷 검색이 유망 소리를하지 않는 이유를 궁금하다.

+0

질문을 업데이트했습니다. 인트라넷상의 나의 NGINX 서버는 특정 도메인과 일치하지 않는 모든 기본 히트에 대해 더미 인증서를 제공합니다. 그 인증서입니다. –

+0

@DanielF : "클라이언트가 더미 인증서를 제공 할 수있는 이유는 무엇입니까?" - 서버가 WebSocket과 같은 일반 페이지를 제공하는 경우 일반적인 HTTPS 요청이 어떤 동작을하는지 확인하십시오 (예 : OkHttp3 또는 HttpURLConnection 사용). 성공하면 아마도 WebSocket 설치를 위해 다른 것을해야 할 것입니다. "어떻게하면 예외없이 인증서를 덤프 할 수 있습니까?"- 내가 아는 유일한 방법은 자신의 'X509TrustManager'를 구현하는 것입니다. 따라서 유효성 검사를 위해 인증서 체인을 얻을 수 있지만 고통 스럽습니다. – CommonsWare

+0

감사합니다. 방금 그 더미 인증서를 문제의 도메인 중 하나로 바꾸어 검사했습니다. 작동합니다. 분명히 이것은 일시적인 해결책이지만 좋은 출발점입니다. 질문을 새 것으로 분리하고 추천을 테스트합니다. X509TrustManager를 구현하는 데별로 신경 쓰지 않습니다. 변경 사항이 인증서에 적용될 때까지 몇 년 후 (예 : 몇 년 후)에 문제가 발생할 수 있습니다. 또한 WebViews는 이것에 아무런 문제가 없다는 것이 이상합니다. WebSocket 라이브러리의 구현 문제 일 수 있습니다. 다음은 https 권장 사항을 확인할 것입니다. –

관련 문제