Cloudflare Flexible vs Origin Cert — 우리는 둘 다 써봤다
Cloudflare Flexible은 결제·API 서버에 쓰면 오리진 구간이 HTTP로 노출된다. HEDVION이 직접 겪은 리다이렉트 루프·PCI 리스크와 Origin Certificate 전환 기준·순서를 공유한다.
Flexible이 결제 팀에게 단순한 "설정 선택"이 아닌 이유
결제·정산을 직접 운영하는 팀에게 SSL 모드 선택은 보안 모범 사례 수준의 이야기가 아니다. Toss Payments, KG이니시스, NICE Pay 같은 국내 PG사들의 웹훅은 서버로 직접 HTTP POST를 날린다. 이 훅에는 주문 ID, 결제 금액, 결제 키가 담긴다. Flexible 모드에서는 Cloudflare가 이 요청을 오리진 서버에 전달할 때 평문 HTTP로 내려보낸다. Cloudflare 데이터센터와 오리진 서버 사이 구간이 암호화되지 않는다는 뜻이다.
같은 IDC 랙이나 VPC 안이라면 그나마 낫다. 하지만 별도 리전에 서버를 두거나, SaaS 형태로 서버가 분리된 구조라면 이 구간은 실질적인 노출 지점이 된다. 더 직접적인 문제는 PCI DSS다. 카드사 연동이나 빌링 자동화 서비스를 운영하는 팀은 PCI DSS Requirement 4.2.1—"카드 소지자 데이터를 공개 네트워크로 전송할 때 강력한 암호화를 사용해야 한다"—조건을 충족해야 한다. Flexible은 오리진 구간이 HTTP이므로 이 요건을 만족하지 못한다. 직접 카드 데이터를 다루지 않더라도 정산 자동화 API를 외부에 노출하거나 고객의 결제 이벤트를 처리하는 구조라면 잠재적 감사 리스크로 남는다.
리다이렉트 루프 — 우리가 40분을 날린 사고의 구조
기존 글에서도 언급했지만, 이 루프를 처음 만났을 때 원인 파악까지 약 40분이 걸렸다. 우리 팀이 쓰는 Node.js Express 서버에는 trust proxy 설정이 걸려 있었고, X-Forwarded-Proto: https 헤더가 없으면 HTTPS로 리다이렉트하는 미들웨어가 붙어 있었다. Cloudflare가 HTTP로 오리진에 요청을 내려보내니, 서버는 "이건 HTTP 요청이네, HTTPS로 보내야지"라고 302를 쏜다. Cloudflare는 그 리다이렉트를 받아 다시 HTTP로 오리진에 요청 — 무한 루프다.
단기 픽스는 미들웨어에서 X-Forwarded-Proto 헤더를 제대로 신뢰하도록 수정하는 것, 근본 해결은 Origin Certificate로 전환해 오리진 구간도 HTTPS로 만드는 것이었다. 만약 이 루프를 결제 웹훅 처리 서버에서 만났다면? PG사의 웹훅 재시도 정책에 따라 수 분 안에 재전송을 포기하고 결제 완료 처리가 누락되는 상황이 된다. "웹훅 루프로 5분간 결제 승인 처리가 안 됐다"는 건 단순 설정 실수가 아니라 운영 장애다. 이 가능성 하나만으로도 API 서버에 Flexible을 유지하는 근거가 사라진다.
Origin Certificate 적용 — 놓치기 쉬운 순서와 포인트
Origin Certificate 발급 자체는 간단하다. Cloudflare 대시보드 → SSL/TLS → Origin Server → Create Certificate. RSA 2048이나 ECDSA 256 선택 후 유효기간을 최대 15년으로 설정하면 된다. 발급된 .pem과 .key 파일을 서버에 올리고 nginx에 ssl_certificate / ssl_certificate_key 경로만 지정하면 끝. Let's Encrypt의 certbot처럼 웹루트 접근 권한 문제도 없고, DNS 챌린지 설정도 필요 없다. 90일마다 갱신을 걱정할 필요도 없다.
놓치기 쉬운 포인트가 하나 있다. Cloudflare SSL/TLS 모드를 반드시 Full(Strict)로 바꿔야 한다. Origin Certificate를 서버에 올려도 Cloudflare 설정이 Flexible로 남아 있으면 오리진으로는 여전히 HTTP 요청이 내려온다. Full(Strict)로 바꿔야 Cloudflare가 오리진에 HTTPS로 붙는다. 우리 팀이 처음 Origin Cert를 적용할 때 이 설정을 빠뜨려서 "인증서를 올렸는데 왜 여전히 HTTP지?"라고 15분을 허비했다. 443 포트가 열려 있는지도 확인해야 한다. 80만 열어둔 채로 Full(Strict)로 전환하면 502 Bad Gateway를 만나게 된다.
HEDVION 팀의 서비스 성격별 선택 기준
지금 우리 팀은 서비스를 세 가지로 분류해 SSL 정책을 달리 가져간다.
공개 정적 사이트·마케팅 페이지: Flexible 유지. CDN 캐시가 대부분의 요청을 처리하고 민감한 데이터 전송이 없다. Cloudflare Pages로 올리는 것도 검토 중이라 인증서에 투자할 이유가 없다.
API 서버·정산 자동화 엔드포인트: 무조건 Origin Certificate + Full(Strict). 토큰, 정산 금액, 고객 식별자가 오가는 경로는 오리진 구간도 암호화해야 한다. 서버 프로비저닝 스크립트에 Origin Cert 설치 단계를 포함시켜뒀다. 새 서버를 만들 때 스크립트 한 번이면 인증서가 자리를 잡는다.
내부 관리 도구·어드민 패널: Origin Certificate 적용. 트래픽이 많지 않아 설정 부담이 없고, 관리자 세션 토큰이 오가는 경로인 만큼 Flexible은 선택지에서 제외한다.
한 가지 추가 고려사항: Cloudflare Authenticated Origin Pull을 같이 걸면 Cloudflare를 우회한 직접 오리진 접근을 차단할 수 있다. Origin Certificate만 쓰면 서버 IP를 아는 사람이 직접 443으로 붙었을 때 "인증서 신뢰 불가" 경고가 뜨긴 하지만 연결 자체는 된다. Authenticated Origin Pull까지 설정하면 Cloudflare 클라이언트 인증서 없이는 오리진이 연결을 거부한다. 결제 API 서버라면 이 조합까지 가는 것을 권장한다.
지금 바로 점검할 다섯 가지
결제 또는 API 서버를 Cloudflare 뒤에 두고 있다면 지금 확인해야 한다.
1. SSL/TLS 모드 확인: Cloudflare 대시보드 → SSL/TLS → Overview. "Flexible"이면 오리진 구간은 HTTP다. API 서버가 Flexible 뒤에 있으면 즉시 전환 계획을 잡아라.
2. 오리진 443 포트 확인: curl -v https://[서버IP]로 직접 접근해본다. 연결이 안 되면 Full(Strict) 전환 전에 먼저 인증서와 포트를 세팅해야 한다.
3. 웹훅 로그에 302 응답 없는지 확인: PG사 웹훅 수신 로그에 302가 기록되어 있으면 루프 가능성이 있다.
4. 전환 순서 지키기: 인증서를 먼저 서버에 올리고 443이 정상 응답하는 것을 확인한 다음에 Cloudflare 모드를 바꿔라. 순서가 바뀌면 전환 직후 502를 유발한다.
5. Authenticated Origin Pull 추가 검토: 결제 API 서버라면 Origin Cert만으로는 부족하다. Cloudflare 외 직접 접근을 mTLS로 차단하는 것을 고려해라.
Flexible은 편하다. 하지만 결제·정산 서버에서 편함의 대가가 데이터 노출이나 웹훅 장애라면, 그 10분의 설정 절약이 나중에 훨씬 비싼 값을 치른다.
— by mings
* 위 링크는 인프런 affiliate 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
* 위 추천 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.