홈랩에 올린 서비스를 밖에서 접속하려면 보통 공유기 포트포워딩 + DDNS를 씁니다. 그런데 저는 공유기에 포트를 단 하나도 열지 않고 이 블로그(blog.pswq.net)를 외부에 공개하고 있습니다. 방법은 Cloudflare Tunnel입니다. 실제로 제 홈랩을 이걸로 운영하면서 겪은 구성과 장단점을 그대로 공개합니다.
1. 왜 포트포워딩을 버렸나
전통적인 방식(포트포워딩 + DDNS)은 홈랩에서 문제가 많습니다.
고정 IP가 없다 — 가정용 회선은 IP가 바뀌어서 DDNS에 의존해야 함
포트를 여는 순간 공격 표면 — 열린 80/443은 전 세계 스캐너의 표적
내 공인 IP가 노출 — 위치·회선이 드러남
일부 ISP는 80/443 인바운드를 아예 막음
Cloudflare Tunnel은 이걸 근본적으로 뒤집습니다. 홈랩에서 Cloudflare로 바깥으로 나가는(outbound) 연결만 맺고, 외부 요청은 그 연결을 타고 들어옵니다. 즉 공유기에 열 포트가 0개입니다.
2. 동작 원리 한 장 요약
방문자 → Cloudflare 엣지(HTTPS) → [터널] → cloudflared(홈랩) → 내부 서비스
↑ 홈랩이 먼저 outbound로 연결해 둠
핵심은 인바운드 포트가 필요 없다는 점입니다. 홈랩의 cloudflared 데몬이 Cloudflare에 먼저 붙어 있고, 외부 트래픽은 그 통로로만 들어옵니다. HTTPS 인증서도 Cloudflare가 자동으로 처리해서 내가 인증서를 관리할 필요가 없습니다.
3. 실제 구성 — 토큰(원격 관리형) 방식
Cloudflare Tunnel은 두 가지로 설정할 수 있습니다. 저는 토큰 방식을 씁니다.
방식
설정 위치
특징
토큰(원격 관리형)
Cloudflare Zero Trust 대시보드
웹에서 라우팅 관리, 서버엔 토큰만
로컬 config.yml
서버의 설정 파일
파일로 버전관리, GitOps에 유리
홈랩 서버에서 데몬을 이렇게 띄웁니다(토큰은 절대 공개 금지, 여기선 가림).
cloudflared --no-autoupdate tunnel run --token <터널토큰>
--no-autoupdate는 데몬이 멋대로 자동 업데이트해서 예기치 않게 재시작하는 걸 막으려고 붙였습니다(홈랩은 안정성이 우선). 서버 쪽 설정은 이게 전부고, 나머지 라우팅은 전부 대시보드에서 합니다.
4. 공개 호스트네임 연결
Zero Trust 대시보드 → 터널 → Public Hostname에서 도메인과 내부 서비스를 매핑합니다.
항목
값(예)
Subdomain / Domain
blog . (내 도메인)
Service Type
HTTP
URL
http://192.168.x.x:<내부포트>
여기서 URL은 홈랩 내부에서 본 서비스 주소입니다. 즉 방문자는 HTTPS로 blog.내도메인에 접속하지만, 터널 반대편에선 평범한 사내 HTTP 서비스로 전달됩니다. 내부 서비스는 HTTPS를 몰라도 되고, 공인 IP도 드러나지 않습니다. 저는 이 방식으로 WordPress 블로그를 외부에 공개하고 있습니다.
5. 직접 써 보고 느낀 장단점
좋은 점
포트 개방 0 — 공유기 설정을 건드릴 필요가 없고 공격 표면이 사라짐
공인 IP 숨김 — 방문자는 Cloudflare만 봄
HTTPS 자동 — 인증서 갱신을 신경 쓸 필요 없음
무료 — 개인 홈랩 규모에선 비용이 들지 않음
주의할 점
토큰 유출은 치명적 — 토큰이 곧 터널 권한이라, 프로세스 인자·로그·스크린샷에 노출되지 않게 관리해야 함
Cloudflare 의존 — 트래픽이 Cloudflare를 경유하므로 서비스 장애의 영향을 받음
관리자 페이지는 반드시 보호 — 외부 공개 시 Cloudflare Access로 접근 제어를 걸어 두는 걸 권장(로그인/관리 경로)
6. 결론
홈랩 서비스를 밖에 내놓을 때, 저는 이제 포트포워딩으로 돌아갈 이유를 못 느낍니다. 포트 0개, IP 숨김, 무료 HTTPS라는 조합은 개인 홈랩에 특히 잘 맞습니다. 단, 토큰 관리와 관리자 경로 보호만 확실히 하면 됩니다. 홈랩 서비스를 외부에 공개할 계획이라면 Cloudflare Tunnel부터 검토해 보시길 권합니다.
Cloudflare Workers AI 활용 이야기를 해보려고 합니다. 요즘 AI 기능 하나 붙이려 해도 어디에 올릴지부터 고민되시죠. 중앙 리전(region, 클라우드 지역)에 모델 서버를 두면 구조는 익숙한데, 지연 시간(latency, 응답 지연)이나 운영 복잡도가 은근히 발목을 잡거든요. 저도 홈랩이랑 사내 테스트 환경에서 이것저것 붙여보다가, “이걸 꼭 무거운 GPU 서버로만 풀어야 하나?” 싶은 순간이 많았습니다. 처음엔 반신반의했는데, Cloudflare Workers AI를 같이 써보니까 엣지 AI(edge AI, 사용자와 가까운 위치에서 추론하는 방식) 서비스의 방향이 꽤 선명해지더라고요.
특히 Cloudflare Workers AI 활용 포인트는 단순합니다. 기존 Workers(워커스, 서버리스 런타임) 위에서 요청을 받고, AI 추론을 붙이고, 필요하면 KV(Key-Value 저장소)나 R2(Object Storage, 오브젝트 스토리지) 같은 주변 서비스를 연결해서 바로 서비스 형태로 만들 수 있다는 점입니다. 서버를 직접 띄우고 헬스체크하고 오토스케일링 붙이는 부담이 줄어드니까, 작은 팀이나 1인 개발자에게 꽤 현실적인 선택지였어요.
이번 글에서는 제가 직접 구성해본 흐름을 기준으로, 엣지 AI와 서버리스 AI를 어떻게 조합했는지, 그리고 실제로 어디서 삽질했는지까지 정리해보겠습니다. 너무 화려한 데모보다, “이 정도면 실서비스 PoC(Proof of Concept, 개념 검증)로는 충분하겠다” 싶은 수준에 맞춰 설명드릴게요.
사용자 요청이 Cloudflare 엣지로 들어와 Workers와 AI 추론, 저장소 연동으로 이어지는 전체 구조 예시입니다.
Cloudflare Workers AI란 무엇인가
쉽게 말해, Cloudflare 네트워크 위에서 AI 추론을 호출하는 방식입니다. 우리가 직접 AI 모델 배포 환경을 일일이 운영하기보다, Worker 코드 안에서 AI 작업을 요청하고 결과를 응답으로 돌려주는 식이죠. 여기서 중요한 건 “엣지에서 실행되는 애플리케이션 로직”과 “AI 추론 호출”이 한 흐름으로 이어진다는 점입니다.
처음 접하면 “그럼 모든 모델이 로컬처럼 바로 도는 건가?” 하고 헷갈릴 수 있어요. 저도 처음엔 그랬거든요. 실제로 써보니까 핵심은 이렇습니다.
Workers: HTTP 요청을 받고 라우팅, 인증, 전처리, 후처리를 담당합니다.
Workers AI: 텍스트 생성, 분류, 임베딩(embedding, 의미 벡터화) 같은 AI 작업을 호출합니다.
엣지 AI: 사용자와 가까운 네트워크 지점에서 빠르게 응답 체감을 만드는 접근입니다.
서버리스 AI: GPU 서버 운영보다 코드 중심으로 기능을 붙이는 방식입니다.
이 조합이 왜 좋았냐면, 서비스 초기에 필요한 건 대개 “정답률 0.1% 더 높은 모델”보다도 빨리 붙고, 운영이 단순하고, 비용 구조를 예측하기 쉬운 아키텍처인 경우가 많기 때문입니다. 특히 문의 분류, 간단한 요약, 입력 정제, 임베딩 기반 검색 전처리 같은 작업은 중앙 집중형 대형 백엔드보다 엣지 쪽이 훨씬 손에 잘 붙는 경우가 있더라고요.
어떤 서비스에 잘 맞는가: 엣지 AI와 서버리스 AI 활용 기준
모든 AI 워크로드가 여기에 맞는 건 아닙니다. 이게 중요한 포인트예요. 작게 쪼갤 수 있는 추론 작업에 특히 잘 맞습니다. 제가 테스트하면서 잘 맞는다고 느낀 케이스는 아래와 같았습니다.
사용자 입력 유해성 검사나 형식 검증 같은 프런트 관문 처리
짧은 텍스트 요약이나 카테고리 분류
검색 전 임베딩 생성과 간단한 추천 로직
챗봇 앞단의 프롬프트 가공 및 응답 후처리
파일 업로드 후 메타데이터 추출 같은 이벤트성 작업
반대로 긴 세션을 유지해야 하거나, 아주 무거운 후처리 파이프라인이 붙는 작업은 별도 백엔드와 역할을 나누는 편이 낫습니다. 저도 처음엔 모든 걸 Worker 하나에 넣어보려다가 금방 정신 차렸습니다. 서비스 경계가 흐려지면 디버깅이 정말 힘들어지거든요.
구분
Cloudflare Workers AI 활용
전통적 모델 서버 운영
배포 방식
코드 중심의 빠른 배포
서버/컨테이너 운영 필요
운영 부담
상대적으로 낮음
스케일링, 패치, 모니터링 직접 관리
적합한 작업
짧은 추론, 엣지 응답 최적화
장시간 처리, 복잡한 파이프라인
개발 속도
PoC에 유리
초기 구축 시간 길어짐
실전 구현: 가장 단순한 Workers AI API 만들기
이제 실제로 붙여보겠습니다. 예시는 “사용자 문의를 요약하고 카테고리 라벨을 붙여주는 API”로 잡아볼게요. 이 패턴은 생각보다 응용 범위가 넓더라고요.
1. 프로젝트 생성
Cloudflare에서는 보통 Wrangler(랭글러, CLI 도구)를 사용해 Worker 프로젝트를 만듭니다.
npm create cloudflare@latest workers-ai-demo
cd workers-ai-demo
npm install
생성 과정에서 Worker 템플릿을 선택하고, JavaScript 또는 TypeScript 기반으로 시작하면 됩니다. 저는 이런 종류는 TypeScript가 조금 더 편하더라고요. 입력과 출력 스키마를 잡기가 수월해서요.
2. Worker 코드 작성
핵심은 요청 본문을 받고, AI 바인딩(binding, 서비스 연결 객체)을 통해 추론을 호출한 뒤, 결과를 JSON으로 반환하는 구조입니다.
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const body = await request.json();
const text = body.text;
if (!text || typeof text !== "string") {
return Response.json({ error: "text is required" }, { status: 400 });
}
const prompt = [
"You are a support triage assistant.",
"Summarize the user message in Korean in one sentence.",
"Then assign one category among billing, technical, account, other.",
"Return JSON with summary and category.",
"User message:",
text
].join("\n");
const result = await env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt
});
return Response.json({
input: text,
result
});
}
};
여기서 모델 식별자는 실제 Cloudflare에서 제공하는 카탈로그 기준으로 맞춰야 합니다. 글을 읽는 시점에 사용 가능한 모델 목록은 바뀔 수 있으니, 이 부분은 공식 문서를 한 번 확인하셔야 합니다. 저는 예전에도 이런 부분 대충 외워서 넣었다가 바로 에러 봤습니다. 이런 건 꼭 현재 콘솔 기준으로 맞추셔야 해요.
HTTP 요청이 Worker 코드로 들어오고, AI 바인딩을 통해 추론이 호출되는 내부 흐름을 정리한 이미지입니다.
3. 설정 파일 확인
설정 파일에서는 Worker 이름, 진입점, 호환성 날짜 같은 기본값과 함께 AI 바인딩을 선언합니다.
name = "workers-ai-demo"
main = "src/index.js"
compatibility_date = "2024-05-01"
[ai]
binding = "AI"
여기서 binding 이름이 코드의 env.AI와 일치해야 합니다. 별거 아닌데, 이거 안 맞으면 “왜 env에 아무것도 없지?” 하면서 시간 정말 많이 잡아먹습니다. 저도 한 번 오타로 한참 돌았네요.
4. 로컬 개발과 배포
npx wrangler dev
npx wrangler deploy
배포 후에는 발급된 Worker URL로 POST 요청을 보내 테스트하면 됩니다.
curl -X POST https://your-worker.your-subdomain.workers.dev \
-H "Content-Type: application/json" \
-d '{"text":"로그인이 자꾸 풀리고 결제 영수증도 확인이 안 됩니다."}'
이 단계에서 드디어 첫 응답이 오면 정말 기분이 좋습니다. 드디어 됐다! 싶은 순간이 있어요. 사실 구조 자체는 단순한데, AI 기능이 바로 붙는다는 체감이 꽤 큽니다.
실서비스 형태로 확장하기: 캐시, 저장소, 검증 로직
단순 데모에서 한 단계만 올라가도 필요한 게 생깁니다. 예를 들어 같은 입력이 반복되면 결과를 캐시(cache, 재사용 저장)하고 싶고, 요청 로그는 저장하고 싶고, 프롬프트 인젝션(prompt injection, 입력을 통한 지시 왜곡)도 어느 정도 방어하고 싶어지죠.
제가 실제로 써보니까 아래 3가지는 거의 필수에 가깝더라고요.
입력 검증: 너무 긴 본문, 빈 문자열, 예상 외 필드 차단
응답 캐시: 동일 입력 반복 호출 방지
로그 저장: 어떤 입력에서 어떤 결과가 나왔는지 추적
예를 들어 요청 해시(hash, 고정 길이 요약값)를 키로 써서 KV에 저장해두면 재호출을 줄일 수 있습니다.
async function sha256(text) {
const data = new TextEncoder().encode(text);
const digest = await crypto.subtle.digest("SHA-256", data);
return Array.from(new Uint8Array(digest))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
export default {
async fetch(request, env) {
const body = await request.json();
const text = body.text?.trim();
if (!text) {
return Response.json({ error: "empty text" }, { status: 400 });
}
const cacheKey = await sha256(text);
const cached = await env.RESULTS_KV.get(cacheKey, "json");
if (cached) {
return Response.json({ source: "cache", data: cached });
}
const result = await env.AI.run("@cf/meta/llama-3-8b-instruct", {
prompt: "Summarize in Korean: " + text
});
await env.RESULTS_KV.put(cacheKey, JSON.stringify(result), {
expirationTtl: 3600
});
return Response.json({ source: "ai", data: result });
}
};
이렇게만 해도 체감이 확 달라집니다. 특히 짧은 문의 요약이나 반복 질의가 많은 내부 도구에서는요. Cloudflare Workers AI 활용 포인트가 여기서 또 살아납니다. AI 자체보다도, 그 앞뒤의 경량 로직을 엣지에서 같이 처리하니까 전체 구성이 매끈해져요.
⚠️ 트러블슈팅: 제가 실제로 막혔던 지점들
이 섹션은 좀 현실적으로 가보겠습니다. 멋진 성공담보다 이런 게 더 도움 되더라고요.
1. 바인딩 이름 불일치
아까 잠깐 언급했지만, 설정의 AI 바인딩과 코드의 환경 변수 이름이 다르면 바로 실패합니다. 에러 메시지가 친절한 편일 때도 있지만, 처음 보면 감이 안 올 수 있어요.
증상: env.AI가 비어 있거나 호출 실패
원인: 설정 파일의 binding 이름과 코드 불일치
해결: 설정 파일과 코드 이름을 동일하게 맞추기
2. 응답 포맷이 들쭉날쭉함
생성형 모델은 항상 예쁘게 JSON을 주지 않습니다. “JSON으로 줘”라고 했는데 설명까지 붙여주는 경우도 있거든요. 저도 처음엔 파싱 로직을 믿고 갔다가 깨졌습니다.
증상: JSON 파싱 실패
원인: 모델 응답이 순수 JSON이 아님
해결: 출력 형식을 더 엄격하게 지시하거나, 후처리 파서를 둠
여기서는 가능하면 모델에게 자유 서술을 덜 주고, 출력 스키마를 명확히 제한하는 쪽이 낫습니다.
3. 무거운 워크로드를 한 번에 몰아넣음
처음엔 이게 만능처럼 보여서, 요약도 하고 분류도 하고 벡터도 만들고 로그도 남기고 알림도 보내고 한 번에 다 넣고 싶어집니다. 근데 여기서 구조가 금방 꼬입니다.
증상: 디버깅 난이도 상승, 응답 지연 증가
원인: 하나의 Worker에 역할 과다 집중
해결: 전처리 API, 추론 API, 비동기 저장 작업을 분리
이건 인프라 쪽에서 흔히 하는 실수랑 비슷합니다. 처음엔 단순해 보여도 책임 분리를 안 해두면 나중에 훨씬 더 힘들어요.
4. 모델 선택보다 프롬프트 설계가 더 중요했던 경우
모델만 바꾸면 해결될 줄 알았는데, 실제로는 프롬프트(prompt, 모델에게 주는 지시문) 설계가 더 큰 영향을 준 경우가 많았습니다. 특히 분류 작업은 라벨 정의를 명확히 안 해두면 결과가 흔들리더라고요. 혹시 이런 경험 있으신가요? 모델 탓만 하다가 결국 입력 문장 설계부터 다시 보는 경우요.
바인딩 오류, 응답 포맷 문제, 역할 과다 집중 같은 흔한 장애 포인트를 시각적으로 정리한 이미지입니다.
검증과 결과: 무엇이 좋아졌나
완성 후에는 꼭 확인해야 합니다. 그냥 “응답 온다”에서 끝내면 안 되거든요. 저는 아래 기준으로 검증했습니다.
기능 검증: 입력별로 요약과 분류가 의도대로 나오는지
지연 시간 확인: 중앙 백엔드 경유 대비 체감 응답이 나아졌는지
재현성 확인: 동일 입력에서 품질이 과도하게 흔들리지 않는지
운영성 확인: 로그 추적과 에러 원인 파악이 쉬운지
여기서 중요한 건 과한 기대를 버리는 겁니다. 이 구조의 장점은 최고 성능 경쟁보다 빠른 서비스화와 운영 단순화에 있습니다. 실제로 써보니까, 고객 문의 분류기나 내부 자동화 도구처럼 “완벽한 창의성”보다 “일관된 처리”가 중요한 곳에 특히 잘 맞더라고요.
curl -X POST https://your-worker.your-subdomain.workers.dev \
-H "Content-Type: application/json" \
-d '{"text":"회원 탈퇴 후 재가입이 안 되고 인증 메일도 오지 않습니다."}'
{
"source": "ai",
"data": {
"summary": "회원 탈퇴 이후 재가입과 인증 메일 수신에 문제가 있는 상태입니다.",
"category": "account"
}
}
이 정도 흐름만 안정적으로 나오면 PoC 단계에서는 꽤 괜찮습니다. 특히 AI 모델 배포를 직접 무겁게 하지 않고도 사용자-facing API를 만들 수 있다는 점이 정말 좋았습니다. 물론 대규모 서비스로 갈수록 관측성(observability, 관찰 가능성), 비용 추적, 프롬프트 버전 관리가 더 중요해지겠지만요.
API 호출 결과, 캐시 적중 여부, 응답 흐름 확인 같은 검증 포인트를 한눈에 볼 수 있는 예시 이미지입니다.
Cloudflare Workers AI 활용 시 운영 팁
마지막으로, 제가 정리해둔 운영 팁 몇 가지를 공유드릴게요. 이런 건 문서 한 줄보다 실제 운영에서 더 크게 다가오더라고요.
프롬프트 버전 관리: 코드와 같이 관리해야 롤백이 쉽습니다.
입력 길이 제한: 무제한 입력을 열어두면 품질과 비용이 같이 흔들립니다.
캐시 전략 분리: 요약, 분류, 임베딩은 캐시 정책이 달라야 합니다.
장애 대비: AI 호출 실패 시 기본 응답 또는 재시도 정책을 준비합니다.
비동기 분리: 저장, 알림, 통계 적재는 가능하면 본 응답 경로에서 떼어냅니다.
그리고 하나 더. Cloudflare Workers AI 활용은 만능 해법이 아니라, 서비스의 앞단을 영리하게 가볍게 만드는 선택지라고 보는 게 맞습니다. 이 관점으로 접근하면 훨씬 덜 실망하고, 훨씬 더 잘 쓰게 됩니다.
정리: 엣지 AI 서비스는 작게 시작하는 게 맞습니다
오늘 정리한 내용을 한 문장으로 줄이면 이겁니다. 엣지 AI와 서버리스 AI는 작은 기능을 빠르게 서비스화할 때 강력하다. 저도 처음엔 이게 뭔가 싶었는데, 직접 붙여보니까 “아, 이건 대형 모델 인프라를 대체한다기보다 앞단 자동화를 엄청 빠르게 만든다”는 쪽에 가깝더라고요.
만약 지금 AI 기능을 제품에 붙이려는데 인프라 부담이 걱정되신다면, 문의 분류기나 요약 API처럼 작고 분명한 문제부터 시작해보시는 걸 권합니다. 거기서 검증이 되면 검색, 추천, 간단한 어시스턴트 기능으로 확장하면 되고요. 다음 글에서는 Workers와 KV, R2를 같이 써서 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 비슷한 흐름을 어떻게 가볍게 실험할 수 있는지 다뤄볼 예정입니다. 이전 글에서 다뤘던 엣지 캐시 전략과도 연결해서 보시면 더 이해가 잘 되실 거예요.
전통적 모델 서버 방식과 엣지 AI 방식의 차이, 적용하기 좋은 워크로드를 요약한 인포그래픽입니다.
자주 묻는 질문
Q1. Cloudflare Workers AI 활용은 어떤 팀에 가장 잘 맞나요?
A. 작은 팀, 빠른 PoC가 필요한 팀, 그리고 AI 모델 운영보다 서비스 통합이 더 급한 팀에 잘 맞습니다.
Q2. 서버리스 AI만으로 모든 서비스를 구성할 수 있나요?
A. 아닙니다. 장시간 작업이나 복잡한 파이프라인은 별도 백엔드와 역할을 나누는 편이 더 안정적입니다.
Q3. AI 모델 배포를 완전히 대체하나요?
A. 완전 대체라기보다, 특정 구간에서는 훨씬 더 가볍고 빠른 대안이 됩니다. 특히 요청 전처리, 요약, 분류 같은 작업에서 장점이 큽니다.
Cloudflare WAF vs AWS WAF를 비교해 달라는 요청을 받으면, 저는 기능표부터 꺼내지 않습니다. 실무에서는 웹 방화벽 자체보다도 장애가 났을 때 얼마나 빨리 원인을 좁히고, 우회하고, 복구하느냐가 더 중요하거든요. 저도 초반에는 “둘 다 룰만 잘 넣으면 되는 거 아닌가?” 싶었는데, 운영을 해보면 보는 지점도 다르고 디버깅 방식도 꽤 다르더라고요. 특히 보안 장애는 애플리케이션 오류처럼 로그 한 줄로 바로 드러나지 않아서 초기에 헤매기 쉽습니다.
이번 글은 Cloudflare WAF vs AWS WAF를 단순 스펙 비교가 아니라, 보안 장애와 트러블슈팅 관점에서 정리한 글입니다. 정상 사용자가 막혔을 때 어디부터 볼지, 403이 떴을 때 WAF 문제인지 앱 문제인지 어떻게 가를지, Cloudflare 앞단과 AWS 원본 구성이 함께 있을 때 무엇을 먼저 확인해야 하는지 실무 기준으로 풀어보겠습니다.
Cloudflare 엣지와 AWS 내부 구간에서 WAF가 어떻게 배치되는지 한눈에 보여주는 아키텍처 이미지가 들어갈 자리입니다.
1. 왜 Cloudflare WAF vs AWS WAF 비교가 실무에서 중요한가
두 제품 모두 HTTP 요청을 검사하고 차단하지만, 트래픽을 관찰하는 위치와 운영자가 원인을 추적하는 방식이 다릅니다. Cloudflare WAF는 보통 사용자 요청이 원본 서버에 도달하기 전에 Cloudflare 엣지에서 먼저 평가합니다. AWS WAF는 CloudFront, Application Load Balancer(ALB), API Gateway 같은 AWS 보호 대상 리소스에 연결해 정책을 적용하죠.
그래서 같은 403 응답이어도 의미가 완전히 같지는 않습니다.
Cloudflare WAF: 원본까지 요청이 가지 않았을 가능성이 큽니다.
AWS WAF: AWS 리소스 경계까지는 도달했지만 연결된 Web ACL에서 차단됐을 수 있습니다.
애플리케이션 403: WAF가 아니라 인증, 인가, 세션, 경로 권한 로직 문제일 수 있습니다.
이 구분을 초반에 못 하면 개발팀은 앱 로그만 보고, 보안팀은 룰만 보고, 인프라팀은 CDN만 보게 됩니다. 장애 대응은 결국 관찰 지점을 분리하는 데서 시작됩니다. 이거 하나만 정리해도 대응 속도가 눈에 띄게 달라지더라고요.
2. Cloudflare WAF vs AWS WAF 핵심 차이
쉽게 말해 Cloudflare WAF는 인터넷 입구 쪽에 더 가깝고, AWS WAF는 AWS 리소스 보호에 더 밀착돼 있습니다. 둘 다 관리형 룰, 커스텀 룰, IP 제어, 레이트 리밋 같은 공통 기능은 있지만 운영 감각은 꽤 다릅니다. 특히 로그를 어디서 보고, 어떤 헤더를 기준으로 클라이언트를 식별하는지가 실무에서는 정말 중요합니다.
항목
Cloudflare WAF
AWS WAF
주요 배치 위치
Cloudflare 엣지
CloudFront, ALB, API Gateway 등 AWS 리소스 앞단
장애 체감 지점
사용자 입장에서 즉시 차단 체감
AWS 서비스 경계에서 정책 적용
원인 추적 포인트
Security Events, 커스텀 룰, 관리형 룰, 봇/레이트 리밋 정책
Web ACL, Rule priority, sampled requests, 로그 대상
복합 구성 시 주의점
원본 IP 전달 헤더와 프록시 체인 확인
커스텀 IP/레이트 룰의 forwarded IP 설정 점검
제가 현업에서 자주 강조하는 포인트가 하나 있습니다. WAF는 보안 장비이면서 동시에 트래픽 해석기라는 점입니다. 어떤 헤더를 보고 판단하는지, 어떤 경로와 메서드에 민감한지, 차단이 어느 단계에서 일어나는지 모르면 운영이 금방 꼬입니다.
Cloudflare WAF가 잘 맞는 경우
전 세계 사용자 대상 서비스라 엣지 차단 효과가 중요한 경우
DDoS 완화, 봇 제어, 캐시와 함께 운영하는 경우
원본 서버까지 악성 요청을 최대한 보내고 싶지 않은 경우
AWS WAF가 잘 맞는 경우
AWS 인프라 중심으로 서비스가 구성된 경우
CloudFront, ALB, API Gateway와 일관되게 묶어 관리하고 싶은 경우
변경 이력과 IaC로 정책을 통제하고 싶은 경우
3. 실전 구현: 장애 추적을 쉽게 만드는 기본 구성
보안 장애에서 제일 아쉬운 순간은 로그를 안 남겼다는 사실을 뒤늦게 깨달을 때입니다. 처음엔 번거로워 보여도, WAF는 차단보다 관측 체계를 먼저 만들어두는 편이 훨씬 낫습니다. 저는 보통 아래 원칙으로 시작합니다.
WAF 정책을 처음부터 전부 block으로 넣지 않습니다.
가능하면 count, log, sampled requests 중심으로 먼저 동작을 봅니다.
원본 IP, 요청 경로, 메서드, User-Agent, Host 헤더를 함께 확인합니다.
Cloudflare와 AWS를 같이 쓸 때는 어느 계층에서 막혔는지 구분 가능한 로그 기준을 먼저 정합니다.
Cloudflare 앞단 + AWS 원본 구조 테스트 예시
아래 명령은 공개 엔드포인트에서 상태 코드와 응답 헤더를 빠르게 비교할 때 많이 씁니다. 다만 프록시 환경의 원본 IP 판별은 단순 curl 한 번으로 결론내리기보다, Cloudflare 이벤트와 AWS WAF 로그를 함께 맞춰 보는 편이 안전합니다.
# 기본 응답 헤더와 상태 코드 확인
curl -s -o /dev/null -D - https://example.com/
# 로그인 경로 확인
curl -s -o /dev/null -D - https://example.com/login
# 헬스체크 경로 확인
curl -s -o /dev/null -D - https://example.com/health
단순해 보여도 꽤 유용합니다. 정상 경로와 문제 경로를 나눠 보면 어느 계층에서 튕겼는지 감이 잡히거든요. 여기에 시간대까지 맞춰서 WAF 이벤트를 보면 훨씬 빨라집니다.
AWS WAF Web ACL 설계 예시
아래 YAML은 개념 설명용 예시입니다. 콘솔, CloudFormation, Terraform 문법과 1:1로 동일한 배포 파일은 아니고, 룰 우선순위와 관측 포인트를 이해하기 위한 샘플로 보시면 됩니다.
실무에서는 priority 때문에 생각보다 많이 헷갈립니다. 저도 처음엔 관리형 룰이 뒤에서 잡을 줄 알았는데, 앞단 커스텀 룰에서 이미 차단되고 있었던 적이 있었습니다. 그래서 장애가 나면 저는 항상 룰 순서부터 먼저 봅니다.
AWS WAF의 Web ACL 우선순위와 Cloudflare 규칙 평가 흐름을 비교해 보여주는 이미지가 들어갈 자리입니다.
4. 실제 장애 사례 1: 정상 사용자만 403이 뜨는 상황
개발팀에서는 로그인 잘 된다고 하는데, 특정 사용자군만 403이 뜨는 경우가 있습니다. 처음엔 브라우저 문제나 쿠키 문제처럼 보여도, 실제로는 정상 트래픽이 봇이나 의심 요청으로 오탐되는 경우가 제법 있습니다. 이런 케이스는 특히 배포 직후나 로그인 경로 변경 직후에 잘 나타납니다.
Cloudflare 쪽에서는 보통 아래 순서로 보는 게 빨랐습니다.
해당 시간대 Security Events에서 URI와 IP를 확인합니다.
차단 룰이 관리형 룰인지, 커스텀 룰인지 분리합니다.
특정 국가, ASN, User-Agent, 봇 정책 조건이 걸려 있는지 봅니다.
원본 서버 로그가 비어 있는지 함께 확인해 앞단 차단인지 가릅니다.
AWS WAF에서는 접근 방식이 조금 다릅니다.
연결된 Web ACL과 보호 대상 리소스를 먼저 확인합니다.
sampled requests에서 어떤 룰이 매치됐는지 확인합니다.
ALB 액세스 로그나 애플리케이션 로그와 시간대를 맞춰 봅니다.
원본 서버에 요청이 실제로 도달했는지 확인합니다.
핵심은 WAF 403과 앱 403을 분리하는 겁니다. 앱 로그가 전혀 없으면 앞단 차단 가능성이 높고, 앱 로그에 인증 실패나 권한 오류가 남으면 애플리케이션 이슈일 수 있습니다. 당연한 이야기 같지만, 장애 상황에서는 이 기본 분기가 제일 강력합니다.
5. 실제 장애 사례 2: Cloudflare 뒤에 AWS WAF를 붙였더니 원본 IP 판단이 꼬인 경우
이 케이스도 자주 나옵니다. Cloudflare가 프록시 역할을 하고 뒤에 AWS WAF가 또 있는 구조였는데, 로그인 경로의 레이트 리밋이 이상하게 동작하는 상황이었습니다. 사용자 한 명이 과도 요청을 보낸 것도 아닌데 여러 사용자가 묶여 차단되는 느낌이었죠.
원인은 대개 단순합니다. AWS WAF 커스텀 IP 기반 룰이나 rate-based rule이 실제 클라이언트 IP가 아니라 프록시 구간의 주소를 기준으로 평가하면 의도와 다르게 동작할 수 있습니다. 이럴 때는 원본 IP 전달 방식과 forwarded IP 설정을 같이 점검해야 합니다.
CF-Connecting-IP 또는 X-Forwarded-For를 원본에서 어떻게 수집하는지 확인합니다.
AWS WAF의 커스텀 IP/Geo/ASN/rate-based rule이 어떤 헤더를 기준으로 평가하는지 확인합니다.
프록시 체인이 여러 단계라면 어느 주소가 first IP로 해석되는지 테스트합니다.
레이트 리밋은 바로 차단보다 관찰 모드로 먼저 검증합니다.
# 응답 헤더와 상태 코드 확인
curl -s -o /dev/null -D - https://example.com/login
# 특정 경로 반복 호출로 제한 반응 확인
for i in $(seq 1 5); do
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/api/login
done
직접 겪어보면, 이 문제는 기능 차이보다도 배치 구조를 정확히 이해하지 못한 상태에서 둘을 같이 붙일 때 더 자주 터집니다. 그래서 Cloudflare WAF vs AWS WAF를 비교할 때는 누가 더 좋으냐보다, 누가 어디서 무엇을 보고 차단하느냐를 먼저 정리해야 합니다.
6. 주의사항: 트러블슈팅할 때 자주 놓치는 포인트
이 섹션은 실제 장애 대응에서 체감이 큽니다. 아래 항목만 체크해도 원인 추적 속도가 훨씬 빨라집니다.
규칙 우선순위: 먼저 매치된 룰에서 이미 차단됐을 수 있습니다.
허용 목록: 관리자 IP만 열어두고 모바일 회선, VPN, 사내 NAT 대역을 빼먹는 경우가 많습니다.
경로 예외 처리: /health, /callback, /api/upload 같은 경로는 성격이 달라 별도 예외가 필요할 수 있습니다.
메서드 차이: GET은 통과하는데 POST만 막히는 경우가 생각보다 자주 있습니다.
헤더 기반 탐지: User-Agent 누락, 비정상 Content-Type, 특이한 Host 헤더 때문에 오탐이 날 수 있습니다.
배포 타이밍: 앱 변경과 WAF 룰 변경이 겹치면 원인 추적이 훨씬 어려워집니다.
장애 중에는 룰을 무작정 끄기보다 영향 범위가 좁은 예외부터 적용하는 편이 안전합니다. 예를 들어 전체 관리형 룰을 비활성화하기보다 특정 URI나 특정 파라미터에 한해 임시 예외를 주는 식이죠. 이렇게 해야 보안 노출을 최소화하면서 서비스는 살릴 수 있습니다.
403 응답이 났을 때 어떤 순서로 헤더, 로그, 룰 매치를 따라가야 하는지 보여주는 트러블슈팅 이미지가 들어갈 자리입니다.
7. 검증 방법: 해결됐는지 어떻게 확인할까
문제가 해결된 것처럼 보여도 검증이 약하면 같은 장애가 반복됩니다. 저는 보통 아래 순서로 확인합니다.
차단되던 실제 요청 패턴을 다시 재현합니다.
정상 사용자 시나리오와 악성 의심 시나리오를 둘 다 테스트합니다.
WAF 로그에서 의도한 룰만 매치되는지 확인합니다.
애플리케이션 로그와 응답 시간도 같이 봅니다.
임시 예외를 넣었다면 만료 계획과 원복 일정을 남깁니다.
코드 블록은 아주 기본적인 확인용입니다. 여기서 중요한 건 상태 코드만 볼 게 아니라, 어느 레이어에서 응답이 만들어졌는지도 같이 보는 겁니다.
# 정상 페이지 확인
curl -I https://example.com/
# 로그인 엔드포인트 확인
curl -X POST -d "username=test&password=test" https://example.com/login -i
# 헬스체크 경로 확인
curl -I https://example.com/health
검증에서 진짜 중요한 건 200 OK가 나왔는지만 보는 게 아닙니다. 원래 막아야 할 요청이 계속 막히는지도 꼭 같이 봐야 합니다. 서비스는 살렸는데 방화벽이 사실상 꺼진 상태가 되는 게 가장 위험하거든요.
장애 조치 전후로 차단 이벤트와 정상 응답 비율이 어떻게 달라졌는지 보여주는 결과 대시보드 이미지가 들어갈 자리입니다.
8. Cloudflare WAF vs AWS WAF, 무엇을 기준으로 선택할까
정리하면 이렇습니다. 두 제품은 기능 몇 개만 비교해서 고를 대상이 아닙니다. 운영 팀의 시야, 로그 수집 체계, 서비스 배치 구조, 장애 대응 프로세스를 함께 봐야 선택이 훨씬 정확해집니다.
질문
Cloudflare WAF 쪽이 유리한 경우
AWS WAF 쪽이 유리한 경우
트래픽을 어디서 먼저 걸러야 하나?
인터넷 엣지에서 최대한 먼저
AWS 리소스 경계에서 정교하게
운영 중심이 어디인가?
CDN, 엣지 보안, 글로벌 트래픽
AWS 네이티브 리소스 중심
트러블슈팅 포인트는?
원본 도달 전 차단 여부
Web ACL, sampled requests, 리소스 연결 상태
복합 환경 난이도는?
AWS와 조합 시 헤더와 원본 IP 해석 주의
프록시 뒤 커스텀 룰의 forwarded IP 설정 주의
도입을 검토 중이라면 제품 비교표만 보지 말고 장애 시나리오를 먼저 적어보는 걸 권합니다. “로그인 POST가 갑자기 막히면 누가 어디서 무엇을 확인할까?”, “Cloudflare와 AWS WAF를 함께 쓰면 어느 계층에서 예외를 줄까?” 같은 질문이 실제 운영 품질을 좌우합니다.
9. 마무리: 웹 방화벽은 도입보다 운영이 어렵습니다
이번 글에서는 Cloudflare WAF vs AWS WAF를 웹 방화벽 비교 차원이 아니라, 보안 장애와 트러블슈팅 중심으로 정리했습니다. 직접 운영해보면 좋은 제품을 고르는 일보다 관찰 가능성을 확보하는 일이 더 중요하다는 걸 금방 느끼게 됩니다. 로그를 남기고, 룰 우선순위를 정리하고, 원본 IP 해석 기준을 분명히 해두면 장애 대응이 훨씬 편해집니다.
핵심만 짚으면 아래 네 가지입니다.
Cloudflare WAF는 엣지에서 빠르게 차단하는 데 강점이 있습니다.
AWS WAF는 AWS 리소스와의 통합 운영에 강점이 있습니다.
403 장애는 WAF, 프록시, 애플리케이션을 분리해서 봐야 빨리 해결됩니다.
복합 구성에서는 헤더와 원본 IP 해석이 가장 자주 문제를 일으킵니다.
다음 글에서는 WAF 예외 처리 패턴과 헬스체크, 로그인, API 업로드 경로를 안전하게 분리하는 방법도 다뤄보겠습니다. 이전에 정리한 리버스 프록시와 원본 IP 전달 방식 글도 함께 보시면 이해가 훨씬 빨라집니다.
도입 환경, 장애 대응 포인트, 운영 난이도를 기준으로 두 WAF를 요약 비교한 인포그래픽 이미지가 들어갈 자리입니다.
자주 묻는 질문
Cloudflare WAF와 AWS WAF를 같이 써도 되나요?
됩니다. 다만 어디서 차단됐는지 구분할 수 있도록 로그, 헤더, 원본 IP 해석 기준을 먼저 정리해두는 게 좋습니다.
보안 장애가 나면 가장 먼저 뭘 봐야 하나요?
응답 코드만 보지 말고 원본 서버 로그 유무와 WAF 이벤트를 함께 보셔야 합니다. 그 분기만 정확히 잡아도 시간을 많이 줄일 수 있습니다.
처음 도입할 때 바로 차단 정책으로 가도 될까요?
권장하지 않습니다. 가능하면 count, log, sampled requests 중심으로 먼저 관찰하고 오탐 여부를 확인한 뒤 점진적으로 차단 강도를 올리는 편이 안전합니다.
오늘은 제 홈랩에서 개인 NAS(Network Attached Storage)를 원격으로 안전하게 접속하려고 Cloudflare Tunnel(클라우드플레어 터널)을 구축하다가 겪었던 ‘삽질 경험’과 그 해결 과정을 솔직하게 공유해보려고 합니다. 혹시 저처럼 Cloudflare Tunnel로 NAS 원격 접속을 시도하다가 연결 오류에 막혀본 적 있으신가요? 그렇다면 이 글이 많은 도움이 될 거라고 생각합니다.
예전에는 VPN이나 포트 포워딩으로 NAS에 접속했었는데, 보안이나 설정의 복잡성 때문에 늘 고민이 많았거든요. 그러다 Cloudflare Tunnel이라는 아주 매력적인 솔루션을 알게 되었고, ‘이거다!’ 싶어서 바로 적용에 들어갔죠. Public IP(공인 IP) 없이도 안전하게 내부 서비스에 접근할 수 있다는 점이 정말 환상적이었어요. 그런데 막상 구축을 시작하니 생각지 못한 곳에서 오류가 터지면서 삽질 좀 했습니다. ㅎㅎ
제가 어떤 문제에 부딪혔고, 어떻게 해결했는지 그 과정을 상세하게 풀어보겠습니다. 이 경험이 독자 여러분의 소중한 시간을 절약하는 데 기여했으면 좋겠습니다. 자, 그럼 시작해볼까요?
먼저, 핵심 개념들을 간단하게 짚고 넘어가죠. 이 세 가지 기술이 어떻게 시너지를 내는지 이해하는 것이 중요합니다.
Cloudflare Tunnel (클라우드플레어 터널): 쉽게 말해, 외부에서 내부 네트워크로 안전하게 연결할 수 있는 ‘터널’을 만들어주는 서비스입니다. 우리 집 NAS나 서버가 공인 IP가 없어도, 심지어 방화벽 뒤에 있어도 Cloudflare의 엣지 네트워크를 통해 외부와 통신할 수 있게 해줘요. 내부에서 외부로 나가는 연결만 허용하면 되기 때문에 방화벽 설정도 훨씬 간단해집니다.
Zero Trust (제로 트러스트): ‘절대 아무것도 신뢰하지 않고, 항상 검증한다’는 보안 모델입니다. 전통적인 ‘경계 기반 보안’이 내부 네트워크는 안전하다고 가정했다면, Zero Trust는 내부 네트워크에 있더라도 모든 접근에 대해 사용자, 장치, 애플리케이션을 철저히 검증하죠. Cloudflare Zero Trust 플랫폼은 이 개념을 구현하는 강력한 도구거든요.
NAS (Network Attached Storage): 네트워크에 연결된 저장 장치입니다. 제 홈랩에서도 중요한 역할을 하는 녀석이죠. 사진, 동영상, 문서 등 개인 데이터를 저장하고, 미디어 서버나 백업 솔루션으로도 활용합니다.
이 세 가지를 조합하면, Public IP 없이도 NAS에 안전하게 원격 접속할 수 있고, Zero Trust 모델을 통해 누가 언제 어디서 접속하는지까지 통제할 수 있게 됩니다. 기존의 VPN보다 훨씬 유연하고 강력한 보안 환경을 구축할 수 있다는 게 저의 오랜 경험상 가장 큰 장점이라고 생각합니다.
Cloudflare Tunnel 설정부터 NAS 연결까지 차근차근
이제 실제로 Cloudflare Tunnel을 설정하고 NAS에 연결하는 과정을 단계별로 설명해드릴게요. 제가 진행했던 순서 그대로입니다.
Tunnel을 생성하면 화면에 token이 표시되는데, 이 토큰을 잘 복사해두세요. NAS에 cloudflared를 설치할 때 필요합니다.
2. NAS에 Cloudflared 설치 및 실행
NAS의 운영체제에 따라 cloudflared 설치 방법이 조금 다를 수 있습니다. 저는 주로 Debian/Ubuntu 기반의 리눅스 서버나 Docker를 사용하기 때문에 해당 기준으로 설명해드릴게요.
Linux (Debian/Ubuntu 기반):
# cloudflared 패키지 다운로드 및 설치
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
# 시스템 서비스로 등록 및 실행 (위에서 복사한 토큰 사용)
sudo cloudflared service install
# 서비스 시작
sudo systemctl start cloudflared
# 서비스 상태 확인
sudo systemctl status cloudflared
Docker 사용 시:
Docker Compose를 사용하는 것이 편리합니다. docker-compose.yml 파일을 다음과 같이 작성할 수 있습니다.
version: '3.8'
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command: tunnel run --token
network_mode: host # 중요: NAS의 다른 서비스에 접근하기 위해 host 네트워크 사용
이후 docker-compose up -d 명령으로 실행합니다.
정상적으로 실행되면 Cloudflare Zero Trust 대시보드에서 Tunnel의 상태가 ‘Healthy’로 표시될 겁니다. ✅
Cloudflare Zero Trust 대시보드의 Tunnel 설정 화면 (Ingress 규칙)
3. Ingress(인그레스) 규칙 설정
이제 가장 중요한 Ingress 규칙을 설정할 차례입니다. 이 규칙은 어떤 요청을 어느 내부 서비스로 보낼지 정의하는 역할을 합니다. NAS의 cloudflared가 실행되는 서버에 ~/.cloudflared/config.yaml 파일을 생성하거나 수정해야 합니다.
# ~/.cloudflared/config.yaml
tunnel: # Tunnel 생성 시 부여된 UUID
credentials-file: /root/.cloudflared/.json # 자격 증명 파일 경로
ingress:
- hostname: nas.yourdomain.com # NAS에 접속할 도메인
service: http://192.168.1.100:5000 # NAS의 내부 IP와 서비스 포트 (예: Synology DSM 기본 포트)
originRequest:
noTLSVerify: true # NAS가 HTTPS를 사용하지 않거나 자체 서명 인증서일 경우 필수!
- service: http_status:404 # 모든 요청이 위 규칙에 해당하지 않으면 404 반환
파일을 저장한 후, cloudflared 서비스를 재시작해야 변경 사항이 적용됩니다.
sudo systemctl restart cloudflared # Linux 서비스의 경우
# docker-compose restart cloudflared # Docker Compose의 경우
4. DNS 레코드 설정
마지막으로, Cloudflare 대시보드에서 NAS에 연결할 도메인(nas.yourdomain.com)이 위에서 생성한 Tunnel로 트래픽을 라우팅하도록 DNS 레코드를 설정해야 합니다. Zero Trust 대시보드의 Tunnel 설정 화면에서 ‘Public Hostname’을 추가하거나, CLI로 설정할 수 있습니다.
cloudflare tunnel route dns my-nas-tunnel nas.yourdomain.com
이 명령을 실행하면 Cloudflare DNS에 CNAME 레코드가 자동으로 생성되어 해당 도메인으로 들어오는 트래픽이 Tunnel로 연결됩니다.
⚠️ 삽질 경험: 터널 설정 오류 디버깅 포인트!
자, 이제 제가 가장 많이 헤매고 삽질했던 포인트들을 공유할 시간입니다. 아마 많은 분들이 여기서 비슷한 문제를 겪으셨을 거예요.
1. noTLSVerify 옵션의 중요성 (그리고 제 실수)
제가 가장 먼저 부딪힌 문제는 바로 이 noTLSVerify 옵션이었습니다. Ingress 규칙에 service: http://192.168.1.100:5000이라고 분명히 HTTP로 설정했는데도 계속 502 Bad Gateway 에러가 뜨는 거예요. ‘아니, NAS는 HTTPS 안 쓰는데 왜 이러지?’ 하고 한참을 헤맸습니다.
알고 보니 Cloudflare Tunnel은 기본적으로 Origin(원본 서버, 즉 NAS)과의 통신을 HTTPS로 시도하려고 합니다. 그런데 제 NAS는 HTTPS를 사용하지 않거나, 자체 서명 인증서를 사용하고 있었던 거죠. 이럴 경우 Tunnel이 NAS의 인증서를 신뢰하지 못해서 연결에 실패하게 됩니다. 해결책은 originRequest 아래에 noTLSVerify: true를 추가하여 TLS(전송 계층 보안) 검증을 건너뛰도록 하는 것이었습니다. 이 옵션을 추가하니 거짓말처럼 연결이 되더라고요! 🎉
💡 팁: 보안상 가능하면 NAS도 정식 HTTPS 인증서를 적용하고 noTLSVerify: false(또는 제거)로 설정하는 것이 좋습니다. 하지만 홈랩 환경에서는 편의상 이 옵션을 사용할 때가 많죠.
2. 서비스 포트 불일치
두 번째 삽질은 NAS의 실제 서비스 포트와 Ingress 규칙에 설정한 포트가 달라서 생긴 문제였습니다. 예를 들어 Synology NAS의 DSM(DiskStation Manager)은 기본적으로 5000번(HTTP) 또는 5001번(HTTPS) 포트를 사용하는데, 제가 다른 서비스 포트를 실수로 입력해놓은 적이 있었어요. 브라우저에서 NAS 내부 IP로 접속하면 잘 되는데, Cloudflare Tunnel을 통하면 접속이 안 되니 ‘Tunnel 문제인가?’ 하고 엉뚱한 곳을 파고 있었죠. 😅
NAS의 관리 페이지나 다른 서비스(Plex, Photo Station 등)에 접근할 때는 반드시 해당 서비스가 사용하는 정확한 내부 포트를 Ingress 규칙의 service 필드에 명시해야 합니다. http://localhost:5000 대신 http://[NAS_내부_IP]:[포트]처럼 명시적으로 내부 IP를 사용하는 것이 더 안전하고 명확합니다.
3. DNS 레코드 미설정 또는 오설정
Tunnel과 Ingress 규칙을 완벽하게 설정했다고 생각했는데도 접속이 안 된다면, DNS 레코드 설정을 다시 확인해보세요. Cloudflare Tunnel은 도메인에 대한 트래픽을 Tunnel로 라우팅하기 위해 CNAME 레코드가 필요합니다. 만약 이 레코드가 없거나 잘못 설정되어 있다면, 브라우저가 NAS 도메인으로 접속하려 해도 트래픽이 Tunnel로 들어오지 못하게 됩니다. 위에서 언급한 cloudflare tunnel route dns 명령어를 사용하거나 Cloudflare 대시보드에서 직접 CNAME 레코드를 확인해보세요.
4. cloudflared 서비스 로그 확인의 중요성
문제가 발생했을 때 가장 먼저 해야 할 일은 cloudflared 서비스의 로그를 확인하는 것입니다. Linux 시스템에서는 sudo journalctl -u cloudflared -f 명령으로 실시간 로그를 볼 수 있고, Docker 컨테이너를 사용한다면 docker logs -f cloudflared 명령으로 확인할 수 있습니다. 저도 위에서 언급한 noTLSVerify 문제를 로그에서 Error: x509: certificate signed by unknown authority와 같은 메시지를 보고 나서야 해결 실마리를 찾을 수 있었습니다. 로그는 항상 진실을 말해주거든요!
🎉 드디어 NAS 원격 접속 성공!
수많은 삽질 끝에 드디어 제 NAS가 https://nas.yourdomain.com으로 외부에서 완벽하게 접속되는 순간, 그 쾌감이란…! 🎉 Zero Trust 대시보드에서 Tunnel의 상태가 Healthy로 초록불이 들어오고, 트래픽이 정상적으로 흐르는 것을 확인했을 때의 안도감은 인프라 엔지니어만이 아는 뿌듯함이죠. 이제 언제 어디서든 제 NAS에 안전하게 접속하여 파일을 관리하고, 미디어를 스트리밍할 수 있게 되었습니다.
Cloudflare Zero Trust 대시보드에서 확인한 Tunnel의 정상 작동 상태
마치며: 안전한 홈랩을 위한 Cloudflare Tunnel
오늘은 Cloudflare Tunnel을 이용해 NAS 원격 접속을 설정하고, 제가 겪었던 연결 오류들을 어떻게 디버깅했는지 상세하게 공유해드렸습니다. 13년차 인프라 엔지니어로서 많은 시스템을 만져봤지만, 이렇게 새로운 기술을 제 홈랩에 적용하며 겪는 삽질은 언제나 성장의 밑거름이 되는 것 같습니다. ‘삽질은 기술 발전의 어머니’라는 말을 다시 한번 실감했네요. 😊
Cloudflare Tunnel은 Public IP 없이도 내부 서비스를 외부로 안전하게 노출할 수 있는 강력한 도구입니다. 특히 Zero Trust 모델과 결합하면 보안과 편의성을 동시에 잡을 수 있다는 점이 큰 매력이라고 생각합니다. 만약 여러분도 NAS 원격 접속이나 다른 홈랩 서비스를 외부에서 안전하게 접근하고 싶다면, Cloudflare Tunnel을 적극적으로 고려해보시길 강력히 추천합니다.
다음 글에서는 Cloudflare Access를 이용해 Tunnel로 접속하는 서비스에 사용자 인증/인가를 추가하는 방법을 다뤄볼 예정입니다. 더 강력한 Zero Trust 환경을 구축하는 방법을 기대해주세요!
안녕하세요, 13년차의 서버실 주인장입니다. 여러분, 웹사이트 이용하다 보면 이런 생각 안 해보셨나요? “아, 또 CAPTCHA! 이거 언제까지 해야 하나?” 저는 매일같이 봇과 전쟁을 치르는 인프라 엔지니어로서, 이 지긋지긋한 CAPTCHA가 얼마나 사용자 경험을 해치는지 몸소 느끼고 있습니다. 저만 해도 로그인할 때마다 횡단보도 찾고, 신호등 찾고… 이젠 정말 지겨워하고 있어요. 😩
그러던 와중에 Cloudflare에서 Turnstile(턴스타일)이라는 새로운 봇 방어 솔루션을 내놓았다는 소식을 접했습니다. “오, 드디어 CAPTCHA 지옥에서 벗어날 수 있나?” 하는 기대감이 솟았죠. 그런데 이 Turnstile이 사용자 프라이버시 침해 논란에 휩싸였다는 이야기도 들려오더라고요. 흠, 과연 뭐가 진실일까요?
오늘은 이 Cloudflare Turnstile이 대체 무엇이고, 어떤 프라이버시 논란이 있는지, 그리고 앞으로 봇 방어 솔루션의 미래는 어떻게 흘러갈지에 대해 저의 13년차 경험을 바탕으로 솔직하게 이야기해보려고 합니다. 저처럼 홈랩에서 이것저것 실험하며 웹 보안에 관심 많은 분들이라면, 오늘 글이 꽤 흥미로우실 거예요.
Cloudflare Turnstile이 웹사이트에서 사용자 활동을 분석하여 봇을 식별하는 과정을 간략하게 보여주는 다이어그램입니다. 기존 CAPTCHA와 달리 사용자 상호작용 없이 백그라운드에서 작동하는 특징을 강조합니다.
Turnstile은 대체 뭘까요? (CAPTCHA의 새로운 대안)
쉽게 말해, Cloudflare Turnstile은 우리가 흔히 겪는 CAPTCHA(캡차), 즉 ‘Completely Automated Public Turing test to tell Computers and Humans Apart’의 대안으로 등장한 서비스예요. 기존 CAPTCHA는 사용자가 그림을 맞추거나 글자를 입력하는 등 직접적인 상호작용을 통해 자신이 봇이 아님을 증명해야 했죠. 근데 Turnstile은 다릅니다. 사용자가 아무것도 하지 않아도 백그라운드에서 자동으로 봇 여부를 판별해줍니다. 마치 무인 검문소처럼요. Cloudflare가 개발한 비대화형(non-interactive) 봇 탐지 기술을 활용해서, 브라우저 환경 정보, 마우스 움직임 패턴 같은 다양한 신호를 분석한다고 하더라고요. 이걸 통해서 악성 봇을 걸러내고, 진짜 사람에게는 아무런 방해도 주지 않는다는 게 핵심입니다. 제가 직접 써보지는 않았지만, 개념만 들어도 사용자 경험이 훨씬 좋아질 거라는 건 분명해 보여요. 봇 방어는 해야겠고, 사용자들은 불편해하고… 이런 딜레마 속에서 나온 기술인 거죠.
CAPTCHA의 한계와 Turnstile의 등장 배경 (왜 Turnstile이 필요했을까?)
기존 CAPTCHA, 특히 Google의 reCAPTCHA(리캡차)는 사실상 웹에서 봇을 방어하는 표준처럼 쓰여왔습니다. 하지만 문제가 많았어요. ⚠️
사용자 경험 저해: 아까 말씀드린 대로, 그림 맞추고 텍스트 입력하는 게 여간 귀찮은 일이 아닙니다. 저도 급할 땐 짜증이 확 올라오더라고요.
접근성 문제: 시각 장애인이나 특정 인지 능력이 불편한 사용자들에게는 CAPTCHA가 웹 접근을 가로막는 장벽이 될 수 있습니다.
봇 우회 기술 발전: 봇들도 진화합니다. 요즘 봇들은 CAPTCHA를 꽤 능숙하게 우회하거나, 심지어 저렴한 비용으로 사람을 고용해서 CAPTCHA를 풀게 하는 수법까지 쓴다고 하더라고요. 씁쓸하죠.
프라이버시 우려: reCAPTCHA의 경우, Google이 사용자의 브라우징 데이터를 수집하여 봇 여부를 판단합니다. 이 과정에서 Google이 너무 많은 개인 정보를 가져가는 게 아니냐는 우려가 꾸준히 제기되어 왔습니다. 사실 이게 오늘 주제와도 깊이 연관되어 있죠.
이런 문제점들 때문에 새로운 봇 방어 솔루션의 필요성이 대두되었고, 그 결과물이 바로 Turnstile인 거예요. Cloudflare는 특히 프라이버시를 강조하며 reCAPTCHA와의 차별점을 내세웠습니다.
Cloudflare Turnstile과 Google reCAPTCHA가 각각 어떤 종류의 데이터를 수집하고 처리하는지, 그리고 그 과정에서 사용자 프라이버시에 어떤 영향을 미칠 수 있는지 비교하는 표입니다. 데이터 최소화 원칙을 강조합니다.
프라이버시 침해 논란, 과연 사실일까요? (Cloudflare Turnstile 프라이버시 논란 깊이 파고들기)
자, 이제 가장 중요한 부분입니다. Cloudflare Turnstile이 프라이버시 침해 논란에 휩싸인 이유는 무엇일까요? 그리고 Cloudflare는 이에 대해 뭐라고 말하고 있을까요?
논란의 핵심은 “Cloudflare도 결국 사용자의 브라우징 데이터를 수집하는 것 아니냐?”는 의문에서 시작됩니다. Turnstile은 사용자가 모르는 사이에 백그라운드에서 동작하고, 봇 여부 판단을 위해 브라우저 환경, 요청 헤더, 마우스/터치 이벤트 패턴 등 다양한 신호를 분석합니다. 이 과정에서 개인 식별 가능 정보(PII: Personally Identifiable Information)가 수집되거나, 사용자 활동이 추적될 수 있다는 우려가 제기된 거죠.
하지만 Cloudflare는 이에 대해 “데이터 최소화(data minimization) 원칙을 철저히 지킨다”고 강조하고 있습니다. Cloudflare의 공식 입장을 요약하면 이렇습니다:
개인 식별 정보 미수집: IP 주소, 이메일 주소, 쿠키 등 개인을 식별할 수 있는 정보는 수집하지 않습니다.
추적 금지: 사용자 브라우징 기록을 추적하여 프로필을 만들거나 광고 목적으로 사용하지 않습니다.
필요 최소한의 데이터: 오직 봇 여부 판단에 필요한 최소한의 데이터만 수집하며, 이 데이터는 일정 기간 후 삭제됩니다.
독립적인 솔루션: Cloudflare의 다른 서비스와 독립적으로 작동하며, 다른 서비스의 데이터와 연동되지 않습니다.
제가 보기에 Cloudflare의 이러한 설명은 reCAPTCHA가 Google 서비스 전반에 걸쳐 데이터를 활용할 수 있다는 비판을 의식한 것으로 보여요. 물론 Cloudflare의 말을 100% 믿어야 할지는 사용자 개개인의 판단에 달렸지만, 최소한 명확한 가이드라인을 제시하고 있다는 점은 긍정적으로 평가할 만하다고 생각합니다. 💡
봇 방어 솔루션의 미래, 어디로 갈까요? (CAPTCHA를 넘어선 웹 보안 트렌드)
Turnstile을 보면서 저는 봇 방어 솔루션의 미래가 점차 “보이지 않는” 방향으로 흘러갈 거라고 확신했어요. 사용자에게 아무런 방해도 주지 않으면서, 백그라운드에서 정교하게 봇을 탐지하는 방식이 대세가 될 거라는 거죠.
이러한 트렌드는 몇 가지 핵심 기술을 기반으로 합니다.
행동 분석 (Behavioral Analysis): 사용자의 마우스 움직임, 키보드 입력 속도, 스크롤 패턴 등을 분석하여 인간과 봇의 행동 양식을 구분해요. 봇은 보통 매우 기계적이고 일관된 패턴을 보이거든요.
장치 지문 (Device Fingerprinting): 브라우저, 운영체제, 설치된 폰트, 플러그인 등 사용자 장치의 고유한 특성을 조합하여 “지문”을 생성하고, 이를 통해 봇을 식별합니다. (물론 이 부분도 프라이버시 논란에서 자유롭지는 않습니다.)
머신러닝/AI: 방대한 데이터를 기반으로 봇의 특징을 학습하고, 새로운 공격 패턴을 실시간으로 감지하는 데 활용됩니다.
결국, 봇 방어는 단순히 “사람인가, 봇인가”를 넘어서 “의도와 행동이 정상적인가, 악의적인가”를 판단하는 방향으로 진화하고 있어요. Turnstile은 이러한 흐름의 선두 주자 중 하나라고 볼 수 있겠네요. 저도 제 홈랩 프로젝트에 봇 방어 기능을 추가할 때, 사용자 경험을 최대한 해치지 않는 방법을 항상 고민하거든요. 이런 솔루션들이 더욱 발전하기를 기대하고 있습니다.
Cloudflare Turnstile, Google reCAPTCHA, 그리고 기타 행동 기반 봇 방어 솔루션들의 주요 특징, 장점, 단점을 시각적으로 비교한 인포그래픽입니다. 사용자 프라이버시, 편의성, 봇 탐지 정확도 등의 기준을 포함합니다.
제 경험과 생각 (13년차 인프라 엔지니어의 시선)
13년 동안 서버실에서 봇과 씨름하면서 느낀 건 딱 하나예요. “봇과의 전쟁은 끝이 없다.” 🥲 제가 처음 인프라 엔지니어링을 시작했을 때부터 지금까지, 봇들은 점점 더 똑똑해지고 교묘해졌거든요. 단순한 스팸 봇부터 웹 스크래핑, 계정 탈취 시도까지… 종류도 정말 다양합니다.
이런 상황에서 Cloudflare Turnstile 같은 새로운 봇 방어 솔루션의 등장은 분명 환영할 만한 일입니다. 특히 reCAPTCHA에 대한 의존도가 너무 높았던 웹 생태계에 새로운 선택지를 제공한다는 점이 정말 중요하다고 생각해요. 저도 개인적으로 홈랩에서 운영하는 몇몇 웹 서비스에 봇 공격이 들어올 때마다 골머리를 앓았거든요. 사용자가 불편해하지 않으면서도 봇을 막을 수 있다면 정말 좋겠죠.
하지만 “프라이버시”라는 민감한 이슈는 항상 따라붙을 거예요. Cloudflare가 아무리 데이터를 최소화한다고 해도, 결국 ‘누군가’가 내 브라우저 활동을 들여다보고 있다는 사실은 변치 않으니까요. 저는 이 부분에 대해서는 개발자나 서비스 운영자가 명확하게 사용자에게 고지하고, 선택권을 주는 것이 중요하다고 봅니다. 예를 들어, “저희 서비스는 Cloudflare Turnstile을 사용하여 봇 공격을 방어하고 있습니다. 이 과정에서 최소한의 브라우저 정보가 분석될 수 있습니다.” 같은 문구를 보여주는 거죠. 그래야 사용자들이 안심하고 서비스를 이용할 수 있지 않을까요?
아직 Turnstile이 완벽한 대안이라고 말하기는 어렵습니다. 하지만 기존 CAPTCHA의 한계를 극복하려는 시도 자체는 높이 평가하고 싶네요. 앞으로 더 많은 봇 방어 솔루션들이 사용자 프라이버시를 존중하면서도 강력한 보안을 제공하는 방향으로 발전했으면 하는 바람입니다.
Cloudflare Turnstile이 현대 웹 보안 생태계에서 봇 방어의 중요한 한 축을 담당하며, 사용자 경험과 프라이버시 보호 사이의 균형점을 찾는 모습을 시각적으로 표현한 다이어그램입니다. 미래 지향적인 솔루션임을 강조합니다.
마무리 (결국 선택은 우리의 몫입니다)
오늘은 Cloudflare Turnstile의 등장부터 프라이버시 논란, 그리고 봇 방어 솔루션의 미래까지 폭넓게 다뤄봤습니다. 봇과의 전쟁은 기술의 발전과 함께 계속될 거고, 그 과정에서 사용자 프라이버시 보호는 더욱 중요해질 겁니다.
Cloudflare Turnstile은 분명 매력적인 대안이지만, 모든 기술이 그렇듯 장점과 단점을 동시에 가지고 있어요. 우리가 할 일은 이 기술의 작동 방식과 잠재적인 영향을 정확히 이해하고, 우리 서비스와 사용자들에게 가장 적합한 해결책을 현명하게 선택하는 것이라고 생각합니다.
여러분은 Cloudflare Turnstile에 대해 어떻게 생각하시나요? 댓글로 여러분의 의견을 나눠주세요! 다음번에는 또 다른 흥미로운 인프라 이야기로 찾아오겠습니다. 그때까지 모두 안전한 서버실 운영하세요! 😄
오늘은 제가 최근 홈랩에서 이것저것 실험하면서 꽤나 재미를 보고 있는 기술, 바로 Cloudflare Workers(클라우드플레어 워커스)에 대한 이야기를 풀어볼까 합니다. 다들 서버리스(Serverless)니, 엣지 컴퓨팅(Edge Computing)이니 하는 말 많이 들어보셨을 텐데요. 이게 실제 제 서비스에 어떻게 적용될 수 있을까 궁금하셨던 분들에게 좋은 길잡이가 되었으면 합니다.
사실 저도 처음엔 ‘이게 뭔가 싶었는데’ 직접 써보고 나니 ‘와, 이거 진짜 물건이네!’ 싶더라고요. 특히 작은 API나 특정 요청을 처리해야 할 때, 굳이 무거운 서버 인스턴스를 띄우지 않고 전 세계 Cloudflare(클라우드플레어) 엣지 네트워크에서 코드를 바로 실행할 수 있다는 점이 매력적이었습니다. 저지연(low-latency)을 줄이고, 비용 효율적으로 서비스를 운영할 수 있는 강력한 도구거든요.
이번 글에서는 Cloudflare Workers가 무엇인지부터 시작해서, 제가 직접 겪었던 삽질 경험과 해결 과정까지, Cloudflare Workers 실전 가이드: 서버리스 엣지 컴퓨팅 활용 전략을 자세히 알려드리겠습니다. 그럼, 함께 떠나볼까요? 🎉
Cloudflare Workers의 전체적인 아키텍처와 엣지 컴퓨팅 개념을 시각적으로 보여주는 다이어그램입니다.
Cloudflare Workers, 대체 뭘까요?
쉽게 말해, Cloudflare Workers는 Cloudflare의 전 세계 분산된 엣지 네트워크(Edge Network) 위에서 JavaScript나 WebAssembly 코드를 실행할 수 있게 해주는 서버리스 실행 환경(Serverless Execution Environment)이에요. 기존의 서버리스 함수(Lambda, Cloud Functions 등)와 비슷하지만, 사용자와 물리적으로 가장 가까운 엣지 로케이션에서 실행된다는 점에서 엣지 컴퓨팅의 특성을 지니고 있습니다.
제가 처음 접했을 때 가장 놀랐던 건 ‘콜드 스타트(Cold Start)’ 거의 없이 극도로 빠른 응답 시간을 보여준다는 점이었어요. 기존 서버리스 함수들은 유휴 상태일 때 첫 요청에서 약간의 지연이 생길 수 있거든요. 하지만 Workers는 그런 걱정을 거의 할 필요가 없었습니다.
Cloudflare Workers의 주요 장점
극도로 낮은 지연 시간(Ultra-low Latency): 사용자와 가장 가까운 엣지 서버에서 코드가 실행되므로, 응답 시간이 획기적으로 단축됩니다. 이는 글로벌 네트워크를 활용한 개발자 경험 개선에 크게 기여합니다.
뛰어난 확장성(Massive Scalability): Cloudflare의 강력한 인프라 위에서 작동해서 트래픽이 폭증해도 자동으로 확장되고 안정적인 서비스를 제공합니다. 제가 직접 트래픽 테스트를 해보니 정말 안정적이더라고요.
비용 효율성(Cost-effectiveness): 사용량 기반(pay-per-use) 요금 모델로, 요청 수에 비례하여 비용이 발생합니다. 특히 무료 티어(Free Tier)가 넉넉해서 소규모 서비스나 실험에 정말 좋습니다.
개발자 친화적(Developer-friendly): JavaScript/TypeScript 기반으로 익숙한 언어로 개발할 수 있고, Wrangler CLI 등 개발 도구도 잘 갖춰져 있어요.
Cloudflare Workers 실전 구현: 첫 Workers 배포하기
자, 이제 이론은 충분히 봤으니 직접 한번 만들어보고 배포해보는 시간을 가져볼까요? 제가 홈랩에서 했던 과정을 그대로 따라 해보시면 금방 첫 Workers를 만나보실 수 있을 겁니다. 준비물은 Cloudflare 계정 하나면 충분해요!
1. Cloudflare 계정 생성 및 로그인
아직 Cloudflare 계정이 없으시다면, Cloudflare 웹사이트에서 가입하세요. 무료 계정으로도 충분합니다. 계정을 생성하고 로그인하면 준비 끝입니다.
2. Wrangler CLI 설치
Cloudflare Workers를 개발하고 배포하는 데는 wrangler라는 CLI(Command Line Interface) 도구를 사용하는 것이 가장 편리합니다. Node.js가 설치되어 있어야 합니다.
npm install -g wrangler
설치가 완료되면, 터미널에서 wrangler login 명령어를 실행하여 Cloudflare 계정에 로그인합니다.
wrangler login
이 명령어를 실행하면 브라우저가 열리고 Cloudflare 인증 페이지로 리다이렉트됩니다. 인증을 완료하면 터미널로 돌아와 성공 메시지를 확인할 수 있습니다.
3. 새 Workers 프로젝트 생성
이제 새로운 Workers 프로젝트를 생성해봅시다. 최신 개발 환경을 위해 npm create cloudflare 명령어를 사용하는 것을 권장합니다. 여기서는 TypeScript 템플릿을 기반으로 진행하겠습니다.
npm create cloudflare my-first-worker -- --typescript
cd my-first-worker
이 명령어는 TypeScript 템플릿을 사용하여 기본적인 Workers 프로젝트 구조를 만들어줍니다. my-first-worker 디렉토리로 이동해주세요.
4. 간단한 Worker 코드 작성
src/index.ts 파일을 열어보면 다음과 같은 코드를 볼 수 있습니다. 이게 기본 ‘Hello World’ Workers 코드에요.
/**
* Welcome to Cloudflare Workers! This is your first worker.
*
* - Run `npm run dev` in your terminal to start a development server
* - Open a browser tab at http://localhost:8787/ to see your worker in action
* - Run `npm run deploy` to publish your worker
*
* Learn more at https://developers.cloudflare.com/workers/
*/
export interface Env {
// Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime/kv/
// MY_KV_NAMESPACE: KVNamespace;
// // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime/durable-objects/
// MY_DURABLE_OBJECT: DurableObjectNamespace;
// // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime/r2/
// MY_BUCKET: R2Bucket;
}
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
return new Response('Hello Cloudflare Workers!');
},
};
여기서 new Response('Hello Cloudflare Workers!'); 부분을 원하는 메시지로 바꿔볼 수도 있어요. 예를 들어, 제가 좋아하는 메시지인 ’13년차 서버실에서 보내는 메시지!’로 바꿔보겠습니다.
코드를 수정했다면, 이제 Cloudflare 엣지 네트워크에 배포할 차례입니다. wrangler deploy 명령어를 사용하면 됩니다. 배포 시 Workers의 이름은 wrangler.toml 파일에 설정된 name을 따릅니다.
wrangler deploy
이 명령어를 실행하면 코드가 컴파일되고 Cloudflare에 업로드됩니다. 몇 초 안에 배포가 완료되고, 배포된 Workers의 URL을 터미널에서 확인할 수 있어요. 🎉 드디어 됐다!
Cloudflare Workers 대시보드에서 방금 배포한 Workers의 설정 화면을 보여주는 스크린샷입니다.
⚠️ 주의사항 및 트러블슈팅 경험
제가 Cloudflare Workers를 사용하면서 겪었던 몇 가지 주의사항과 ‘아, 이거 때문에 삽질 좀 했네’ 싶었던 경험들을 공유합니다.
1. 런타임 환경 이해하기
Node.js 호환성: Workers는 Node.js 런타임이 아니에요. V8 엔진 기반의 독자적인 런타임인 Workers Runtime을 사용하거든요. 그래서 Node.js의 모든 내장 모듈(fs, http 등)을 사용할 수 없습니다. 특정 Node.js 모듈이 필요하다면, Cloudflare의 Node.js 호환성 문서를 참고하거나, WebAssembly(Wasm) 같은 대안을 고려해봐야 합니다. 처음엔 Node.js 모듈을 무심코 사용했다가 에러를 뿜어서 당황했던 기억이 있네요.
글로벌 객체: Node.js의 process나 브라우저의 window 같은 전역 객체(Global Object)는 Workers 환경에 없어요. 대신 self나 globalThis를 사용해야 합니다.
2. 리소스 제한(Limits)
Cloudflare Workers는 매우 강력하지만, 엣지 환경의 특성상 몇 가지 리소스 제한이 있습니다. 저도 이 제한 때문에 몇 번 코드를 수정해야 했었죠. (이 정보는 2026년 9월 현재 기준입니다.)
CPU 시간: 단일 요청 처리 시 50ms(무료 플랜) ~ 30초(유료 플랜)의 CPU 시간이 주어집니다. 복잡한 연산보다는 빠르고 가벼운 요청 처리에 적합합니다.
메모리: 약 128MB의 메모리 제한이 있어요. 큰 데이터를 처리하거나 복잡한 상태를 유지하는 데는 한계가 있을 수 있습니다.
요청/응답 본문 크기: 기본적으로 50MB로 제한돼요. 큰 파일을 업로드하거나 다운로드하는 프록시를 만들 때는 이 점을 고려해야 합니다.
3. 로컬 개발 환경
wrangler dev 명령어를 사용하면 로컬에서 Workers를 개발하고 테스트할 수 있어요. 이게 진짜 편하더라고요. 실제 배포하기 전에 충분히 테스트해보는 습관을 들이는 것이 중요합니다. 💡
wrangler dev
이 명령어를 실행하면 로컬 개발 서버가 시작되고, 브라우저에서 http://localhost:8787/로 접속하여 Workers의 동작을 바로 확인할 수 있습니다.
검증 및 결과 확인
배포된 Workers가 잘 작동하는지 확인하는 과정도 중요하죠. 제가 배포한 my-first-worker의 URL을 확인한 뒤, curl 명령어나 웹 브라우저로 접속해보면 됩니다.
Cloudflare 대시보드에서도 Workers의 로그와 분석(Analytics)을 확인할 수 있어요. 얼마나 많은 요청이 들어왔고, CPU 시간은 얼마나 사용했는지 등을 한눈에 볼 수 있어서 모니터링하기 정말 편리하더라고요.
Cloudflare Workers 대시보드에서 Workers의 요청 수, CPU 시간 등 성능 지표를 보여주는 그래프나 차트입니다.
🌟 최신 Cloudflare Workers의 주요 변화 및 신기능
Cloudflare Workers는 지난 몇 달간 눈부신 발전을 거듭하며 엣지 컴퓨팅의 지평을 넓히고 있습니다. 특히 AI 시대의 엣지 컴퓨팅을 선도하는 새로운 기능들이 대거 추가되었어요. 이 변화들을 통해 Workers는 단순한 서버리스 함수를 넘어, 강력한 엣지 애플리케이션 플랫폼으로 진화하고 있습니다.
Workers AI: 엣지 AI의 새로운 지평을 열었습니다. Workers AI를 통해 개발자들은 Cloudflare의 글로벌 네트워크에서 직접 AI 모델을 배포하고 추론을 실행할 수 있습니다. 텍스트 생성, 이미지 분류, 임베딩 등 다양한 AI 작업을 저지연으로 처리할 수 있어, 사용자에게 더 빠르고 개인화된 경험을 제공할 수 있게 되었죠. 이는 서버리스 AI의 가능성을 극대화합니다.
Vectorize (벡터 데이터베이스): Workers AI와 함께 사용하기 좋은 벡터 데이터베이스 서비스인 Vectorize가 정식 출시되었습니다. 벡터 임베딩을 저장하고 검색하여 AI 기반 검색, 추천 시스템 등을 엣지에서 구현할 수 있게 해줍니다.
D1 (서버리스 SQL 데이터베이스): Cloudflare D1은 SQLite 기반의 서버리스 SQL 데이터베이스로, Workers와 긴밀하게 통합되어 엣지에서 데이터를 영속적으로 저장하고 관리할 수 있게 합니다. 이제 Workers만으로도 복잡한 데이터 기반 애플리케이션을 구축하는 것이 더욱 쉬워졌습니다.
Cloudflare Queues: 안정적인 메시징 시스템인 Cloudflare Queues를 통해 Workers 간 또는 외부 시스템과의 비동기 통신을 더욱 견고하게 구축할 수 있습니다. 이는 복잡한 분산 시스템 아키텍처를 엣지에서 구현하는 데 필수적인 요소입니다.
이러한 기능들은 Workers가 단순한 “함수”를 넘어, 완전한 “엣지 애플리케이션 플랫폼”으로 성장했음을 보여줍니다. 글로벌 네트워크를 활용한 개발자 경험은 더욱 풍부해지고 있습니다.
마무리하며: 엣지 컴퓨팅의 미래를 Workers와 함께
오늘은 13년차 인프라 엔지니어의 시선으로 Cloudflare Workers에 대해 자세히 알아보고, 직접 배포까지 해보는 실전 가이드를 소개해드렸습니다. 최신 업데이트를 통해 Workers가 단순한 서버리스 함수를 넘어, 엣지 AI와 데이터 스토리지를 결합한 강력한 플랫폼으로 진화하고 있음을 확인했습니다.
처음엔 단순히 ‘클라우드플레어에서 코드 돌리는 건가?’ 싶었는데, 직접 써보고 삽질도 해보면서 엣지 컴퓨팅의 진정한 가치를 깨달았네요. 특히 지연 시간에 민감한 서비스나 글로벌 사용자들을 대상으로 하는 서비스에는 Workers가 정말 강력한 대안이 될 수 있겠다는 생각이 들었습니다.
Cloudflare Workers의 다양한 활용 사례
API 게이트웨이(API Gateway): 복잡한 백엔드 없이 간단한 API 엔드포인트를 만들거나, 기존 API에 대한 인증/인가 레이어를 추가할 수 있어요.
정적 웹사이트 라우팅(Static Site Routing): 여러 정적 사이트를 하나의 도메인 아래에서 라우팅하거나, A/B 테스트를 위한 트래픽 분배에 활용할 수 있습니다.
이미지 최적화(Image Optimization): 요청 시점에 이미지를 동적으로 리사이징하거나 포맷을 변환하여 전달할 수 있어요.
보안 및 필터링(Security & Filtering): 악성 트래픽을 차단하거나, 특정 IP 대역의 접근을 제한하는 등 보안 로직을 엣지에서 구현할 수 있습니다.
데이터 캐싱(Data Caching): 자주 요청되는 데이터를 엣지에 캐싱하여 백엔드 부하를 줄이고 응답 속도를 높일 수 있어요.
엣지 AI 애플리케이션: Workers AI를 활용하여 실시간 번역, 콘텐츠 모더레이션, 개인화된 추천 등 AI 기반 서비스를 엣지에서 직접 구현할 수 있습니다.
저의 작은 경험과 삽질이 Cloudflare Workers를 시작하려는 분들에게 조금이나마 도움이 되었기를 바랍니다. 다음번에는 Workers KV나 Durable Objects 같은 Workers의 고급 기능들을 활용하는 방법에 대해 더 깊이 파고들어 볼 예정입니다. 기대해주세요! 😄