.htaccess 및 mod_rewrite를 사용하여 SSL / https를 강제 실행


답변:


438

Apache의 경우 다음을 사용 mod_ssl하여 SSL을 강제 실행할 수 있습니다 SSLRequireSSL Directive.

이 지시문은 현재 연결에 대해 SSL을 통한 HTTP (예 : HTTPS)가 사용되지 않는 한 액세스를 금지합니다. 이는 SSL 사용 가상 호스트 또는 디렉토리 내에서 보호해야 할 항목을 노출시키는 구성 오류를 방지하는 데 매우 유용합니다. 이 지시문이 있으면 SSL을 사용하지 않는 모든 요청이 거부됩니다.

그래도 https로 리디렉션하지 않습니다. 리디렉션하려면 mod_rewrite.htaccess 파일에서 다음을 시도 하십시오.

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

또는에 주어진 다양한 접근 중 하나

공급자가 .htaccess를 비활성화 한 경우 PHP 내 에서이 문제를 해결할 수도 있습니다 (요청한 이후에는 가능하지 않지만 어쨌든)

if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
    if(!headers_sent()) {
        header("Status: 301 Moved Permanently");
        header(sprintf(
            'Location: https://%s%s',
            $_SERVER['HTTP_HOST'],
            $_SERVER['REQUEST_URI']
        ));
        exit();
    }
}

1
현재 http 트래픽과 https 트래픽이 혼합되어 있기 때문에 상황에 좋습니다. 관리자 영역의 경우 나머지 사이트를 http로 유지하면서 .htaccess 스크립트를 팝업했습니다.
Michael J. Calkins

1
mod_rewrite 메소드를 사용하면 https로 전송되지만 "페이지가 올바르게 리디렉션되지 않습니다"오류가 발생합니다.
Czechnology

11
후속 조치 : 비슷한 문제가 발생하면 서버 및 HTTP 변수를 확인하십시오. 서버가 프록시를 사용하는 경우 %{HTTP:X-Forwarded-Proto}또는 %{HTTP:X-Real-Port}변수를 사용 하여 SSL이 설정되어 있는지 확인할 수 있습니다.
Czechnology

8
프록시 뒤에서 실행되는 서버 ( CloudFlare , Openshift )에서 리디렉션 루프가 발생 하는 경우 해당 사례에 적합한 솔루션에 대해서는 이 답변 을 참조하십시오 .
raphinesse

4
@GTodorov-공간을 제거하면 저에게 rewriterule을 끊었다. Rewriterules에 대한 내 (제한된) 지식에서 구문은 RewriteRule <input-pattern> <output-url>입니다. 따라서 공간이 있어야하며 싱글 ^은 "모든 입력 URL과 일치"라고 말합니다.
Sphinxxx 2016 년

54

mod_rewrite프록시 서버와 프록시되지 않은 서버 모두에서 잘 작동 하는 솔루션을 찾았습니다 .

당신이 사용하는 경우 CloudFlare, AWS 탄성로드 밸런싱, Heroku가, OpenShift 또는 기타 클라우드 / PaaS를 솔루션을 당신이 발생하는 리디렉션 루프 정상 HTTPS 리디렉션과를 대신 다음 코드를 사용해보십시오.

RewriteEngine On

# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]

# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on

# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

이것은 훌륭한 thx입니다! 그러나 사후 조건을 추가해야합니까? RewriteCond % {REQUEST_METHOD}! ^ POST $
Aleksej

@Aleksej True, 이것은 암호화되지 않은 POST 요청을 중단합니다. 그러나 나는 이것이 좋은 것이라고 생각합니다. 이런 식으로 사람들은 자신이 무언가 잘못하고 있음을 알게 될 것입니다. 가장 좋은 방법은 서비스를 올바르게 사용하는 방법을 알려주는 페이지로 리디렉션하는 것입니다.
raphinesse

@raphinesse이 질문에 대한 답을 알고 있습니까 : stackoverflow.com/questions/51951082/…
RRN

36

PHP 솔루션

Gordon의 매우 포괄적 인 답변에서 직접 차용 한 귀하의 질문에 HTTPS / SSL 연결을 강제 할 때 페이지 별 내용이 언급되어 있습니다.

function forceHTTPS(){
  $httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  if( count( $_POST )>0 )
    die( 'Page should be accessed with HTTPS, but a POST Submission has been sent here. Adjust the form to point to '.$httpsURL );
  if( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']!=='on' ){
    if( !headers_sent() ){
      header( "Status: 301 Moved Permanently" );
      header( "Location: $httpsURL" );
      exit();
    }else{
      die( '<script type="javascript">document.location.href="'.$httpsURL.'";</script>' );
    }
  }
}

그런 다음 PHP를 통해 강제로 연결하려는 페이지의 상단에 require()가까워이 (및 다른) 사용자 정의 함수를 포함하는 중앙 집중식 파일을 만든 다음 간단히 forceHTTPS()함수 를 실행할 수 있습니다.

HTACCESS / mod_rewrite 솔루션

나는 이런 종류의 솔루션을 개인적으로 구현하지 않았지만 (단순하기 위해 위의 것과 같은 PHP 솔루션을 사용하는 경향이 있지만) 다음은 적어도 좋은 시작일 수 있습니다.

RewriteEngine on

# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$

# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

호기심에서 왜 RewriteCond %{REQUEST_METHOD} !^POST$?
depoulo

12
POST 매개 변수는 리디렉션에서 유지되지 않기 때문입니다. 모든 POST 제출이 안전한지 확인하려면 해당 행을 생략 할 수 있습니다 (보안되지 않은 POST 제출은 무시 됨).
Luke Stevenson

@Lucanos-POST시 http 또는 https로 리디렉션하지 않는 RewriteCond를 작성하는 방법은 무엇입니까? 내 .htaccess는 특정 페이지에서 HTTPS를 강제로 설정하고 나머지는 HTTP로 강제합니다. 그러나 HTTPS 페이지에는 웹 루트에 제출하는 양식이 있습니다. 양식은 작업 URL을 HTTPS로 지정합니다. 그러나 웹 루트는 HTTPS를 강제 실행하도록 지정된 페이지 중 하나가 아니기 때문에 내 .htaccess는 리디렉션을 강제 실행하여 POST 변수가 손실됩니다. POST에서 리디렉션을 어떻게 방지합니까?
StackOverflowNewbie

1
@StackOverflowNewbie :이 행 RewriteCond %{REQUEST_METHOD} !^POST$은 POST 제출이 이러한 리디렉션의 영향을받지 않도록해야합니다.
Luke Stevenson

나는이 PHP 버전을 좋아한다. POST를 고려할 때 훨씬 낫고 헤더가 이미 전송 된 경우 더 잘 처리합니다.
TheStoryCoder

10

모드 재 작성 기반 솔루션 :

htaccess에서 다음 코드를 사용하면 모든 http 요청이 https로 자동 전달됩니다.

RewriteEngine on

RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

이것은 당신의 리디렉션 www가 아닌를 하고 www가 에서 http 요청 www가 HTTPS의 버전.

다른 솔루션 (Apache 2.4 *)

RewriteEngine on

RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]

2.4 이후로 % {REQUEST_SCHEME} 변수가 mod-rewrite에 추가되었으므로 아파치 하위 버전에서는 작동하지 않습니다.


9

디렉토리 깊이에서 여러 .htaccess 파일을 사용할 때 Apache 에 최악의 상속 규칙 이 있음을 지적하고 싶습니다 . 두 가지 주요 함정 :

  • 가장 깊은 .htaccess 파일에 포함 된 규칙 만 기본적으로 수행됩니다. RewriteOptions InheritDownBefore이를 변경 하려면 지시문 (또는 유사한)을 지정해야합니다 . (질문 참조)
  • 패턴은 주어진 규칙에 따라 .htaccess 파일을 포함하는 상위 디렉토리가 아닌 서브 디렉토리에 상대적인 파일 경로에 적용됩니다. (토론 참조)

이는 하위 디렉토리에서 다른 .htaccess 파일을 사용하는 경우 Apache Wiki 의 제안 된 글로벌 솔루션 이 작동 하지 않음을 의미합니다 . 나는 다음과 같은 수정 된 버전을 작성했습니다.

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteOptions InheritDownBefore
# This prevents the rule from being overrided by .htaccess files in subdirectories.

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/

0

간단하고 쉽게 다음을 추가하십시오.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

이것은 인터넷상의 모든 사람들이 https를 강제로하기 위해 지시하는 것과 거의 같습니다. 그러나 그렇게 할 때마다 내 웹 사이트 전체가 FORBIDDEN이되거나 귀하는 볼 권한이 없습니다. 저런 ... 내가 뭘 잘못하고 있니? 이것에 대한 질문을 게시하기 전에 아이디어가 있는지 알고 싶습니다.
ThN

비슷한 문제가 있었고 https.conf 파일에 규칙을 적용해야했습니다. 아래 답변을 참조하십시오.
Risteard

-1

이 코드는 나를 위해 작동합니다

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

-1

간단한 것 :

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow

URL을 example.com으로 바꾸십시오.


아니! 사이트 URL은 동적이어야합니다.
Amir Savand

-1

Apache .htaccess로 SSL을 강제 실행하기 위해 사용할 수 있습니다.

SSLOptions +StrictRequire
SSLRequireSSL

위의 답변을 리디렉션하면 정확합니다.


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