안전한 웹서버 구축하기

현재 사용하고 있는 기술은 SSL/TLS 입니다. SSL/TLS 군에는 5개의 프로토콜이 있습니다: SSLv2, SSLv3, TLSv1.0, TLSv1.1, TLSv1.2. 아직 알려진 취약점이 없는 TLSv1.2와 TLSv1.1 사용을 권장하고 있습니다. TLSv1.0도 여전히 대체로 안전하다고 알려져 있는 반면, SSLv2와 SSLv3 프로토콜은 사용하기에 취약하다고 합니다.

SSL/TLS 기술은 전적으로 공개키 암호화(PKI)에 의존하기 때문에 비밀키를 생성하는 방법부터 알아봅니다. RSA 비밀키와 CSR(Certificate Signing Request)를 생성하기 위해 openssl 툴을 사용합니다. 보안 수준은 사용된 비밀키와 해시함수의 강도에 의존합니다. 현재 권장되는 RSA 비밀키 크기는 2048비트이고 해시함수는 SHA2입니다. 그밖에도 다른 종류의 해시함수와 공개키 암호 방식이 있지만, 여기에서는 RSA와 SHA2만 다룹니다.

비밀키 생성

openssl genrsa -out private.key 2048

파일 형식은 아스키 텍스트인 PEM입니다. 비밀키 생성시 -des3와 같은 옵션으로 비밀키 사용시 비밀번호를 요구하게 할 수도 있습니다. 하지만 매번 입력해야하는 번거로움과 함께, 입력된 비밀번호를 프로세스 메모리에서 추출할 수도 있다는 점도 명심해야 합니다.

추가적으로 비밀키에서 공개키를 추출하는 과정과 알고리즘에 사용된 정보를 알아봅니다:

비밀키에서 공개키 추출

openssl rsa -pubout -in private.key -out public.key

비밀키 정보 출력

openssl rsa -text -in private.key

CSR은 인증기관에 서명을 요청하기 위해 제출해야 하는 양식입니다. 공개키와 더불어 추가적인 정보를 담고 있습니다. 물론 인증기관에 의뢰하지 않고 개인이 직접 서명할 수 있습니다. 다만, 웹 클라이언트들은 개인적으로 서명한 인증서를 신뢰할 수 없기 때문에 위협으로 분류합니다.

CSR을 생성할 때 Distinguised Name (DN)을 입력하게 됩니다. 입력해야 하는 관련 정보 중 Common Name (e.g., YOUR name) 부분이 가장 중요합니다. 적용될 웹사이트의 도메인 주소를 입력하는 부분입니다. 입력한 도메인의(예:viewy.org) 하위 도메인까지(sub.viewy.org) 확장 적용되지 않습니다. 여러 도메인을 하나의 인증서로 서명받는 것이 좋은 생각도 아닙니다. 비밀키에 대한 접근성이 커질수록 유출 확률이 높아지고, 한 번 유출되면 적용된 모든 사이트가 오염되기 때문입니다.

CSR 생성

openssl req -sha256 -new -key private.key -out server.csr

이제 생성된 CSR파일로 신뢰할 수 있는 인증기관에 서명을 받으면 됩니다. 서명받은 인증서에 인증 체인을Certificate chains 구성하는 것도 잊지 않도록 합니다.

웹서버에 인증서를 이용해 프로토콜을 적용하는 일만 남았습니다. nginx 용 예제는 다음 링크에서 찾을 수 있습니다: https://gist.github.com/plentz/6737338

추가적으로 인증기관이 아닌 개인적으로 서명하는 방법을 알아봅니다:

개인 서명된 인증서 생성

openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt

마지막으로 다음 사이트에서 서버의 보안 수준을 알아볼 수 있습니다(여러 자료와 정보를 얻을 수 있습니다: https://www.ssllabs.com


개인 웹서버를 구축하게 되어서 요약해보았는데, 사실 웹서버 구축보다는 인터넷 세대로서 기본적으로 알아야 할 보안상식에 대해 정리할 필요가 있지 않을까 싶어요. 반복되는 개인정보의 대량유출은 그 중요성에 대한 기관의 인식 부족뿐만 아니라, 당사자 개인에게 개인정보에 대한 감각이 부족하기 때문이기도 하니까요.