HSTS 정책 NGINX 및 NGINX Plus로 구성하기
Netcraft는 최근 모니터링하는 SSL/TLS 사이트에 관한 연구를 발표했으며 그 중 5%만이 HSTS(HTTP Strict Transport Security)를 올바르게 구현하는 것으로 나타났습니다. 이 문서에서는 HSTS 정책을 구현하도록 NGINX 및 NGINX Plus를 구성하는 방법을 설명합니다.
목차
1. HSTS가 무엇인가?
2. 어떻게 HSTS가 작동하나?
3. NGINX 및 NGINX Plus로 HSTS 구성
3-1. add_header 지시문에 대한 상속 규칙
3-2. 조심히 HSTS 테스트하기
3-3. 모든 HTTPS 응답에 STS 헤더가 있어야 합니까?
4. 웹 사이트의 HTTP 및 HTTPS 버전 나란히 실행
5. HSTS 강화
6. 더보기
1. HSTS가 무엇인가?
HTTPS(SSL 또는 TLS로 암호화된 HTTP)는 웹사이트 트래픽을 보호하기 위한 필수 요소로, 공격자가 사용자와 웹사이트 간의 트래픽을 가로채거나 수정하거나 위조하는 것을 매우 어렵게 만듭니다.
사용자가 웹 도메인을 수동으로 입력하거나(http:// 또는 https:// 접두사 없이 도메인 이름 제공) 일반 http:// 링크를 따라가면 웹 사이트에 대한 첫 번째 요청이 일반 HTTP를 사용하여 암호화되지 않은 상태로 전송됩니다. 대부분의 보안 웹사이트는 사용자를 HTTPS 연결로 업그레이드하기 위해 즉시 리다이렉션을 되돌려 보내지만, 잘 배치된 공격자는 중간자(MITM) 공격을 탑재하여 초기 HTTP 요청을 가로채고 사용자 세션을 제어할 수 있습니다.
HSTS는 HTTPS를 통해서만 도메인에 액세스할 수 있음을 브라우저에 지시하여 잠재적인 취약점을 처리하려고 합니다. 사용자가 일반 HTTP 링크를 입력하거나 따라가더라도 브라우저는 연결을 HTTPS로 엄격하게 업그레이드합니다.

Chrome 개발자 도구는 HSTS 정책이 어떻게
HTTP를 HTTPS로 업그레이드하기 위한 내부 리다이렉션 생성
2. 어떻게 HSTS가 작동하나?
HSTS 정책은 보안(HTTPS) 웹사이트에서 다음 HTTP 응답 헤더를 전송하여 게시합니다.
Strict-Transport-Security: max-age=31536000
브라우저가 HTTPS 웹사이트에서 이 헤더를 보면 HTTPS(SSL 또는 TLS)를 통해서만 이 도메인에 액세스해야 됨을 "학습"합니다. max-age 기간(일반적으로 약 1년에 해당하는 31,536,000초) 동안 이 정보를 캐시합니다.
선택적 includeSubDomain 매개변수는 HSTS 정책이 현재 도메인의 모든 하위 도메인에도 적용됨을 브라우저에 알립니다.
Strict-Transport-Security: max-age=31536000; includeSubDomains
예를 들어 https://www.example.com에 대한 HTML 응답에는 example.com의 모든 하위 도메인에 대해 HSTS가 설정되었는지 확인하기 위해 https://example.com의 리소스에 대한 요청이 포함될 수 있습니다.
3. NGINX 및 NGINX Plus로 HSTS 구성
NGINX 및 NGINX Plus에서 STS(Strict Transport Security) 응답 헤더를 설정하는 것은 비교적 간단합니다.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
always 매개변수는 내부적으로 생성된 오류 응답을 포함하여 모든 응답에 대해 헤더가 설정되도록 합니다. 이전 버전의 NGINX(버전 1.7.5 또는 NGINX Plus R5 이전)는 항상 매개변수를 지원하지 않으며 내부적으로 생성된 오류 응답에 헤더를 설정하지 않습니다.
3-1. add_header 지시문에 대한 상속 규칙
NGINX 구성 블록은 둘러싸는 블록에서 add_header 지시문을 상속하므로 최상위 server 블록에 add_header 지시문을 배치하기만 하면 됩니다. 한 가지 중요한 예외가 있습니다. 블록에 add_header 지시문 자체가 포함되어 있으면 주변 블록에서 헤더를 상속하지 않으므로 모든 add_header 지시문을 다시 선언해야 합니다.
server {
listen 443 ssl;
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always;
# This ‘location’ block inherits the STS header
location / {
root /usr/share/nginx/html;
}
# Because this ‘location’ block contains another ‘add_header’ directive,
# we must redeclare the STS header
location /servlet {
add_header X-Served-By “My Servlet Handler”;
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always;
proxy_pass http://localhost:8080;
}
}
3-2. 조심히 HSTS 테스트하기
클라이언트에 HSTS 정책이 제공되면 지정된 최대 기간 동안 정보를 캐시합니다. 이 기간에 브라우저는 암호화되지 않은 HTTP를 통한 웹 서비스 액세스를 거부하고 인증서 오류에 대한 예외 승인을 거부합니다(사이트가 이전에 유효하고 신뢰할 수 있는 인증서를 제시한 경우). HSTS 정책에 대해 includeSubDomains 매개변수를 지정하면 이러한 제한 사항이 현재 도메인의 모든 하위 도메인에도 적용됩니다.
웹 사이트 또는 서비스의 HTTPS 버전을 제거하기 위해 HSTS 정책을 철회하는 것은 매우 어렵습니다. HSTS를 테스트할 때 매우 짧은 최대 수명 제한 시간을 사용하고 사이트의 HTTPS 버전을 유지해야 하는 효과와 의무에 대해 안심하고 있는지 확인하십시오. HSTS 정책을 처음 사용하는 경우 max-age를 작게 유지하고 확신이 있을 때만 늘리십시오.
3-3. 모든 HTTPS 응답에 STS 헤더가 있어야 합니까?
목표는 사용자가 HTTPS 세션을 시작할 때 가능한 한 빨리 HSTS 정책을 사용자에게 제공하는 것입니다. 세션 중에 HSTS 정책을 받지 못하면 향후 HTTP 하이재킹 공격에 취약한 상태로 유지됩니다.
브라우저는 STS 헤더를 한 번만 관찰하면 되므로 모든 location 블록과 모든 응답에 추가할 필요는 없습니다. 그러나 홈페이지나 로그인 페이지에만 헤더를 추가하는 것으로는 충분하지 않을 수 있으며 캐시 가능한 응답에만 헤더를 추가하면 클라이언트가 헤더를 보지 못할 수 있습니다. 동적(캐시할 수 없는) 콘텐츠에 특히 주의하면서 가능한 한 많은 URL 공간을 포함해야 합니다.
4. 웹 사이트의 HTTP 및 HTTPS 버전 나란히 실행
일부 사이트는 동일한 NGINX 또는 NGINX Plus 서버 내에서 웹 사이트의 HTTP 및 HTTPS 버전을 실행하여 두 프로토콜을 통해 콘텐츠에 액세스할 수 있도록 합니다.
server {
listen 80;
listen 443 ssl;
# ...
}
사용자가 HTTP를 통해 콘텐츠에 액세스하는 것을 원하지 않기 때문에 HSTS를 사용할 때는 적절하지 않습니다. 대신 HTTPS를 사용하도록 모든 HTTP 웹사이트 액세스를 리다이렉션하려고 합니다.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Discourage deep links by using a permanent redirect to home page of HTTPS site
return 301 https://$host;
# Alternatively, redirect all HTTP links to the matching HTTPS page
# return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
5. HSTS 강화
클라이언트는 선언된 max-age 기간 내에 해당 도메인에 대한 STS 헤더를 확인한 후 HTTP 가로채기로부터 보호됩니다.
그러나 HSTS는 HTTP 세션 하이재킹에 대한 완벽한 솔루션이 아닙니다. 사용자는 다음과 같은 경우 HTTP를 통해 HSTS로 보호되는 웹사이트에 액세스할 경우 여전히 공격에 취약합니다.
- 이전에 사이트를 방문한 적이 없음
- 최근에 운영체제를 다시 설치함
- 최근에 브라우저를 재설치함
- 새 브라우저로 전환됨
- 새 기기로 전환(예: 휴대폰)
- 브라우저 캐시 삭제
- 최근에 사이트를 방문하지 않았으며 max-age 시간이 지남
출처: Netcraft
이 문제를 해결하기 위해 Google은 HSTS를 사용하고 해당 이름을 https://hstspreload.appspot.com/에 제출한 웹 도메인 및 하위 도메인의 'HSTS 사전 로드 목록'을 유지 관리 합니다. 이 도메인 목록은 주요 웹 브라우저에 배포되고 하드코딩됩니다. 이 목록에 있는 도메인에 액세스하는 클라이언트는 자동으로 HTTPS를 사용하고 HTTP를 사용하여 사이트에 액세스하는 것을 거부합니다.
6. 더보기
HSTS에 대한 자세한 내용은 다음 리소스를 확인하세요.
- RFC 6797, HTTP Strict Transport Security(HSTS)
- Wikipedia의 HTTP 엄격한 전송 보안
- HSTS에 대한 브라우저 지원
NGINX 구성에 STS 헤더를 추가하는 것을 고려하고 있다면 지금이 X-Frame-Options 및 X-XSS-Protection과 같은 다른 보안 중심 HTTP 헤더 사용을 고려할 좋은 시기입니다.
NGINX Plus에는 DDoS(분산 서비스 거부) 공격과 같은 보안 위협 및 기타 문제로 사이트를 보호하기 위한 추가 기능이 있습니다. NGINX Plus를 사용해 보려면 지금 무료 30일 평가판을 시작하거나 NGINX STORE로 연락하여 사용 사례에 대해 논의하십시오.
사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.
댓글을 달려면 로그인해야 합니다.