홈 서버에서 Cloudflare Tunnel + Caddy로 여러 웹 애플리케이션 노출하기
Source: Dev.to
Introduction
홈 서버에 여러 웹 애플리케이션을 배포할 때 정적 IP 주소 확보, SSL 인증서 관리, 복잡한 보안 설정 등이 병목이 될 수 있습니다. 이 글에서는 Cloudflare Tunnel, Caddy, 그리고 WSL2를 조합해 이러한 문제를 해결하고 여러 웹 애플리케이션을 안전하게 외부에 노출하는 실용적인 방법을 설명합니다.
Architecture layers
| Layer | Role |
|---|---|
| Cloudflare Tunnel | 홈 서버를 인터넷에 연결합니다 (cloudflared 명령으로 설정). |
| Caddy | 리버스 프록시 역할을 수행하고, 보안 헤더를 추가하며, 접근 로그를 수집합니다. |
| App Services | 다양한 포트에서 실행되는 웹 애플리케이션(예: Streamlit)입니다. |
Caddy는 Cloudflare Tunnel을 통해 들어온 요청을 받아 적절한 애플리케이션으로 전달합니다. URL은 service_name.example.org 형태를 따릅니다.
- App Services:
8xxx범위 포트(애플리케이션 실행 포트) - Caddy:
9xxx범위 포트(리버스‑프록시 포트) - URL naming convention:
{service_name}.example.org
How to Write a Caddyfile
Caddy 2.x에서는 사이트 주소를 먼저 선언하고, 그 뒤에 리버스‑프록시와 로깅 지시문을 적습니다.
:9530 {
log {
output file /var/log/caddy/access.log {
roll_size 10mb
roll_keep 30
}
format json
}
reverse_proxy localhost:8530 {
header_up X-Forwarded-Proto https
}
header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
}
}
What this configuration does
- Reverse proxy: 포트 9530으로 들어온 트래픽을
localhost:8530에서 대기 중인 애플리케이션으로 전달합니다. - Security headers:
Strict-Transport-Security와X-Content-Type-Options헤더를 추가합니다. - Access logging: JSON 형식 로그를
/var/log/caddy/access.log에 기록하고, 파일 크기가 10 MiB에 도달하면 롤링하며 최근 30개의 파일을 보관합니다.
Note:
Content‑Security‑Policy: default-src 'self'와 같은 일반적인 CSP는 외부 리소스를 로드하는 Streamlit 같은 앱에 너무 제한적일 수 있습니다. 필요에 따라 각 애플리케이션에 맞게 CSP를 조정하세요.
Security layers provided
| Layer | Protection |
|---|---|
| Cloudflare | WAF, DDoS 완화, 자동 SSL 제공 |
| cloudflared | 홈 IP 주소를 숨김 |
| Caddy | 보안 헤더 추가, 요청 로그 기록 |
| Application authentication | OTP/PIN 등 접근 제어 |
| Data protection | Fernet으로 민감 데이터 암호화 |
| Cloudflare Access (optional) | SSO 및 다중 인증 |
Cron Setting (Daily Log Analysis)
매일 밤에 크론 작업이 실행되어 Caddy 접근 로그를 분석하고 Gmail을 통해 의심 활동 알림을 보냅니다.
55 23 * * * /home/user/logger/daily_log_analyzer.py
Analysis workflow
- Extract: 오늘의 항목을 JSON 형식 Caddy 로그에서 추출합니다.
- Aggregate: 상태 코드, 서비스, IP 주소, User‑Agent 문자열을 집계합니다.
- Send: 집계된 데이터를 Gemini 2.5 Flash에 전달해 패턴을 탐지합니다.
- Notify: 발견된 내용을 Gmail으로 알립니다.
Cloudflare Tunnel과 Caddy를 결합하면 정적 IP 없이도 홈 서버에 호스팅된 서비스를 외부에 노출할 수 있으며, 자동 SSL, WAF/DDoS 보호, 엔터프라이즈 수준 보안 헤더를 동시에 누릴 수 있습니다. 이 설정은 개인 개발 환경을 프로덕션 수준의 보안으로 끌어올려 줍니다.