FAQ..

SSL, HTTP
그리고 Apache 각각이 요청(request) 처리하는 방식 간의 연관성으로 인하여 SSL 적용된 서버의 어떤 특정 보안 문제에 대한 해결 방법이 항상 명확하지는 않다. 장에서는 그러한 전형적인 상황에서 문제를 어떻게 해결할 것인가에 대하여 논의한다.

어떤 문제를 해결하는 가장 첫번째 방법은 일단 시도해 보는 것이긴 하지만 항상 이전에 내용을 이해하려고 노력해야 한다. 어떤 보안 솔루션의 사용에 있어서 제한(restriction) 연관성(coherence) 알지 못한 상태로 사용하는 것만큼 나쁜 것도 없다!

Cipher Suites and Enforced Strong Security

어떻게 하면 SSLv2만을 사용하는 서버를 생성할 있나? [L]

다음은 SSLv2 프로토콜과 cipher만을 사용하는 SSL 서버를 생성하는 방법이다:

httpd.conf

SSLProtocol -all +SSLv2

SSLCipherSuite SSLv2:+HIGH:+MEDIUM:+LOW:+EXP


어떻게
하면 강력한 암호화(strong encryption)만을 허용하는 SSL 서버를 생성할 있나? [L]

다음은 일곱 가지의 가장 강력한 암호화만을 허용하게 한다:

httpd.conf

SSLProtocol all

SSLCipherSuite HIGH:MEDIUM


어떻게
하면 SSL 서버로 하여금 강력한 암호화만을 허용하면서 수출용 브라우저로 하여금 강력한 암호화를 사용할 있게 업그레이드를 허용할 있을까? [L]

이러한 기능(facility) Server Gated Cryptography (SGC)라고 불려지며, mod_ssl 배포판의 README.GlobalID 문서에서 자세한 내용을 있다. 간단히 말하자면 다음과 같다:

Verisign 같은 수출용 브라우저에서 강력한 암호화를 가능하게 해주는 Verisign 같은 CA 증명서(certificate) 서명된 Global ID 서버 증명서를 서버가 가지고 있다. 브라우저는 수출용 암호(export cipher) 가지고 서버에 접속하면 서버는 자신의 Global ID 증명서를 보내고 브라우저는 증명서를 확인(verify) 어떠한 HTTP 통신이 일어나기 전에 cipher suite 갱신한다. 여기서 생기는 질문은 우리가 어떻게 갱신을 허용하여 strong encryption 강제(enforce) 있는가이다. 다르게 말하면 브라우저가 처음부터 strong encryption 가지고 접속하거나 혹은 strong encryption으로 갱신하여야 하는데 수출용 브라우저는 그러한 수출용 cipher 허용되지 않는다는 것이다.

다음에 트릭이 있다:

httpd.conf

# allow all ciphers for the initial handshake,

# so export browsers can upgrade via SGC facility

SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

<Directory /usr/local/apache/htdocs>

# but finally deny all browsers which haven't upgraded

SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128

</Directory>


어떻게
하면 SSL 서버로 하여금 일반적인 모든 형식의 cipher 허용하면서 특정 URL로의 접근에 대해서만 strong cipher 요구하게 있나? [L]

분명히 strong variant 대한 cipher들을 제한하는 server-wide SSLCipherSuite 사용할 없다. 하지만 mod_ssl per-directory context에서의 cipher suite 재설정을 허용하며 자동으로 새로운 설정을 만족하기 위한 SSL 파라미터들의 재협상(renegotiation) 강요하게 해준다. 따라서 다음과 같이 설정해 주면 된다:

httpd.conf

# be liberal in general

SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

<Location /strong/area>

# but https://hostname/string/area/ and below requires strong ciphers

SSLCipherSuite HIGH:MEDIUM

</Location>

 

Client Authentication and Access Control

나의 모든 클라이언트들을 알고 있는 경우 어떻게 하면 증명서에 기반하여 클라이언트들을 인증할 있나? (How can I authenticate clients based on certificates when I know all my clients?) [L]

인트라넷과 같이 공동체 내의 모든 사용자를 알고 있는 경우 plain certificate authentication 사용할 있다. 해야 일은 단지 클라이언트들의 증명서를 자신의 CA 증명서인 ca.crt 서명한 증명서를 가지고서 클라이언트를 확인(verify)하는 뿐이다.

httpd.conf

# require a client certificate which has to be directly

# signed by our CA certificate in ca.crt

SSLVerifyClient require

SSLVerifyDepth 1

SSLCACertificateFile conf/ssl.crt/ca.crt


특정
URL 대해서만 증명서를 기반으로 클라이언트를 인증하면서 서버의 다른 부분들에 대해서는 임의의 클라이언트들의 접근을 허용하려면 어떻게 하나? (How can I authenticate my clients for a particular URL based on certificates but still allow arbitrary clients to access the remaining parts of the server?) [L]

이를 위해서는 mod_ssl 제공하는 디렉토리 기반 재설정 기능(per-directory reconfiguration feature) 사용한다:

httpd.conf

SSLVerifyClient none

SSLCACertificateFile conf/ssl.crt/ca.crt

<Location /secure/area>

SSLVerifyClient require

SSLVerifyDepth 1

</Location>


몇몇
URL들에 대해서는 증명서에 기반하여 특정 클라이언트들만을 인증하면서 서버의 나머지 부분들에 대해서는 임의의 클라이언트들로부터의 접근을 허용하고자 하는 경우 어떻게 해야 하나? (How can I authenticate only particular clients for a some URLs based on certificates but still allow arbitrary clients to access the remaining parts of the server?) [L]

중요한 것은 클라이언트 증명서의 다양한 구성요소(ingredient)들을 점검하는 것이다. 보통 이것은 Subject DN(Distinguished Name) 전체 혹은 일부분을 점검하는 것을 의미하며, 이를 위해서 두가지 방법, mod_auth 기반 방법과 SSLRequire 존재한다: 첫번' 방법은 클라이언트가 전체적으로 다른 형식, DN organisation 같은 공통 필드를 가지지 않는 경우 유용하다. 경우 모든 클라이언트들에 대한 패스워드 데이터베이스를 구축하여야 한다. 두번째 방법은 클라이언트들이 DN으로 인코딩되어지는 공통 구조(common hierarchy) 부분인 경우 유용하며, 경우 match 쉽다.

첫번째 방법:

/usr/local/apache/conf/httpd.conf

SSLVerifyClient none

<Directory /usr/local/apache/htdocs/secure/area>

SSLVerifyClient require

SSLVerifyDepth 5

SSLCACertificateFile conf/ssl.crt/ca.crt

SSLCACertificatePath conf/ssl.crt

SSLOptions +FakeBasicAuth

SSLRequireSSL

AuthType Basic

AuthUserFile /usr/local/apache/conf/httpd.passwd

require valid-user

</Directory>


/usr/local/apache/conf/httpd.passwd

/C=DE/L=Munich/O=Snake Oild, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA

/C=US/L=S.F./O=Snake Oild, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA

/C=US/L=L.A./O=Snake Oild, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA

 
The second method:

SSLVerifyClient none

<Directory /usr/local/apache/htdocs/secure/area>

SSLVerifyClient require

SSLVerifyDepth 5

SSLCACertificateFile conf/ssl.crt/ca.crt

SSLCACertificatePath conf/ssl.crt

SSLOptions +FakeBasicAuth

SSLRequireSSL

SSLRequire %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." and \
%{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}

</Directory>




Posted by Golmong
: