Posts HTTPS 요청이 HTTP로 리다이렉트 되는 현상
Post
Cancel

HTTPS 요청이 HTTP로 리다이렉트 되는 현상

상황

  • 서버 이전 작업 후 담당 웹사이트에서 URL 리다이렉트시 페이지 응답이 없는 경우가 발생함
  • 특정 사용자에게서는 이런 현상이 발생하지 않음
  • 확인해보니 HTTPS 요청이 HTTP로 바껴서 리다이렉트됨

image

원인 파악하기

  • 요청이 WAS에 도달하기까지의 흐름
    • (브라우저) ---- https ---- (L4/L7 스위치) ---- https ---- (웹서버) ---- http ---- (WAS)
  • 인터셉터에서 HttpServletResponse.sendRedirect 하는 부분을 타고 들어가다보면 헤더에 Location을 세팅하는 코드를 만날 수 있다.
    • org.apache.catalina.connector.Response#sendRedirect

image

  • else절에 toAbsoulte 메서드에서 요청 프로토콜은 request.getScheme() 을 통해 가져온다. org.apache.catalina.connector.Response#toAbsolute image

즉, WEB에서 WAS로 들어오는 요청은 http이므로 리다이렉트 url이 http로 만들어지게 되었던 것

의문점

  1. 이전 서버 구성에서는 이런 이슈 제보된 적이 없었음
    => 이전 L4/L7 스위치에서 80 포트가 허용 되어있었음

  2. 특정 사용자는 접근이 됨
    => HSTS로 인해 HTTPS로 리다이렉트 되었음 (웹서버 설정 : Strict-Transport-Security: max-age=31536000) image

※ HSTS란 ?

공식문서 참고

  • HTTP Strict-Transport-Security 응답 헤더(종종 HSTS로 축약됨)는 사이트가 HTTPS를 통해서만 접근되어야 하며 향후 HTTP를 사용하여 사이트에 접근하려는 모든 시도는 자동으로 HTTPS로 변환되어야 함을 브라우저에 알립니다.
  • HTTPS를 사용하여 사이트에 처음으로 접근하고 Strict-Transport-Security 헤더를 반환하면 브라우저가 이 정보를 기록하고, 이후에 HTTP를 사용하여 사이트를 로드하려고 시도할 때 자동으로 HTTPS를 대신 사용합니다.

조치

해결방법1 : 톰캣 use-relative-redirects 속성 사용

공식문서 설명
“sendRedirect 호출로 생성된 HTTP 1.1 이상의 Location 헤더가 상대 리디렉션을 사용할지 절대 리디렉션을 사용할지 여부 (기본값 : false)”

  • server.tomcat.use-relative-redirects=true로 세팅하면 response.sendRedirect("/상대경로")로 호출시 리다이렉트 url이 상대경로로 지정됨 (요청 프로토콜 그대로 사용)
  • 관련 코드 (위에서 살펴본 org.apache.catalina.connector.Response#sendRedirect의 if절)

image

  • 리다이렉트 url이 상대경로로 지정됐을때, https로 재요청하는 모습

image image

해결방법2 : 톰캣에서 X-Forwarded-Proto 인식할 수 있도록 하기

  • 웹 서버에서 톰캣으로 요청시 X-Forwarded-Proto 헤더에 https를 담아서 보낸다.
    • 관련 아파치 설정 :RequestHeader set X-Forwarded-Proto "https"
  • 톰캣에서 리다이렉트 url 지정시 request에 담긴 X-Forwarded-Proto 활용하게 한다.
    • 이렇게 하려면 response.sendRedirect시 response 구현체가 org.springframework.web.filter 패키지의 ForwardedHeaderFilter.ForwardedHeaderExtractingResponse가 되도록 해야함
    • 이를 위해, 아래와 같이 필터를 빈으로 등록 (부트 2.1 버전부터는 직접등록하지 않고 톰캣에 관련 설정만 해주면 자동으로 세팅되는 것 같음 : 관련 글 - 담당 웹사이트는 2.0.3v 사용)
1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class XForwardedFilterConfig {

    @Bean
    public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
        FilterRegistrationBean<ForwardedHeaderFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new ForwardedHeaderFilter());
        return registrationBean;
    }

}
  • 리다이렉트 url이 https로 세팅됨 image

참고. HTTP 리다이렉트 관련 상태 코드

 301302303307308
StatusMoved PermanentlyFoundSee OtherTemporary RedirectPermanent Redirect
영구적 리다이렉션OXXXO
기존 요청 변경O (POST -> GET)O (POST -> GET)O (무조건 GET으로 변경)XX

※ 영구적 리다이렉션에서는 기존 URL에 대한 모든 SEO 값과 링크 리소스가 새 URL로 이전.

This post is licensed under CC BY 4.0 by the author.

wait_timeout을 초과한 커넥션을 사용해서 겪은 이슈 (The last packet successfully received from the server was ... milliseconds ago)

javax.net.ssl.SSLHandshakeException - No appropriate protocol (protocol is disabled or cipher suites are inappropriate)의 원인을 찾아서