IIS 의 SSL은 안전하지 않다?

Windows 10 1607, 그것도 Server 2016 1607이라는 나름대로 최신1 버전을 사용중이면서 IIS 를 지난 게시물에서 세팅한 바 있습니다. 그러나 그런 과정을 거쳐서 Let’s encrypt를 설정했는데도 불구하고 뭐가 부족했는지 SSLLabs에서는 가차없는 점수를 주었네요. 무엇이 문제일까요?

RC4를 써서는 안 되는 이유

RC4 암호화는 1987년 설계된 스트림 암호입니다. 스트림 암호인 만큼 빠르게 적용할 수 있고, 그간 널리 쓰여온 바가 있지만 이제는 사용을 권하지 않는다고 합니다. 다양한 취약점이 발견되었으며, 암호의 복잡도가 충분히 높지 않아서 무력화되기 쉬우며, 이 취약점이 바로 무선랜 암호화인 WEP를 신용할 수 없게 하는 주요 원인이기도 합니다. 그래서 새로운 SSL 프로토콜에서는 도입되지도 않았으며, 그런 낡은 것을 IIS 는 여전히 지원한다는 점에서 HTTPS 보안에 대한 점수를 크게 감점하게 된 것입니다.

Cipher 선택에 따라 좌우되는 보안

SSL에 대한 그간의 글에서 언급하였던 보안 사이퍼(cipher)는 암호화 방법을 의미합니다. 서버가 암호화할 줄 알아야 하겠지만, 클라이언트도 복호화할 줄 알아야만 올바르게 정보를 전달할 수 있을 것입니다. Cipher는 암호화 알고리즘으로 정의되며, 그 종류는 무척 다양합니다. 개중에는 최신식 고급 보안을 가진 것도 있는가 하면, 옛날부터 쓰던 것이라 취약점이 알려질대로 알려진 낡은 것도 있습니다.

물론 가장 최신의 알고리즘을 쓰면 더욱 안전한 건 당연하겠지만, 모든 브라우저를 만족시킬 수 없기 때문에, 옛날 OS에서는 에러 메시지만을 보게 될 것입니다. 그런 점을 고려하여 호환성과 안전 두 가지의 균형점을 갖춰보고자 합니다. 즉, 이 글은 조금 더 실용적으로 포장된 기존의 글 재탕으로 보셔도 될지 모릅니다.

IIS 에서 Cipher 선택하기

[시작]→[실행]을 들어가서 ‘gpedit.msc’를 실행하면 그룹 정책이 뜹니다. 그룹 정책에서 다음 경로로 들어갑니다.

컴퓨터 관리\관리 템플릿\네트워크\SSL 구성 설정

SSL Cipher Suite Order 항목을 눌러서 ‘사용’을 누르면 아래 입력칸이 한 줄로 있습니다. 한 번 기본값 전체를 살펴보겠습니다.

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5,
TLS_RSA_WITH_NULL_SHA256,
TLS_RSA_WITH_NULL_SHA,
TLS_PSK_WITH_AES_256_GCM_SHA384,
TLS_PSK_WITH_AES_128_GCM_SHA256,
TLS_PSK_WITH_AES_256_CBC_SHA384,
TLS_PSK_WITH_AES_128_CBC_SHA256,
TLS_PSK_WITH_NULL_SHA384,
TLS_PSK_WITH_NULL_SHA256

RSA + PSK WITH NULL 있는 거 실화냐 / ECDSA랑 AES 붙을 때 자신감 있는 NULL

후순위이긴 하나 RC4는 물론 별다른 암호화가 없는 것으로 보이는 것도 보입니다. 이것이 보안의 허점을 노출하는 것으로 봐도 무방하겠습니다.

Windows에서 제안하는 변경점

Windows에서도 관련된 정보를 공개하고 있습니다. 여기 서술대로라면, 일단 크게 봐서 두 가지에 주의해야 합니다.

  • 일부 cipher는 HTTP/2 버전 연결을 미지원하므로 통신에 실패합니다. HTTP/1.1보다 HTTP/2가 지원하는 브라우저에선 서버 연결 속도에서도 압도적으로 낫기에 충분히 고려해봐야 합니다.2
  • SCH_USE_STRONG_CRYPTO시 Yes 되어 있는 것은 안전한 것으로 보고 있습니다. 그러나 여기서 Yes여도 SSLLabs의 깐깐한 판단으로는 WEAK에 속할 수 있습니다.

여기서 SCH_USE_STRONG_CRYPTO가 Yes인 것만 골라서 넣어보겠습니다.

TLS_PSK_WITH_AES_256_GCM_SHA384,
TLS_PSK_WITH_AES_128_GCM_SHA256,
TLS_PSK_WITH_AES_256_CBC_SHA384,
TLS_PSK_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256

그리고 다시 SSLLabs 테스트를 받으니 여전히 WEAK 판정은 존재합니다. RC4를 없애니 랭크도 A로 올랐군요.

문제가 된 cipher를 추려내보겠습니다.

TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_3DES_EDE_CBC_SHA

해당 cipher를 제거하고 넣으면 되겠군요. 추가적으로 최신 브라우저의 우선순위에 맞게 순서를 재배열하였습니다.

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_PSK_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_128_GCM_SHA256
TLS_PSK_WITH_AES_256_CBC_SHA384
TLS_PSK_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256

HSTS 설정을 올바르게 하면 점수가 오를 것이다

이제 Cipher를 무결하게 만들고, 마지막 단계로 HSTS 설정을 하여 A+를 노려보겠습니다.

SSL이 강제될 사이트에서 HTTP Response Headers를 들어갑니다.

[Add…]를 눌러서 새로운 항목을 추가합니다.

다음과 같이 Strict-Transport-Security를 지정합니다. 이 값을 지정하고 헤더로 전송되면, 사용자 클라이언트 브라우저에선 향후 이 사이트에 대한 요청을 반드시 HTTPS로만 하게 되며 더욱 안전한 통신이 가능해집니다.

단, 추후 인증서를 해지하거나 만료되면 사이트에 아예 접속할 수 없을 수 있으니 이 설정에 유의하고 인증서가 없어지거나 만료되지 않도록 갱신 및 관리에 항상 신경써야 합니다.

Name: Strict-Transport-Security
Value: max-age=31536000

SSLLabs는 최소한 120일(10368000초) 이상 주어야 한다고 하며, 이상적인 값은 1년(31536000초)라고 합니다.

또한 평문 전송시 이러한 값을 전송해서는 안 되므로, redirect 전용 사이트 하나를 만들고 SSL 전용 사이트로 지정한 메인 사이트에서만 이러한 설정을 하는 것이 좋겠습니다.

저런, A+가 아직 나오지 않았어요

IIS의 한계랄까 안타까운 부분입니다. 이 부분에 대한 대응을 또 하나씩 해봅시다.

  • SHA1과 RC4 등 RC가 Cipher에 없음을 확인했습니다.
  • OCSP Stapling은 기본적으로 IIS가 챙기는 부분으로 별도의 설정은 불필요합니다. 다만, Must Staple 옵션을 적용할 방법이 보이지 않는군요.
  • Forward Secrecy는 ECDHE와 DHE를 지원한다면 저절로 robust support 될 것입니다.
  • TLS_FALLBACK_SCSV: 브라우저가 폴백(차선책) 시도를 할 수 있게 하여 구식 보안으로 다운그레이드하여 보안성을 약화시키는 것을 방지하는 기능입니다. 적절히 처리하지 못하면 POODLE 공격으로 이어질 수 있는데요. 안타깝게도 이 기능은 IIS에서 지원되지 않습니다.
    • 대신 TLS1.2 버전을 단독 지원함으로써 낮은 버전의 보안 연결을 원천적으로 봉쇄할 수 있습니다.
    • TLS1.2만 허용하게 되면서 버려지는 지원 기기의 예시는 다음과 같습니다.
      • Android 4.3 이전의 기기들
      • Baidu 2015년 1월 이전 버전
      • XP의 IE63~IE8
      • Vista의 IE7~IE8
      • Windows 7의 IE8~IE10 (Windows 7 현재 최신은 IE11)
      • Windows Phone 8.0의 IE8
      • Java 6, Java 7
      • OS X 10의 Safari 6.x

이 조치의 결과 A+를 획득하는데 성공했습니다. 그러나 버려지는 기기가 너무 많은 게 흠인 것 같습니다.

Footnotes

  1. 더 최신도 있습니다. 현재 시점에서는 1703이 대표적인 예시죠.
  2. Windows 10, Server 2016의 IIS는 SSL을 활성화하는 것만으로 별다른 설정 없이도 HTTP/2 연결을 시도하는 것으로 보입니다.
  3. 는 SSLv3만 지원해서 현대 웹에서 도태되어야 마땅하죠