Ghost + Cloudflare에서 HTTPS 설정 문제 해결
Ghost 블로그를 Cloudflare를 이용해 https를 적용할 때 생기는 ERR_TOO_MANY_REDIRECTS 문제를 해결했습니다.
2. Cloudflare Proxy를 쓰는 경우에 충돌이 생겨서 무한 리다이렉트
3. Ghost 앞에 Nginx로
X-Forwarded-Proto https 헤더 추가이 블로그는 Ghost를 이용하여 운영 중입니다.
어쩌다가 선택하게 되었는지는 잘 기억나지 않지만, 아마 네이버 블로그는 진부하고, 티스토리는 뭔가 뭔가고, 워드프레스는 고루해서 찾다가 선택한 결과였던 것 같습니다.
그래서 Ghost로 블로그를 만들겠다고 생각하고, Cloudflared로 연결 했을 때 생긴 문제입니다.
문제 환경

문제가 생긴 환경은 Ghost 블로그가 Cloudflare Proxy를 거칠 때 생겼습니다.
Ghost와 Nginx, Cloudflared는 모두 내부 망에서 통신합니다.
이 과정에서 내부 망에서는 https가 필요없고, 인증서 관리의 번거로움 때문에 Cloudflared와 통신까지는 전부 http로 통신합니다.
원인 분석
Cloudflared를 사용하면, 사용자가 웹사이트를 접속할 때 자동으로 https로 설정됩니다.
Ghost 설정에서 서버 주소가 https로 시작하는 경우
- 사용자가
https://...로 웹사이트에 접속을 시도합니다. - Cloudflare는 내부망으로
http요청을 보냅니다. - Ghost는 서버의 주소가
https://로 지정되어 있으므로,http요청에 대해서301/302 Redirect응답을 보냅니다. - Cloudflare는 이 리다이렉트 응답을 사용자에게 전달하고, 다시 요청합니다.
결과적으로 Cloudflare와 Ghost 사이에서 https -> http 접속을 반복하다, ERR_TOO_MANY_REDIRECTS 에러 화면이 나오게됩니다.
Ghost 설정에서 서버 주소가 http로 시작하는 경우
- 사용자가
https://...로 웹사이트에 접속을 시도합니다. - Cloudflare는 내부망으로
http요청을 보냅니다. - Ghost는 서버의 주소가
http://로 지정되어 있으므로, 정상적으로 응답을 보냅니다.
http로 설정을 한 경우에 이 과정에서 문제는 발생하지 않습니다.
하지만 내부적으로 서버의 주소가 http로 시작하기 때문에, Mixed Content 차단 문제가 발생합니다.
Cloudflare를 이용해서 https가 이미 적용되어있지만, 내부에서는 http로 요청을 하게 되고, 웹 브라우저는 이 요청에 대해서 보안 경고 및 요청 차단을 합니다.
결과적으로 Ghost에서 제공하는 이미지나 Preview, 테마나 iframe 등을 이용할 수 없게 됩니다.
해결

Ghost에서 제공하는 기능과 보안을 위해서는 https로 설정되어야 합니다.
하지만 통신 과정에서 http로 요청하게 된다면, 문제가 발생합니다.
근본적으로 문제를 해결하기 위해서 Ghost와 이후 통신 과정에서는 모든 요청이 https로 인식되어야한다는 결과를 얻을 수 있습니다.
proxy_set_header X-Forwarded-Proto https;이 부분이 핵심입니다.
문제를 해결하기 위해서 Ghost와 직접 연결하지 않고, Nginx를 거치게 만들었습니다.
Nginx는 Ghost와 연결되는 통신에 대해서 X-Forwarded-Proto를 https로 설정합니다.
이후 Ghost는 모두 정상적인 https 요청으로 처리되고, Cloudflare도 http 요청을 했을 때 Redirect 응답이 아니게 되므로 문제가 해결됩니다.
server {
listen 80;
listen [::]:80;
server_name saykcay.dev;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https; # 이 부분을 추가합니다.
proxy_pass http://127.0.0.1:2368;
}
}