Knowledge · 웹 보안

Cloudflare에서 웹서비스 초기 보안 설정하기

공개 파일 범위·HTTPS·보안 헤더를 배포 전에 확인하는 방법

새 웹서비스를 Cloudflare에 연결할 때 정적 파일 공개 범위, Git 빌드 명령, HTTPS 강제, 응답 헤더와 Preview를 확인하는 초기 설정 가이드.

새로운 웹서비스를 만들면 화면과 기능을 먼저 확인하게 된다. 하지만 서비스를 공개하기 전에 어떤 파일이 외부에 제공되는지, HTTP 요청이 안전하게 전환되는지, 기본 응답 헤더가 적용되는지 함께 살펴봐야 한다.

Cloudflare에서 여러 웹서비스를 운영한다면 프로젝트마다 설정을 반복하기보다, 배포 구조와 공통 보안 정책을 처음부터 정리하는 편이 편리하다. 여기서는 새 프로젝트를 연결할 때 다시 확인할 핵심 항목만 정리한다.

1. 웹 공개 디렉터리를 먼저 분리한다

GitHub 저장소가 비공개라고 해서 Cloudflare에 배포된 정적 파일까지 비공개가 되는 것은 아니다. 특히 정적 자산 경로를 저장소 루트 전체로 지정하면, 의도하지 않은 문서나 설정 파일이 배포 대상에 포함될 수 있다.

예를 들어 다음과 같은 설정은 주의가 필요하다.

{
  "assets": {
    "directory": "."
  }
}

가능하면 HTML·CSS·JavaScript·이미지 등 실제 공개할 파일만 모아 public/이나 dist/ 같은 전용 디렉터리로 분리한다.

{
  "assets": {
    "directory": "./public"
  }
}

핵심은 폴더 이름이 아니라 공개 대상을 제한하는 빌드 과정이다. 필요한 파일만 복사하거나 생성하고, 내부 문서·비밀정보·개발용 설정 파일은 포함하지 않아야 한다.

.gitignore는 Git 추적을 제어할 뿐, 배포된 웹사이트에서 파일을 숨겨주는 보안 기능은 아니다.

Cloudflare Git 빌드 명령 확인

공개 디렉터리를 만들도록 코드를 작성했다면 Cloudflare의 빌드 설정에서도 그 작업을 실행해야 한다. Node.js와 Wrangler를 사용하는 프로젝트라면 다음과 같은 구성을 참고할 수 있다.

Build command  : npm run build
Deploy command : npx wrangler deploy

package.json의 build 스크립트가 실제 공개 자산을 준비하고, wrangler.jsonc의 assets.directory가 완성된 디렉터리를 가리키는지 확인한다. 프레임워크와 배포 방식에 따라 명령은 달라질 수 있다.

위 Deploy command는 Cloudflare의 Git 연동 자동 배포 환경에서 사용하는 설정 예시다. 로컬에서 직접 배포하라는 뜻은 아니다. ONSEMO에서는 로컬 검증 후 GitHub에 push하고 Cloudflare의 Git 연동이 배포를 수행하도록 한다.

2. HTTP 접속을 HTTPS로 전환한다

사이트가 HTTPS로 열리는 것과 HTTP 접속이 자동으로 HTTPS로 바뀌는 것은 별개의 문제다.

Cloudflare에서는 다음 경로에서 설정한다.

  1. Cloudflare에서 해당 도메인 영역을 선택한다.
  2. SSL/TLS → Edge Certificates로 이동한다.
  3. Always Use HTTPS를 켠다.
  4. HTTP로 접속했을 때 HTTPS로 리디렉션되는지 확인한다.

이 기능을 켜기 전에 대상 호스트의 HTTPS 인증서와 기존 리디렉션 설정이 정상인지 확인해야 한다. 설정은 해당 Cloudflare 영역에서 프록시를 통해 처리되는 요청을 기준으로 적용되므로, 별도 호스트나 DNS only 대상까지 동일하게 보호한다고 가정해서는 안 된다.

참고: Cloudflare — Always Use HTTPS

3. 기본 보안 헤더를 공통으로 설정한다

HTTPS를 강제하더라도 브라우저의 콘텐츠 해석 방식과 참조 URL 전달 정책은 별도로 관리해야 한다. 초기 설정에서는 다음 두 헤더를 확인할 수 있다.

헤더권장 시작 값역할
X-Content-Type-Optionsnosniff콘텐츠 유형 추측 제한
Referrer-Policystrict-origin-when-cross-origin다른 출처로 전달하는 참조 URL 정보 제한

Cloudflare 대시보드에서 다음 메뉴로 이동한다.

Rules → Overview → Create rule → Response Header Transform Rule

규칙의 적용 대상을 정하고, Modify response header에서 Set static으로 각 이름과 값을 입력한다. 두 번째 헤더는 Set new header를 이용해 추가할 수 있다.

여러 하위 도메인에 같은 정책을 적용하려면 All incoming requests를 고려할 수 있다. 다만 이는 선택한 Cloudflare 영역의 적용 대상 요청 전체를 의미하며 모든 Cloudflare 프로젝트나 workers.dev 호스트에 자동 적용되는 것은 아니다. 기존 응답 헤더를 덮어쓸 수 있으므로 서비스별 예외가 필요한지도 확인한다.

참고: Cloudflare — Response Header Transform Rules

4. 설정 완료보다 실제 응답 검증이 중요하다

대시보드에서 설정을 저장했다고 해서 브라우저에 즉시 기대한 응답이 전달되는 것은 아니다. 주요 경로를 대상으로 읽기 전용 요청을 보내 결과를 확인한다.

# HTTP 요청이 HTTPS로 이동하는지 확인
curl -sS -D - -o /dev/null "http://example.com/"

# HTTPS 응답 헤더 확인
curl -sS -D - -o /dev/null "https://example.com/"

HTTP에서는 301 또는 다른 적절한 리디렉션 상태와 HTTPS Location을 확인한다. HTTPS에서는 X-Content-Type-Options, Referrer-Policy가 기대한 값인지 살펴본다.

메인 HTML 외에도 정적 파일, 공개 API, 다운로드 경로 등 서비스의 대표 URL을 확인한다. 특히 기존 캐시 정책, CORS, 인증 동작, 파일 다운로드가 새 규칙 때문에 변하지 않았는지 비교한다.

정적 파일 공개 범위도 별도로 점검한다. 내부 문서나 설정 파일의 대표 경로가 원문을 반환하지 않는지 확인하되, 몇 개의 경로 검사만으로 전체 파일이 안전하다고 단정해서는 안 된다.

5. 추가 보안은 서비스 특성에 맞게 적용한다

아래 항목은 초기 설정 과정에서 검토하되 모든 서비스에 동일한 값으로 즉시 적용할 필요는 없다.

  • HSTS: HTTPS 전환이 안정적이고 모든 관련 하위 도메인을 검토한 다음 적용한다. 특히 includeSubDomains와 preload는 신중하게 결정한다.
  • CSP: 서비스가 사용하는 스크립트·스타일·외부 자원을 먼저 파악한다. 기능 중단을 피하려면 Report-Only 방식으로 검증하는 방법도 있다.
  • Preview: Git 작업 브랜치의 Preview 주소가 외부에 열려 있는지, 초안과 운영 데이터가 노출될 가능성은 없는지 확인한다.
  • 별도 호스트: Cloudflare 사용자 정의 도메인과 기본 제공 workers.dev 주소는 정책 적용 범위가 다를 수 있다. 기존 클라이언트가 참조하는 주소를 변경할 때는 호환성도 고려한다.

참고: Cloudflare — HSTS

새 프로젝트를 배포하기 전 확인할 것

항목확인 질문
공개 파일저장소 전체가 아닌 공개용 폴더만 배포하는가?
빌드Cloudflare가 올바른 빌드 명령을 실행하는가?
HTTPSHTTP 접속이 HTTPS로 정상 전환되는가?
응답 헤더필요한 공통 보안 헤더가 실제 응답에 나타나는가?
기능 유지API·캐시·다운로드 등 기존 기능이 정상인가?
Preview작업용 주소와 초안·운영 데이터의 공개 범위를 확인했는가?

웹서비스를 처음 설정할 때 이 항목들을 함께 확인하면, 운영을 시작한 뒤 개별 프로젝트마다 같은 문제를 반복해서 수정할 가능성을 줄일 수 있다. 보안 설정은 적용 자체보다 공개 범위를 이해하고 실제 응답을 확인하는 과정까지 포함해야 한다.

공식 참고자료