날씨 정보를 불러오는 중...

Cloudflare Tunnel로 포트 개방 없이 홈서버 외부 공개하기 - 공유기 설정 없이 내 서비스에 https 주소 붙이기

2026-11-10 06:43 · IT기술 · 조회 14
Cloudflare Tunnel 배너

Cloudflare Tunnel로 포트 개방 없이 홈서버 외부 공개하기 - 공유기 설정 없이 내 서비스에 https 주소 붙이기

홈서버에서 웹 서비스를 돌리다 보면 결국 "이걸 밖에서도 주소로 열고 싶다"는 순간이 온다. 보통은 공유기에서 포트포워딩을 열고, 공인 IP를 도메인에 연결하고, 인증서를 붙인다. 되긴 하지만 집 IP가 그대로 노출되고, 포트가 열려 있으니 스캐너가 매일 문을 두드린다. (실제로 내 서버도 새벽에 스캔당한 적이 있다. 새벽에 내 서버가 스캔당했다 글 참고)

Cloudflare Tunnel은 이 구조를 뒤집는다. 서버가 밖으로 먼저 연결을 걸어 두고, 방문자는 Cloudflare를 거쳐 그 연결로 들어온다. 그래서 공유기 포트를 하나도 열지 않아도 서비스를 공개할 수 있다. 클라우드플레어 완전 입문의 후속편으로, 이번에는 정적 페이지가 아니라 내 서버에서 돌아가는 서비스를 공개하는 방법을 다룬다.

목차

  1. Cloudflare Tunnel이 뭔가요? (동작 원리)
  2. 포트포워딩과 뭐가 다른가요? (장단점 비교)
  3. 준비물
  4. 따라하기 A: 대시보드로 만들기 (가장 쉬운 방법)
  5. 따라하기 B: 명령어(CLI)로 만들기
  6. 도커·쿠버네티스에서 돌리기
  7. 접근 제한 걸기 (Cloudflare Access)
  8. 자주 막히는 문제와 해결
  9. 주의사항과 한계
  10. 마무리 체크리스트

1. Cloudflare Tunnel이 뭔가요?

구성 요소는 단 두 개다.

  • cloudflared: 내 서버에 설치하는 작은 프로그램(데몬). Cloudflare 쪽으로 아웃바운드(나가는) 연결을 만들어 유지한다.
  • Cloudflare 네트워크: 방문자의 요청을 받아서, 이미 만들어진 그 연결을 통해 내 서버로 전달한다.

흐름은 이렇다.

방문자 → blog.example.com → Cloudflare(https 처리, 보호) → 터널 → cloudflared → 내 서버의 localhost:8080

비유하면, 보통 방식은 집 현관문을 열어 두고 손님을 기다리는 것이고 Tunnel은 내가 먼저 안내 데스크에 전화를 걸어 두고, 손님이 오면 그 전화로 연결받는 것이다. 현관문은 계속 잠겨 있다.

2. 포트포워딩과 뭐가 다른가요?

Cloudflare Tunnel의 장점

  • 공유기 포트를 열지 않는다. 집 공인 IP가 외부에 드러나지 않는다.
  • https 인증서가 자동이다. 서버에서 인증서를 발급·갱신할 필요가 없다.
  • 공인 IP가 없어도 된다. 통신사 CGNAT 환경이나 유동 IP에서도 동작한다.
  • DDoS 방어, 캐시, WAF 같은 Cloudflare의 보호 기능을 그대로 쓴다.
  • 무료 요금제에서 쓸 수 있다. (요금 정책은 바뀔 수 있으니 공식 페이지에서 확인)

단점·주의할 점

  • 도메인을 Cloudflare에 등록(네임서버 이전)해야 한다. 도메인이 없으면 쓸 수 없다.
  • 모든 트래픽이 Cloudflare를 거친다. 즉 Cloudflare를 신뢰해야 한다.
  • Cloudflare 약관상 대용량 영상·파일 스트리밍 같은 용도는 제한될 수 있다. 서비스별 정책을 확인할 것.
  • cloudflared가 죽으면 외부 접속도 같이 죽는다. 서비스로 등록해 자동 재시작하게 만들어야 한다.

3. 준비물

  • Cloudflare 계정 (무료)
  • Cloudflare에 등록된 내 도메인 (네임서버가 Cloudflare로 되어 있어야 함. 방법은 클라우드플레어 입문 참고)
  • 리눅스 서버 한 대 (Windows·macOS도 가능) 와 공개할 서비스 (예: http://localhost:8080)
  • 서버가 Cloudflare에 아웃바운드 7844 포트로 나갈 수 있을 것 (대부분의 가정용 공유기는 기본 허용)

4. 따라하기 A: 대시보드로 만들기 (추천)

공식 문서에서 권장하는 원격 관리(remotely-managed) 터널 방식이다. 설정이 Cloudflare 대시보드에 저장되어서, 서버에는 토큰 하나만 있으면 된다. (2026년 6월 기준 문서. 메뉴 이름은 바뀔 수 있다.)

  1. Cloudflare 대시보드에 로그인한 뒤 Networking > Tunnels (터널) 메뉴로 간다.
  2. Create a tunnel(터널 만들기)을 누르고 이름을 입력한다. 예: my-homeserver
  3. 운영체제를 고르면 설치 명령어가 나온다. 그대로 복사해서 서버 터미널에 붙여넣고 실행한다. 이 명령어에 토큰이 들어 있다.
  4. 대시보드에서 연결 상태가 Connected로 바뀔 때까지 기다린 뒤 Continue.
  5. 터널을 선택하고 Routes 탭 > Add route > Published application을 고른다.
  6. Subdomain(예: blog), Domain(내 도메인), Service URL(예: http://localhost:8080)을 입력하고 저장한다.
  7. 브라우저에서 https://blog.내도메인.com으로 접속해 본다.

팁: 서브도메인을 두 단계(예: a.b.example.com)로 쓰면 별도의 Advanced Certificate가 필요하다. 처음에는 한 단계 서브도메인으로 시작하자.

팁 2: 위 3번의 명령어에 든 토큰은 비밀번호와 같다. 블로그, 채팅, 깃허브에 올리지 말 것. 유출됐다면 대시보드에서 토큰을 재발급(Refresh token)한다.

5. 따라하기 B: 명령어(CLI)로 만들기

대시보드 대신 설정 파일로 관리하고 싶을 때 쓰는 로컬 관리(locally-managed) 터널 방식이다. 설정을 git으로 버전 관리하고 싶은 사람에게 맞다.

1) cloudflared 설치

# Rocky/CentOS/RHEL 계열 (rpm 직접 설치)
curl -L --output cloudflared.rpm https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm
sudo rpm -i cloudflared.rpm

# Debian/Ubuntu 계열
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb

2) 로그인 → 터널 생성 → DNS 연결 → 실행

cloudflared tunnel login
cloudflared tunnel create my-homeserver
cloudflared tunnel route dns my-homeserver blog.example.com
cloudflared tunnel run my-homeserver
  • tunnel login: 브라우저 인증 후 계정 인증서(cert.pem)가 만들어진다.
  • tunnel create: 터널과 자격 증명 파일(<UUID>.json)이 만들어진다. 이 파일도 비밀이다.
  • tunnel route dns: 도메인에 <UUID>.cfargotunnel.com을 가리키는 CNAME 레코드를 자동으로 만든다.

3) 설정 파일 ~/.cloudflared/config.yml 작성 — 서비스가 여러 개면 한 터널에 줄줄이 붙일 수 있다.

tunnel: <터널-UUID>
credentials-file: /root/.cloudflared/<터널-UUID>.json

ingress:
  - hostname: blog.example.com
    service: http://localhost:8080
  - hostname: git.example.com
    service: http://localhost:3000
  - service: http_status:404

맨 아래 http_status:404 줄은 어느 규칙에도 안 걸린 요청의 기본 응답이다. 반드시 있어야 한다.

4) 서비스로 등록해서 부팅 때 자동 실행

sudo cloudflared service install
sudo systemctl enable --now cloudflared

6. 도커·쿠버네티스에서 돌리기

서버에 프로그램을 직접 깔기 싫다면 컨테이너로 돌리면 된다. 대시보드에서 만든 터널의 토큰만 환경 변수로 넘기면 끝이다.

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${TUNNEL_TOKEN}

.env 파일에 TUNNEL_TOKEN=...을 넣고 docker compose up -d로 실행한다. 쿠버네티스(k3s 등)에서도 같은 이미지를 Deployment로 띄우고, 토큰은 Secret에 넣어 환경 변수로 주입하면 된다. 이때 Service URL은 http://localhost:8080 대신 클러스터 내부 서비스 주소(예: http://my-svc.my-ns.svc.cluster.local:80)를 쓴다. localhost는 cloudflared 컨테이너 자기 자신이기 때문이다.

7. 접근 제한 걸기 (Cloudflare Access)

터널로 공개하면 인터넷의 누구나 접속할 수 있다. 관리 페이지나 개인용 도구라면 Cloudflare Access로 로그인한 사람만 들어오게 막자.

  1. Zero Trust 대시보드에서 Access controls > Applications로 간다. (메뉴 이름은 개편될 수 있다.)
  2. Add an application > Self-hosted를 선택하고 공개한 도메인(예: git.example.com)을 입력한다.
  3. 정책(Policy)에서 허용할 이메일을 지정한다. 예: 내 이메일만 Allow.
  4. 이제 접속하면 이메일 인증 화면이 먼저 뜨고, 허용된 사람만 서비스에 도달한다.

무료 플랜에도 소규모 인원(수십 명 이하)까지는 쓸 수 있는 구간이 있지만, 한도와 조건은 바뀔 수 있으니 현재 요금 페이지를 확인하자.

8. 자주 막히는 문제와 해결

1) 접속하면 502 / 1033 오류

  • cloudflared가 떠 있는지 확인한다: systemctl status cloudflared
  • Service URL의 주소·포트가 맞는지 서버에서 curl http://localhost:8080으로 먼저 확인한다.
  • 컨테이너 안에서 돌린다면 localhost가 아니라 컨테이너/서비스 이름을 써야 한다.

2) 무한 리다이렉트 (ERR_TOO_MANY_REDIRECTS)

  • 내 서버가 이미 http → https 리다이렉트를 하고 있을 때 자주 생긴다. Service URL을 https://...로 바꾸고, 필요하면 대시보드의 Additional application settings > TLS > No TLS Verify(자체 서명 인증서일 때)를 확인한다. 공식 문서의 "HTTPS origins 문제 해결" 항목도 참고.
  • Cloudflare의 SSL/TLS 모드가 Flexible이면 같은 문제가 생기기 쉽다. Full 이상으로 맞춘다.

3) DNS 레코드가 안 생기거나 도메인이 안 열림

  • 도메인의 네임서버가 Cloudflare로 활성(Active) 상태인지 확인한다.
  • 같은 이름의 기존 A/CNAME 레코드가 있으면 충돌한다. DNS 메뉴에서 지우고 다시 연결한다.

4) 터널이 계속 끊김 / 연결 실패

  • 서버나 방화벽이 아웃바운드 7844 포트를 막고 있지 않은지 확인한다.
  • 기본 프로토콜은 auto로, QUIC(UDP)을 먼저 시도하고 안 되면 http2로 내려간다. UDP가 막힌 환경이면 --protocol http2로 고정하면 안정적이다.

상태 확인 명령어 모음

systemctl status cloudflared
journalctl -u cloudflared -n 50 --no-pager
curl -I https://blog.example.com

9. 주의사항과 한계

  • "포트를 안 열었으니 안전하다"는 착각 금지. 공개한 서비스 자체의 취약점·약한 비밀번호는 그대로 공격 대상이다. 관리 화면은 반드시 Access나 자체 2단계 인증으로 보호한다.
  • 토큰과 자격 증명 파일(cert.pem, <UUID>.json)은 깃에 올리지 않는다. 백업할 때도 암호화된 곳에만 보관한다.
  • cloudflared는 업데이트가 자주 나온다. 패키지 관리자로 설치했다면 수동 업데이트, 아니라면 기본 자동 업데이트(--no-autoupdate로 끌 수 있음)를 이해하고 쓴다. 공식 지원은 최신 릴리스 기준 1년 이내 버전이다.
  • Cloudflare가 장애가 나면 내 서비스도 같이 접속이 안 된다. 중요한 서비스라면 대체 경로를 생각해 둔다.
  • 용량이 큰 파일 전송·영상 스트리밍은 약관과 정책을 먼저 읽고 판단한다.

10. 상황별 추천

  • 정적인 홈페이지만 올리고 싶다 → 터널 말고 Cloudflare Pages가 더 간단하다.
  • 집 서버의 앱을 밖에서 쓰고 싶다 → 이 글의 대시보드 방식 + Access.
  • 서버 SSH에 밖에서 접속하고 싶다 → 포트 22를 여는 것보다 Tunnel + Access(또는 WireGuard 같은 VPN)가 안전하다.
  • 나 혼자 쓰는 내부 도구 → 공개 터널보다 VPN으로 사설망에 들어가는 방식이 더 좁게 열린다. 외부 공개가 꼭 필요한지부터 따져 보자.

마무리 체크리스트

  • □ 도메인이 Cloudflare에 Active 상태다
  • □ 터널을 만들고 cloudflared를 서비스로 등록했다 (재부팅 후에도 자동 실행)
  • □ Service URL이 서버에서 curl로 먼저 응답한다
  • □ 공유기에서 열어 둔 포트포워딩을 닫았다
  • □ 관리용 페이지에는 Access 또는 자체 인증을 걸었다
  • □ 토큰과 자격 증명 파일이 외부에 노출되지 않았다

포트를 열지 않고도 서비스를 공개할 수 있다는 점이 가장 큰 장점이다. 홈서버를 외부에 노출하는 게 걱정돼 망설였다면, 포트포워딩보다 먼저 이 방식을 검토해 볼 만하다.

이 글의 메뉴 이름과 절차는 Cloudflare 공식 문서(2026년 6월 업데이트 기준)를 참고했다. 대시보드 메뉴와 요금 정책은 바뀔 수 있으니 실제 화면과 공식 문서를 함께 확인하자.


댓글 0

글에 대한 질문이나 오류 제보는 문의하기로 보내 주세요.