브라우저가 SNI를 지원하는 경우에만 SSL로 리디렉션


20

VirtualHosting과 동일한 IP / 포트에 mod_ssl이 포함 된 Apache 2.2와 HTTPS에 많은 사이트가 있으므로 클라이언트가 해당 가상 호스트에 연결하려면 SNI를 지원해야합니다.

다음과 같은 방법으로 서버를 구성하고 싶습니다.

사용자가 www.dummysite.com을 입력하고 그의 브라우저 SNI (Server Name Indication)를 지원하면 HTTP 요청이 https://HSTS 헤더가 전송되는 곳 으로 리디렉션됩니다 . 그러나 브라우저 SNI를 지원하지 않으면 요청은 HTTP로 제공됩니다.

위와 같은 규칙은 모질라와 크롬에 이러한 문제가 없으므로 사용자를 사이트 밖으로 나가지 않기 위해 여전히 오래된 브라우저를 사용하는 사람들에게는 대체 규칙입니다.

Apache 구성 수준에서 사용자 에이전트의 필터를 사용 하여이 리디렉션을 수행하고 싶습니다. 직접적인 http : // 참조가 존재하지 않는 것을 제외하고 실행중인 응용 프로그램을 만지고 싶지 않습니다 (그렇지 않으면 보안 경고를 암시합니다)

(내가 잊었 질문 편집하는 동안 [편집] 질문) : 리디렉션 SNI 사용이 가능한 사용자 에이전트의 목록은 무엇인가?

답변:


20

SNI는 SSL / TLS 핸드 셰이크 중에 발생하므로 클라이언트가 HTTP에 연결할 때 브라우저 지원을 감지 할 수 없습니다.

그래서 당신이 맞습니다. 이를 수행하는 유일한 방법은 사용자 에이전트 필터입니다.

가장 큰 문제는 SNI를 수신하지 않는 브라우저 또는이를 지원하는 것으로 알려진 브라우저에 대해 블랙리스트로 작업 할 것인지 여부입니다. 사이트를 사용할 수없는 모호하거나 새로운 장치는 거래 차단기처럼 보이므로 허용 목록이 더 나은 옵션이라고 할 수 있습니다.

귀하의 HTTP에서 <VirtualHost>:

# Internet Explorer 7, 8, 9, on Vista or newer
RewriteCond %{HTTP_USER_AGENT} MSIE\s7.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s8.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s9.*Windows\sNT\s6 [OR]
# Chrome on Windows, Mac, Linux
RewriteCond %{HTTP_USER_AGENT} Windows\sNT\s6.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Macintosh.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Linux.*Chrome [OR]
# Firefox - we'll just make the assumption that all versions in the wild support:
RewriteCond %{HTTP_USER_AGENT} Gecko.*Firefox
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]

블랙리스트 옵션도 있습니다. 이로 인해 SNI를 사용하지 않는 클라이언트를 SNI가 필요한 사이트로 보낼 위험이 있지만 반면에 IE 10과 같은 새로운 사용자를 오른쪽으로 보낼 것입니다. 장소:

# IE 6
RewriteCond %{HTTP_USER_AGENT} !MSIE\s6
# Windows XP/2003
RewriteCond %{HTTP_USER_AGENT} !Windows\sNT\s5
# etc etc
RewriteRule ^/(.*)$ https://ssl.hostname/$1 [R=301]

거기에는 많은 브라우저가 있습니다. 나는 표현이 너무 느슨했고 많은 브라우저를 다루지 않았습니다.

어떤 옵션을 선택하든 .. 행운을 빌어 요!


1
큰! Opera Mobile (SNI 호환이지만 목록에는 없음)로 테스트했으며 리디렉션되지 않습니다. 내 Firefox에서는 리디렉션됩니다!
usr-local-ΕΨΗΕΛΩΝ

6
mod_setenvif httpd.apache.org/docs/2.2/mod/mod_setenvif.html 의 BrowserMatch 지시문 으로이 솔루션을 모듈화하는 것이 좋습니다 . BrowserMatch를 사용하여 환경 변수 supports_sni = y를 설정 한 다음 RewriteCond % {ENV : supports_sni} = y를 작성하십시오. 이렇게하면 다른 RewriteRules에 대해 SNI 감지 로직을 재사용 할 수 있습니다.
200_success

@ 200_success 좋은 생각이야!
Shane Madden

8

내 해결책은 이것입니다 :

  # Test if SNI will work and if not redirect to too old browser page
  RewriteCond %{HTTPS} on
  RewriteCond %{SSL:SSL_TLS_SNI} =""
  RewriteRule ^ http://www.example.com/too-old-browser [L,R=307]

SNI가없는 오래된 브라우저가 https://www.example.com/ * 에 액세스하려고 하면 브라우저에서 먼저 오류가 발생합니다. 아파치가 SNI가 아닌 브라우저에 응답 할 때까지 알 수 없으므로 피할 수 없습니다 요청하는 사이트 그런 다음 사용자 클릭이 웹 사이트를 계속 사용하는 한 브라우저가 너무 오래되었음을 알리는 페이지로 리디렉션됩니다.

새로운 브라우저를 사용하는 사용자에게는

  #Test if new browser and if so redirect to https
  #new browser is not MSIE 5-8, not Android 0-3
  RewriteCond %{HTTPS} off
  RewriteCond %{HTTP_USER_AGENT} !MSIE\ [5-8]
  RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)?\ [0-3]
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Vista의 MSIE 5-8과 같은 일부 이전 브라우저는 제외합니다 (9+는 Vista / 7에 불과하므로 SNI 지원). 100 % (심볼은 무시되는 등)는 아니지만 대다수를 위해 작동해야합니다. 소수는 여전히 인증서 오류를 수락하도록 선택할 수 있습니다.


3

내가 아는 한 실제로이 작업을 수행하는 좋은 방법은 없습니다 . 헤더를 기반으로 mod_rewrite 규칙 또는 이와 유사한 조건을 조건부로 사용할 수 User-agent있지만 NON-SSL 가상 호스트에 있어야합니다. 브라우저 가 그렇지 않은 경우 SNI를 지원하고 안전한 ( https://) 사이트로 이동하여 "이 IP 주소와 관련된 첫 번째 SSL 인증서는 다음과 같습니다."라는 구식 Apache 동작을 얻 습니다. -인증서가 아닌 경우 브라우저에서 호스트 이름이 일치하지 않는다는 오류 메시지가 표시됩니다.

이는 기본적으로 사람들이 SSL을 사용하지 않는 전면 광고 페이지를 방문하여 경로를 재지 정하여 요청시 전송중인 데이터를 노출시킬 수 있음을 의미합니다. 이것은 거래 차단기 일 수도 있고 아닐 수도 있습니다 (SNI를 지원하지 않는 경우 SSL을 사용하지 않는 사이트로 보내겠다고 말하므로 보안에 대해서는 크게 신경 쓰지 않는다고 가정합니다. 암호화 또는 인증 계층으로 SSL이 필요한 시스템을 설계하지만 조금 더 일관성이 있습니다 ...)

그 중 어느 것도 보안 사이트를 책갈피에 추가하는 것을 막을 수는 없습니다. 공유 책갈피 서비스를 사용하거나 웹 브라우저가 SNI를 지원하지 않는 컴퓨터로 책갈피를 복원하는 경우 SSL 오류 가능성 사례로 돌아갑니다. .


1

이 세 가지 방법 중 하나를 해결하고 싶은 유혹이 있습니다.

  1. RewriteRuleUser-Agent헤더를 기반으로 합니다.
  2. <SCRIPT>기본이 아닌 VHost 의 태그에 https : // URI를로드하십시오 . 로드가 성공하면 HTTPS에서 전체 페이지를 다시로드하는 것은 약간의 JS입니다.
  3. 내 방문자가 우선 순위 인 경우 HTTPS Everywhere와 같은 것을 사용하도록 가르치고, 필요한 페이지에서 HTTPS를 강제 실행하고 모든 것이 결국 제대로 작동하기를 바랍니다.

이 중 개인적으로 # 2가 가장 좋지만 사이트 코드 수정과 관련이 있습니다.


0

그것을 필요로하는 누군가를 위해.

여러 개의 호스트가 있고 VirtualHosting에서 모두 SSL을 사용하도록 설정하고 각 호스트에 대해 인증서를 구입하려는 경우 새 호스트를 사용해보십시오. mod_djechelon_ssl

$ cat /etc/apache2/mod_djechelon_ssl.conf 
RewriteEngine on
# Internet Explorer 7, 8, 9, on Vista or newer
RewriteCond %{HTTP_USER_AGENT} MSIE\s7.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s8.*Windows\sNT\s6 [OR]
RewriteCond %{HTTP_USER_AGENT} MSIE\s9.*Windows\sNT\s6 [OR]
# Chrome on Windows, Mac, Linux
RewriteCond %{HTTP_USER_AGENT} Windows\sNT\s6.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Macintosh.*Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} Linux.*Chrome [OR]
# Firefox - we'll just make the assumption that all versions in the wild support:
RewriteCond %{HTTP_USER_AGENT} Gecko.*Firefox [OR]
#Safari iThing
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPhone.*Safari [OR]
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPod.*Safari [OR]
RewriteCond %{HTTP_USER_AGENT} Mozilla.*iPad.*Safari [OR]
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=permanent,L]

용법:

<VirtualHost ip:80>
ServerName www.yourhost.com

Include /path/to/mod_djechelon_ssl.conf

[plain old Apache directives]
</VirtualHost>

<VirtualHost ip:443>
ServerName www.yourhost.com

[SSL-related directives]

[Copy and paste directives from above host]
</VirtualHost>

0

여기게시 한대로 SNI 지원을 요청 하기 전에 SNI 지원 만 테스트 할 수 있습니다 . 즉, 사용자에게 SNI HTTPS를 강제로 적용한 후이를 지원하지 않으면 대체 할 수 없습니다. 계속 진행할 방법이없이 Windows XP의 Chrome에서 이와 같은 오류가 발생하기 때문입니다.

따라서 (불행히도) 사용자는 실제로 안전하지 않은 HTTP 연결을 시작한 다음 SNI를 지원하는 경우에만 업그레이드해야합니다.

다음을 통해 SNI 지원을 감지 할 수 있습니다.

  1. 원격 스크립트
    일반 HTTP 페이지 <script>에서 대상 SNI HTTPS 서버에서 a 를로드하고 스크립트가 올바르게로드 및 실행되면 브라우저가 SNI를 지원한다는 것을 알고 있습니다.

  2. 도메인 간 AJAX (CORS)
    옵션 1과 유사하게 HTTP 페이지에서 HTTPS로 도메인 간 AJAX 요청을 수행 할 수 있지만 CORS는 브라우저 지원이 제한적 이라는 점에 유의하십시오 .

  3. 사용자 에이전트 스 니프이
    방법은 아마도 가장 신뢰할 수없는 방법이므로이를 지원하지 않는 것으로 알려진 브라우저 (및 운영 체제)의 블랙리스트 또는 알려진 시스템의 화이트리스트를 결정해야합니다.

    Windows XP 이하의 모든 IE, Chrome 및 Opera 버전은 SNI를 지원하지 않습니다. 지원되는 브라우저의 전체 목록은 CanIUse.com을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.