Cloudflare를 켠 뒤 갑자기 “ERR_TOO_MANY_REDIRECTS”, “SSL handshake failed”, “526 Invalid SSL certificate” 같은 문제가 생기면, 원인이 복잡해 보이지만 실제로는 몇 가지 설정 실수가 대부분입니다. 이 글은 가장 흔한 설정부터 순서대로 확인하고, 설정 파일 예시와 함께 검증/재시작까지 이어가는 방식으로 정리했습니다.
급할수록 “지금 어떤 HTTPS가 어디에서 끝나는지(Cloudflare vs Origin)”만 먼저 정리하면 빨라집니다.
1) 먼저 증상별로 Cloudflare 에러 코드를 분류하기
Cloudflare SSL 이슈는 에러 코드가 힌트를 줍니다. 아래에서 본인 증상에 가장 가까운 것부터 확인하세요.
- ERR_TOO_MANY_REDIRECTS: HTTP→HTTPS 리다이렉트가 Cloudflare와 Origin(Nginx/Apache)에서 중복되었을 가능성이 큼
- 526 Invalid SSL certificate: Cloudflare가 Origin에 HTTPS로 붙는데, Origin 인증서가 유효하지 않거나 체인이 불완전(대개 “Full (strict)”에서 발생)
- 525 SSL handshake failed: Origin의 TLS 설정(프로토콜/암호군) 또는 방화벽/포트 이슈 가능
- 520/521/522: SSL 자체보다 Origin 응답/연결 문제(웹서버 다운, 방화벽, 과부하)일 수 있음
이번 글은 그중에서도 SSL 설정 실수 비중이 높은 케이스(526, 리다이렉트 루프, 인증서/체인 문제)를 우선으로 다룹니다.
2) 가장 흔한 1순위: Cloudflare SSL/TLS 모드(Full vs Full (strict))부터
Cloudflare 대시보드에서 SSL/TLS → Overview의 모드가 핵심입니다.
- Full: Cloudflare↔Origin 구간을 HTTPS로 하되, Origin 인증서 유효성은 엄격히 검사하지 않음(임시 처방으로는 쉬움)
- Full (strict): Cloudflare↔Origin 구간 HTTPS + Origin 인증서가 유효해야만 함(운영 권장)
운영에서는 보통 Full (strict)가 목표입니다. 다만 지금 장애 상황이면, 원인 파악을 위해 잠깐 Full로 바꿔 “인증서 검증 실패인지”를 가려낼 수 있습니다. Full로 바꾸자마자 정상화된다면, 거의 확실히 Origin 인증서/체인 문제입니다.
3) Origin 인증서 실수 체크: Cloudflare Origin Certificate vs Let’s Encrypt
Full (strict)에서 가장 흔한 실수는 “Origin에 설치한 인증서가 Cloudflare가 신뢰할 수 없는 형태”인 경우입니다. 선택지는 크게 두 가지가 있습니다.
- Let’s Encrypt: 일반적인 공인 인증서. 브라우저/Cloudflare 모두 신뢰.
- Cloudflare Origin Certificate: Cloudflare가 Origin용으로 발급하는 인증서. 브라우저 직접 접속에는 부적합할 수 있으나(환경에 따라 경고), Cloudflare↔Origin에는 최적.
가장 흔한 실수
- Origin에 인증서 파일은 깔았는데 fullchain이 아니라 cert만 연결해서 체인 누락
- Cloudflare Origin Certificate를 설치했는데, Cloudflare 모드는 Full (strict)인데도 키/인증서 매칭이 틀림
- Origin의 SNI/서버블록이 여러 개인데, 기본 vhost가 엉뚱한 인증서를 제공
Nginx 설정 예시(권장: fullchain 사용)
예: /etc/nginx/sites-enabled/example.conf
주의: 경로는 환경에 맞게 조정하세요.
Nginx에서 Let’s Encrypt를 쓰는 경우 보통 아래처럼 fullchain.pem을 사용합니다.
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# (선택) 최소 TLS 버전 정책
ssl_protocols TLSv1.2 TLSv1.3;
}
Apache 설정 예시(체인 포함)
예: /etc/apache2/sites-enabled/example-le-ssl.conf
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# 배포판/버전에 따라 SSLCertificateChainFile이 필요 없는 경우가 많습니다(fullchain 사용 시)
</VirtualHost>
빠른 검증(Origin에서 직접 확인)
- Origin 서버에서 인증서 만료일 확인: openssl x509 -in /path/to/fullchain.pem -noout -dates
- Cloudflare를 우회해 Origin이 어떤 인증서를 주는지 확인(서버에서 실행):
openssl s_client -connect 127.0.0.1:443 -servername example.com -showcerts
여기서 CN/SAN이 도메인과 맞는지, 체인이 함께 보이는지(중간 인증서 포함) 확인합니다.
4) 무한 리다이렉트(Too Many Redirects): “한 군데만” HTTPS로 올리기
리다이렉트 루프는 보통 아래 조합에서 터집니다.
- Cloudflare: Always Use HTTPS 켬 + Origin(Nginx/Apache)에서도 HTTP→HTTPS 리다이렉트
- Cloudflare: Flexible(권장X) + Origin이 “HTTPS로 접속했다”고 착각/판단하는 규칙이 꼬임
- Origin 뒤에 앱(PHP/Laravel, Node 등)이 X-Forwarded-Proto를 반영 못 해서 계속 https로 재리다이렉트
권장 정리 원칙
- Cloudflare는 Full (strict)로 두고
- HTTP→HTTPS 리다이렉트는 Cloudflare 또는 Origin 중 한 곳에서만 수행
Nginx에서 리다이렉트 처리 예시(Origin에서만 처리할 때)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Cloudflare에서만 처리할 때는 Origin의 80 서버블록에서 무조건 301을 걸지 말고, 앱/정책에 맞게 최소한만 둡니다(특히 프록시 헤더 판단이 섞인 리다이렉트 규칙은 루프의 원인이 됩니다).
체크 포인트: X-Forwarded-Proto
Cloudflare를 거치면 Origin 입장에서는 요청이 HTTP처럼 보일 수 있습니다(구성에 따라). 앱이 이를 고려하지 않으면 https로 강제 리다이렉트를 반복할 수 있어요. Nginx 리버스 프록시를 쓰는 경우라면 보통 아래 헤더가 중요합니다.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
다만 Cloudflare → Origin 직결이고 앱이 직접 받는 구조라면, 앱 프레임워크의 “trusted proxy” 설정도 함께 확인해야 합니다(예: Laravel의 TrustedProxies, Express의 trust proxy 등).
5) HSTS/캐시 때문에 “고친 것 같은데 계속 이상할 때”
SSL/리다이렉트는 브라우저 캐시, HSTS 때문에 “서버는 고쳤는데 내 PC만 계속 문제”가 자주 생깁니다.
- Cloudflare에서 HSTS를 켰다면, 잘못된 설정을 한 번 배포한 뒤에는 브라우저가 강제로 https로만 접근합니다.
- 리다이렉트 규칙 수정 후에는 시크릿 모드로 테스트하거나, 다른 네트워크/기기에서 교차 확인하세요.
- Cloudflare 캐시(특히 페이지 규칙/캐시 규칙)를 쓰고 있다면, 변경 후 Purge cache가 도움이 될 때가 있습니다.
6) 변경 후 검증/재시작 절차(실수 줄이는 루틴)
SSL 관련 설정은 “적용했는지, 어떤 설정이 살아있는지”를 확인하는 루틴이 중요합니다. 아래 순서로 하면 삽질이 확 줄어듭니다.
- 1) 설정 문법 검사
- Nginx: nginx -t
- Apache: apachectl configtest (또는 httpd -t)
- 2) 서비스 재시작(또는 reload)
- systemd: systemctl reload nginx (가능하면 reload 우선)
- systemd: systemctl reload apache2 또는 systemctl reload httpd
- 3) 로컬에서 TLS 응답 확인
- curl -I https://example.com (응답 코드/Location 확인)
- curl -I http://example.com (301이 의도대로인지)
- 4) Cloudflare 경유/우회 둘 다 확인
- Cloudflare 경유: 일반 접속으로 테스트
- 우회 테스트(가능한 경우): hosts 파일 임시 지정 또는 Origin IP로 직접 접근(방화벽 정책에 주의)
특히 “Cloudflare 모드 변경 + Origin 인증서 교체 + 리다이렉트 수정”을 한 번에 같이 하면 원인 분리가 어려워집니다. 가능하면 한 번에 하나씩 바꾸고 curl로 즉시 확인하세요.
마무리
Cloudflare SSL 문제는 대개 SSL 모드(Full/Strict), Origin 인증서 체인, 리다이렉트 중복 세 가지에서 결정됩니다. 먼저 이 3가지를 순서대로 정리하면 대부분 빠르게 복구됩니다.
그래도 해결이 안 되면 “Cloudflare 경유 vs Origin 직결에서 어떤 차이가 나는지” 결과를 모아두면, 다음 단계(방화벽, TLS 정책, SNI/vhost 충돌)로 넘어갈 때 진단이 훨씬 쉬워집니다.