2014-04-24 4 views
15

클라이언트 응용 프로그램이 플라스크를 사용하여 SSL 서버 응용 프로그램의 ID를 확인한 곳에서 이미 SSL 통신을 구현했습니다. 이제 SSL 서버 응용 프로그램이 SSL 클라이언트 응용 프로그램의 ID를 확인하기를 원합니다. 플라스크로 가능합니까? 클라이언트 인증서를 확인하려면 어떻게합니까? 첫 핸드 셰이크 클라이언트가 CSR을 보내는 동안 응답으로 자체 서명 된 CA 인증서로 서명 된 인증서를 다시 보내고 있습니다.플라스크 용 양방향 SSL 인증

하지만 다음 통신이 진행되는 동안 서버에서 클라이언트를 확인하는 방법은 아직 명확하지 않습니다. 인증서 확인을위한 콜백이 있습니까? Google groups에 대한 링크는 Flask에서 ssl 인증을 사용할 수 없다고 말합니다. 이 일을하기 위해서 아파치 웹 서버 ngnix를 사용할 필요가 있습니다. 이것이 클라이언트를 인증하는 유일한 방법입니까?

인증서를 기반으로 각 클라이언트를 식별해야하는 또 다른 사항이 하나 있습니다. 플라스크로도 가능합니다. 내가 @Emanuel 어이의 의견을주의 할 시작하기 전에 나는 아직 많이 익숙

+0

왜 다른 방법으로 인증해야합니까? 클라이언트가 연결을 청취하지 않는 한 당신도 필요하지 않아야합니다. –

+0

@ sshanshank124 클라이언트 인증서를 기반으로 각 클라이언트를 인증하고 그에 따라 요청을 처리하고 싶습니다. – nishi

+2

TLS/SSL은 웹 서버의 일부 기능입니다. 귀하의 질문에 귀하의 애플 리케이션을 실행하기 위해 프로덕션 서버 대신 Flask의 개발 서버를 사용하고 있다는 것을 의미합니다. 이것은 아마도 나쁜 생각 일 것입니다. http://flask.pocoo.org/docs/0.10/deploying/ –

답변

6

면책 조항

을 플라스크에 아닙니다으로

제 질문은 순진 수 있습니다. 이것이 프로덕션 또는 개발 서버에서 먼저 수행되고 있는지 고려하고 싶을 것입니다. 예를 들어; Apache WebServer를 사용하는 경우 Apache에서 HTTPS 구성 요소를 수행 할 수 있습니다. 다르게 수행 할 수있는 유일한 방법은 인증서 세부 정보를 옵션으로 전달하므로 서버 앱은 앱 자체의 일련 번호를 확인합니다.

그것은

가능하지만 좋은 프로그래밍 연습으로 간주되지 않습니다 수있는 방법입니다. 불행히도 flask.request에서 액세스 할 수 없으며 Flask 패키지에서는 불가능합니다. 그러나 Flask는 Werkzeug를 사용하며 werkzeug.serving 패키지를 패치하여 기본 Flask 코드를 작성할 수 있습니다. 나중에 Flask 나 Werkzeug를 업데이트하고 패치가 중단되어 다시 팩토링되어야하기 때문에 권장하지 않습니다. 즉 0.9 내지 1.0이다.

웹 서버를 사용하지 않고도 해결책을 제공합니다. 하지만 웹 서버/환경 변수 콤보를 권하고 싶습니다. 그것은 깨끗하고 비교적 좋은 연습입니다.

구현이 쉬운지를 알기 위해 테스트를 해봤습니다. 이 방법이 최신 개발 코드베이스 'Werkzeug-0.10_devdev_20141223-py2.7'을 사용하여 작동하는지 확인할 수있었습니다.

아마도 각 인증서에서 발견되는 일련 번호 (시드 번호)를 확인하고 싶을 것입니다. 아시는 바와 같이 일련 번호는 각 인증서마다 고유하며 서버 쪽에서 인증서 생성 과정에서 결정됩니다. 나중에 클라이언트 인증서 일련 번호를 확인하기 위해 클라이언트 기록 및 인증서 정보 (필요한 경우)와 함께 저장하는 것이 좋습니다. 주 : 10 진수와 10 진수 사이의 변경이 필요할 수 있습니다.

는 WERKZEUG 내가 wrap_socket()werkzeug.serving.BaseWSGIServer.__init__ 통화에 다음과 같은 옵션을 추가하는 것이 었습니다 무슨 짓을

을 dev_2014122.

다음을 사용하십시오. server_side=True, ca_certs= '/etc/apache2/ssl/ca.pem', cert_reqs=ssl.CERT_REQUIRED

  • ca_certs : 사용 문제는이가)
  • ssl.CERT_REQUIRED을 클라이언트 인증서를 생성하는 데 사용되는 CA의 인증서입니다에 대해 확인 : ca_certs에 대한 클라이언트 인증서 확인을 요구

참고 : 클라이언트 인증서가 초기 확인을 통과하지 못하면 클라이언트 인증서를 가져올 수 없습니다. 그것은 None이 될 것입니다.

그런 다음 내 플라스크 테스트 클래스에 나는

def verify_request(self, request, client_address): 

cert = request.getpeercert(True) 
raw = decoder.decode(cert)[0] 
print "Serial Number of your certificate is: % " % str(raw[0][1]) 
# todo: do checks & if serial no is ok then return true 
return True 

werkzeug.serving.BaseWSGIServer.verify_request = verify_request 

이 그것을 가능하지만 당신은 아마 BaseWSGIServer 찾을 상속하는 HTTP 서버 클래스의 요청 처리기를 조사 할 것입니다 입증 verify_request 패치 콜백 또는 오버라이드를 수행하는 더 좋은 방법입니다.

WERKZEUG의 0.9.X

당신은 내가 가져 오기 from OpenSSL import SSL를 사용하고 있으리라 믿고있어 WERKZEUG 0.9.X를 사용하는 경우. 코드 스 니펫 here을 참조하십시오. 나는 이것을 시험하지 않았다.

이 버전에 관심이있는 전화 중 일부는 다음과 같습니다. - Context.set_verify(mode, callback) - Connection.get_peer_certificate()

대한 설명

내가 이해하지 못하는 것은 최초의 핸드 셰이크 중에 CSR을 전송하는 참조입니다. 이것이 클라이언트 인증서 생성 프로세스 인 경우 시스템 및 환경의 컨텍스트에서이를 수행하는 방법을 다시 생각해 볼 수 있습니다. 좀 더 자세한 정보가 있으면 더 자세히 설명 할 수 있습니다.

또한 SSL/TLS 컨텍스트에서 '핸드 셰이크'는 일반적으로 기존 인증서를 사용하여 보안 연결을 처음으로 만드는 작업을 나타냅니다. 느슨하게 말해서 핸드 셰이 킹 직후 연결이 설정됩니다.

+0

Connection 객체는 어떻게 얻을 수 있습니까? 플라스크 요청 개체에서 액세스 할 수 있습니까? –

+0

개념 증명을 위해 원숭이 패치를 테스트하고 답변을 편집했습니다. 좋은 연습은 아니지만 필요한 경우 가능하다는 것을 보여줍니다. SSL 패키지와의 Werkzeug 0.9 및 1.0 차이점에 유의하십시오. – Ross

+0

답변 주셔서 감사합니다. 나는 이것을 재검토하고 이것이 내 경우에 효과가 있는지 확인한다. – nishi