.htaccess의 HSTS 권장 사항

Oct 18 2020

아래 하이퍼 링크에서 이전 게시물을 참조하십시오.

.htaccess여러 권장 변경 사항과 함께 HSTS를 고려하도록 파일을 업데이트했습니다 . 아래 스 니펫을 참조하십시오. 나는 HSTS구현하는 것이 그것에 익숙하지 않은 다른 누구에게도 가볍게 받아 들여지지 않는다는 점을 강조하고 싶습니다 . 이에 대한 지식이있는 사람들과 다르게 할 수있는 일에 대한 조언을 찾고 있습니다 .htaccess.

#IMPLEMENT HSTS
<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</IfModule>

#CUSTOM ERROR PAGES
ErrorDocument 400 /allerror.php
ErrorDocument 401 /allerror.php
ErrorDocument 403 /allerror.php
ErrorDocument 404 /allerror.php
ErrorDocument 405 /allerror.php
ErrorDocument 408 /allerror.php
ErrorDocument 500 /allerror.php
ErrorDocument 502 /allerror.php
ErrorDocument 504 /allerror.php

RewriteEngine On

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] #FORCE WWW TO NON-WWW RewriteCond %{HTTP_HOST} ^www.example.com [NC] RewriteRule ^(.*)$ https://example.com/$1 [L,R=301] #URL EXTENSION REMOVAL RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC] RewriteRule ^ /%1 [NC,L,R] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^ %{REQUEST_URI}.html [NC,L] #HOTLINKING PROTECTION RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com(/.*)*$ [NC]
RewriteCond %{HTTP_REFERER} !^$ RewriteRule \.(css|flv|gif|ico|jpe|jpeg|jpg|js|mp3|mp4|php|png|pdf|swf|txt)$ - [F]

#CONTENT SECURITY POLICY
<FilesMatch "\.(html|php)$"> Header set Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: 'unsafe-inline'; media-src 'self' data: 'unsafe-inline'; connect-src 'self';" </FilesMatch> #REDIRECT FOR DATE PAGE RewriteRule ^date$ /storage/date-202010 [R=301,L]

#REDIRECT FOR HOME PAGE
RewriteRule ^home$ / [R=301,L] #PREVENT DIRECTORY BROWSING Options All -Indexes #FILE CACHING #cache html and htm files for one day <FilesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>
    #cache css, javascript and text files for one week
<FilesMatch "\.(js|css|txt)$"> Header set Cache-Control "max-age=604800" </FilesMatch> #cache flash and images for one month <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|mp4|png)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
    #disable cache for script files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$"> Header unset Cache-Control </FilesMatch> #BLOCKS FILE TYPES FOR USERS <FilesMatch "\.(ht[ap]|ini|log|sh|inc|bak)$">
Require all denied
</FilesMatch>

HSTS 구현

HSTS를 조사하면서 배운 몇 가지 사항을 참고하려면 :

  1. SSL 인증서가 필요합니다.
  2. HTTP를 통해 사이트를 사용할 수있는 경우 301 영구 리디렉션을 사용하여 모든 요청을 HTTPS로 리디렉션합니다.
  3. .htaccess파일에 다음을 포함하십시오 Strict-Transport-Security: max-age=31536000; includeSubDomains; preload.. 최대 연령은 10886400 초 또는 18 주 이상이어야합니다. 2 년 가치를 유지하십시오.
  4. 아래 첫 번째 링크를 사용하여 도메인을 사전로드 목록에 추가하십시오.

자세한 내용은 아래의 각 출처를 읽어 보시기 바랍니다.

  • HSTS 사전로드 목록 제출
  • HSTS 란 무엇이며 왜 사용해야합니까? | Acunetix
  • HSTS 란 무엇이며 구현해야합니까? | 네트워크 역학
  • 웹 사이트에서 보안과 SEO를 개선하기 위해 HSTS를 사용해야하는 이유

답변

3 MrWhite Oct 27 2020 at 23:09

HSTS (HTTP Strict Transport Security)에는 두 가지 측면이 있습니다.

  1. 사이트에 HSTS를 구현합니다.
  2. 이미 HSTS가 활성화 된 사이트를 HSTS 사전로드 목록에 제출합니다 . 여기에서 "HSTS 사이트 목록"이 브라우저에 직접 컴파일되어 HTTP를 통한 첫 번째 요청 (요청이 MITM 공격에 잠재적으로 취약한 경우)을 방지합니다.

당신은 # 2를 위해 똑바로 가고있는 것 같습니다. 반드시 권장되는 것은 아닙니다. "사전로드 목록"을 편도 여행으로 생각하십시오. 기술적으로 사전로드 목록에서 제거 할 수 있습니다. 현실적으로 그것은 당신이 생각하고 싶은 것이 아닙니다. (힘들다-느리다-HSTS 전용에서 충분히 뒤로 물러 서기.)

사전로드 목록 제출 페이지 자체는 "목록 제출 사전로드"로 바로 이동하는 것을 권장하지 않습니다. 권장 사항은 max-age사전로드 목록에 제출하기위한 마지막 단계를 수행하기 전에 일정 기간 (개월)에 걸쳐 매개 변수 를 늘리는 것 입니다. 그 동안 테스트 테스트를 통해 SSL 인증서가 안정적으로 갱신되고 혼합 콘텐츠 경고 등이 없는지 확인합니다.

또한 SSL 구성을 완전히 제어 할 수없는 공유 서버 에서 HSTS 사전로드 목록 제출 (또는 어느 정도 HSTS 자체)에 대해서도주의 해야합니다. 실제로 공유 서버에 있는지 여부는 언급하지 않지만에서이 모든 구성을 수행하고 있으므로 사용자가 .htaccess있다고 가정합니다. 자신의 서버가 있고 서버 구성에 대한 액세스 권한이있는 경우이 대부분은 서버 / 가상 호스트 구성에서 구성해야합니다 (이 작업이 더 쉽고 안정적 ​​임).

일단 HSTS 경로를 사용하고 사용자가 HTTPS 사이트에 액세스했거나 "사전로드 목록"에 있으면 사이트 에 HTTPS를 통해서만 액세스 할 있다는 점 을 기억하십시오 . 이것은 귀하의 사이트뿐만 아니라 귀하가 사용하고있는 모든 제 3 자 서비스 (혼합 콘텐츠 브라우저 경고 등)에도 적용됩니다.

#IMPLEMENT HSTS
<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</IfModule>

이것은 "대부분의" * 1 응답 에 필요한 HSTS HTTP 응답 헤더를 설정합니다 (하지만 preload처음에는 생략되어야 하는 매개 변수에 유의하십시오 ).

* 1 그러나이 지시문은 모든 응답에 필요한 헤더를 반드시 설정하지는 않습니다. HSTS의 요구 사항은 "리디렉션"응답에 헤더를 설정하는 것입니다 (예 : HTTPS에서 www가 아닌 ​​www로). 현재 위는 이것을하지 않습니다. 200 OK 이외의 응답에 헤더를 설정하려면 지시문의always 조건 을사용해야합니다Header. 예를 들면 :

# Use "always" condition to set on "redirects" as well.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

(지금은 preload매개 변수 도 제거했습니다 .)

<IfModule>래퍼 가 필요하지 않으므로 제거해야합니다. mod_headers는 기본적으로 활성화되어야합니다. 이것은 귀하의 서버이며, mod_headers가 활성화되었는지 여부를 알고 있습니다. 이 작업을 수행 하려면 mod_headers 활성화 해야합니다 . mod_headers를 사용할 수없는 경우 자동으로 실패 하는 것을 원하지 않습니다. 로그의 오류와 함께 실패하는 즉시 알림이 필요합니다.

많은 기사 에서 보안 (HTTPS) 응답 에만Strict-Transport-Security 헤더를 설정 해야한다고 설명 합니다 . 그리고 "사전로드 목록 제출"은 HTTP를 통해서도 헤더를 보내면 실제로 "경고"(엄격히 "오류"가 아니라)를 발행합니다. 그러나 그것은 단지 반면 필요 가 헤더가 문제인지 "불필요"HTTP뿐만 아니라 보냈해서는 안 (방지 MITM 공격에) 암호화되지 않은 HTTP 연결을 통해 전송 될 때 HTTPS 응답에 설정할 수, 호환 브라우저는이 헤더를 무시합니다. 이것은 <VirtualHost>주 서버 구성 의 적절한 컨테이너에서 관리하기가 더 쉽습니다 . HTTPS 응답에 대해서만 이 헤더를 보내는 .htaccess것은 더 복잡하므로 오류가 발생하기 쉽습니다. HSTS 응답 헤더를 조건부로 설정하는 데 사용할 수있는 추가 환경 변수를 사용해야합니다.

예를 들면 :

# Set environment var "HSTS" if accessed over HTTPS connection
RewriteCond %{HTTPS} on
RewriteRule ^ - [E=HSTS:1]

# Conditionally set only on HTTPS connections (ie. when "HSTS" env var is set)
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" env=HSTS

그렇지 않으면 HSTS와 관련하여 나머지 지침이 괜찮다고 생각합니다. 그러나 항상 그렇듯이 테스트 테스트 테스트.


여러 (불필요한) 리디렉션 해결

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]

여기서 잠재적 인 문제 (위의 두 번째 및 세 번째 표준 리디렉션, HTTP에서 HTTPS로 리디렉션 후)는 www+ .html가 요청 될 경우 잠재적으로 두 번의 추가 리디렉션이 발생한다는 것 입니다. 이 문제는 단순히 두 리디렉션을 되돌리고 'URL 확장 제거'리디렉션에 표준 호스트 이름을 포함하여 해결할 수 있습니다 ( 이전 질문에 대한 답변 에서 언급 했듯이 ).

예를 들면 :

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ https://example.com/%1 [R=301,L]

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [R=301,L]

일부 잠재적 문제를 해결하는 "URL 확장 제거"리디렉션에 대한 대체 접근 방식에 대해서는 이전 답변 을 참조하십시오 .

www다른 호스트 이름 (예 :) 에서 하위 도메인을 사용하지 않는 경우 www www.subdomain.example.comCondPattern 을 www가 아닌 ​​리디렉션으로 단순화 할 수 ^www\.있습니다. www.전체 호스트 이름을 확인하지 않고 단순히 시작하는 요청 된 호스트 이름.


추가 수정

URL 확장 제거 / 다시 쓰기 루프 (500 내부 서버 오류)

HSTS와 관련이없는 이전 질문 에서 다루지 않은 몇 가지 다른 문제가 있습니다. 아래에서 다룰 것입니다.

#URL EXTENSION REMOVAL
:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [NC,L]

이것은 확장명이없는 URL을 사용할 때 파일 확장명을 추가 (URL 재 작성)하는 "표준"방법으로 모든 곳에 "맹목적으로"복사 / 붙여 넣기하는 코드 스 니펫 중 하나입니다 . 그러나 유효한 URL에는 "작동"할 수 있지만 잘못된 URL을 요청할 때는 심각한 결함이 있습니다.

경우 /about.html확장명이 URL을 요청할 때 여러분이 봉사 할 것을 유효한 파일이 /about다음 확인을 작동합니다. 그러나 내가 (악의적으로) 요청 /about/하거나 /about/<anything>서버를 나선형 재 작성 루프로 보내면 500 내부 서버 오류 응답이 발생합니다. 최종 사용자는 그러한 응답을 호출 할 수 없어야합니다 (DDOS 공격 및 기타 적대적 행동에 더 취약 할 수 있음).

이는 REQUEST_FILENAME(매핑 된 파일 시스템 경로)가 반드시 REQUEST_URI(요청 된 URL- 경로) 변수 와 동일한 공용 URL- 경로를 참조하지 않기 때문 입니다.

이 문제를 해결하려면 REQUEST_URI전체적으로 사용하십시오 . 예를 들면 :

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^ %{REQUEST_URI}.html [L]

( NC플래그는 RewriteRule여기 의 지시문에서 불필요 합니다.)

이에 대한 자세한 내용 은 다음 ServerFault 질문에 대한 내 대답 을 참조하십시오 .

핫 링크 보호-조건 단순화

#HOTLINKING PROTECTION
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com(/.*)*$ [NC]

이것은 상대적으로 사소합니다. 위 조건의 정규식은 단순화 할 수 있습니다. .htaccess파일 의이 시점에서 호스트 이름은 이미 www가 하위 도메인을 제거하도록 정규화되었으므로 (www\.)?위 의 하위 패턴은 불필요합니다. 다른 모든 것과 일치 하는 후행 (/.*)*$하위 패턴도 마찬가지입니다. 여기에서 어떤 것도 실제로 일치 시킬 필요는 없습니다 . 헤더가 적절한 (scheme +) 호스트 이름으로 시작 한다고 단언하면 됩니다.Referer

예를 들면 :

RewriteCond %{HTTP_REFERER} !^https://example\.com

NC플래그는 여기에도 불필요하다. 필요하지 않은 경우 대소 문자를 구분하지 않는 일치를 강제하면 서버에 더 많은 작업이 생성되고 어떤 경우에는 취약성에 노출 될 수 있습니다 ( "중복 콘텐츠"는 일반적인 문제입니다-여기에서는 문제가되지 않습니다). .

불필요한 활성화 Options

#PREVENT DIRECTORY BROWSING
Options All -Indexes

이것은 "디렉토리 브라우징"을 막는 것만 이 아닙니다 . 이 All인수 서버 측 포함 ( Includes) 및 CGI 스크립트 실행 ( ExecCGI) 기능 과 같이 필요하지 않을 있는 다른 많은 것들을 가능하게 합니다 . (덧붙여, 이것은 당신이 함께 인수를 혼합 할 수있는 유일한 시간 +이나 -없는 사람으로.)하기 (예. mod_autoindex가 디렉토리 인덱스의 자동 생성) 후 제거 디렉터리 검색을 방지 All인수를.

그러나 아마도 (이미 서버 구성에 설정되었을 수 있음) 필요 FollowSymLinks 하므로 대신 다음을 설정할 수 있습니다.

Options FollowSymLinks

+또는 의 부재에 유의하십시오 -. 이 단지 세트 FollowSymLinks, 불가능하므로 Indexes이미 설정된 경우 ( "디렉터리 검색을").