🖥️

홈 서버 만들기 시리즈

1편 → 남는 PC로 개인 서버 만들기 → 2편 → Samba로 나만의 NAS 만들기 → 3편 → Jellyfin 미디어 서버 구축 → 4편 ← 지금 여기 → 5편 → VNC 원격 접속

Cloudflare Tunnel로 외부에서 안전하게 내 서버에 접속하기

1편에서 남는 PC에 우분투 서버를 설치하고, 2편에서 Samba NAS를 구축했으며, 3편에서 Jellyfin 미디어 서버까지 완성했습니다. 이제 남은 마지막 퍼즐 한 조각 — '외부에서 접속'입니다.

카페에서 내 NAS 파일을 열고 싶거나, 출장 중 호텔에서 Jellyfin으로 영화를 스트리밍하고 싶은 순간이 올 것입니다. 그런데 공유기 포트포워딩은 보안상 위험하고, ISP(인터넷 서비스 제공자)가 특정 포트를 원천 차단하기도 합니다.

해결책은 Cloudflare Tunnel입니다. 포트를 전혀 열지 않고, 공인 IP 노출 없이, 무료 HTTPS까지 자동 적용하여 전 세계 어디서든 안전하게 내 홈 서버에 접속할 수 있습니다. 이번 4편에서는 Cloudflare Tunnel을 처음부터 끝까지 설정하는 방법을 단계별로 안내합니다.

Cloudflare Tunnel을 활용한 홈 서버 외부 접속 구성도 — 포트포워딩 없이 안전하게 연결
Cloudflare Tunnel을 사용하면 공인 IP를 노출하지 않고도 외부에서 안전하게 홈 서버에 접속할 수 있습니다.

1. Cloudflare Tunnel이란? — 포트포워딩의 완벽한 대안

이전 편들에서 외부 접속을 위해 공유기의 포트포워딩을 사용했지만, 이 방식에는 근본적인 한계가 있습니다. 집의 공인 IP가 직접 노출되고, ISP가 특정 포트(445번 등)를 차단하며, 보안 취약점이 생깁니다.

Cloudflare Tunnel(이전 이름: Argo Tunnel)은 이 모든 문제를 해결합니다. 서버에서 Cloudflare의 글로벌 네트워크로 아웃바운드(나가는 방향) 연결을 먼저 맺기 때문에, 공유기에서 포트를 열 필요가 전혀 없습니다.

❌ 포트포워딩 방식

위험하고 제한적

  • 집 공인 IP가 외부에 직접 노출
  • ISP가 특정 포트(445 등) 원천 차단
  • DDoS, 랜섬웨어 공격에 취약
  • 공인 IP 변경 시 접속 불가
  • HTTPS(SSL) 별도 설정 필요

✅ Cloudflare Tunnel

안전하고 무료

  • 공인 IP 노출 없음 (Zero Trust)
  • 포트 개방 불필요 — ISP 차단 무관
  • Cloudflare의 DDoS 방어 자동 적용
  • 동적 IP 환경에서도 항상 접속 가능
  • HTTPS(SSL) 자동 적용 — 설정 불필요
💡 작동 원리를 쉽게 이해하기: 일반 포트포워딩은 '집 현관문(포트)을 열어두고 손님을 기다리는 것'이라면, Cloudflare Tunnel은 '집에서 Cloudflare 본사까지 전용 비밀 지하통로를 파 놓는 것'입니다. 외부 방문자는 Cloudflare를 통해서만 접근하고, 집의 위치(IP)는 절대 노출되지 않습니다.

2. 시작 전 준비사항

이 가이드는 1편에서 우분투 서버 구축을 마친 상태를 기준으로 합니다. 아래 항목을 먼저 확인하세요.

준비사항 세부 내용 확인
Ubuntu Server Ubuntu 22.04 LTS 또는 24.04 LTS 실행 중 ☐
SSH 접속 터미널에서 서버에 SSH 접속 가능 ☐
도메인 개인 도메인 1개 (없다면 섹션 3에서 구매 방법 안내) ☐
Cloudflare 계정 무료 계정 (섹션 3에서 생성 안내) ☐
연결할 서비스 Jellyfin(8096번 포트) 또는 기타 웹 서비스가 서버에서 실행 중 ☐
⚠️ 도메인이 꼭 필요한가요? 네, Cloudflare Tunnel은 Cloudflare에 등록된 도메인을 통해 동작합니다. 도메인은 연간 1만 원 미만으로 구매할 수 있으며, Cloudflare에서 직접 등록하면 원가에 가까운 가격으로 구매 가능합니다. .com 도메인 기준 연간 약 $10.44(약 14,000원)입니다.

3. Cloudflare 계정 생성 및 도메인 연결

① Cloudflare 무료 계정 생성

  1. Cloudflare 가입 페이지에 접속합니다.
  2. 이메일과 비밀번호를 입력하여 무료(Free) 플랜으로 가입합니다.
  3. 이메일 인증을 완료합니다.

② 도메인을 Cloudflare에 추가하기

이미 보유한 도메인이 있다면 Cloudflare에 추가하여 네임서버를 변경합니다. 도메인이 없다면 Cloudflare에서 직접 구매할 수도 있습니다.

  1. Cloudflare 대시보드에서 '사이트 추가(Add a Site)' 버튼을 클릭합니다.
  2. 보유한 도메인(예: mydomain.com)을 입력하고 Free 플랜을 선택합니다.
  3. Cloudflare가 기존 DNS 레코드를 자동으로 스캔합니다. 확인 후 '계속'을 클릭합니다.
  4. 화면에 표시되는 Cloudflare 네임서버 2개를 복사합니다.
  5. 도메인을 구매한 등록기관(가비아, 호스팅KR, Namecheap 등)의 관리 패널에서 네임서버를 Cloudflare에서 제공한 값으로 변경합니다.
  6. 네임서버 변경 후 Cloudflare 대시보드에서 '네임서버 확인'을 클릭합니다. 전파에 최대 24시간이 걸릴 수 있지만, 보통 10분~1시간 이내에 완료됩니다.
✅ 확인 완료! Cloudflare 대시보드의 도메인 상태가 '활성(Active)'으로 표시되면 다음 단계로 진행할 수 있습니다.

4. 우분투 서버에 cloudflared 설치

cloudflared는 Cloudflare Tunnel을 구동하는 경량 데몬 프로그램입니다. 우분투 서버에서 이 프로그램이 Cloudflare 네트워크와의 보안 연결을 담당합니다.

SSH로 우분투 서버에 접속한 상태에서 아래 명령어를 순서대로 실행합니다.

① Cloudflare 공식 GPG 키 추가

curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
  | sudo tee /usr/share/keyrings/cloudflare-main.gpg > /dev/null

② 공식 APT 저장소 추가

echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] \
https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list

③ 패키지 설치

sudo apt update
sudo apt install cloudflared -y

④ 설치 확인

cloudflared --version

cloudflared version 2024.x.x 형태로 출력되면 설치가 완료된 것입니다.

💡 꿀팁: cloudflared는 Cloudflare의 공식 저장소에서 설치하므로 sudo apt update && sudo apt upgrade 명령어로 시스템 업데이트 시 자동으로 최신 버전을 유지합니다.

5. Tunnel 생성 및 인증

① Cloudflare 계정 인증 (로그인)

서버에서 Cloudflare 계정에 인증을 진행합니다. 아래 명령어를 실행하면 인증용 URL이 터미널에 표시됩니다.

cloudflared tunnel login

터미널에 출력되는 URL을 복사하여 PC나 스마트폰의 웹 브라우저에서 열고, Cloudflare 계정으로 로그인한 뒤 터널에 사용할 도메인을 선택합니다. 인증이 완료되면 터미널에 You have successfully logged in. 메시지가 출력됩니다.

💡 참고: 인증 정보는 ~/.cloudflared/cert.pem 파일로 저장됩니다. 이 파일은 다시 발급받을 수 있으므로 서버 재설치 시에도 걱정 없습니다.

② 터널 생성

인증이 완료되었으면 터널을 생성합니다. 터널 이름은 알아보기 쉬운 이름을 자유롭게 지정합니다.

cloudflared tunnel create homeserver

명령어 실행 후 아래와 비슷한 출력이 나타납니다.

Tunnel credentials written to /root/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json
Created tunnel homeserver with id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

여기서 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 형태의 Tunnel ID와 credentials 파일 경로를 메모해 둡니다. 이후 설정에서 사용합니다.


6. Tunnel 설정 — Jellyfin & 웹 서비스 연결

터널이 어떤 도메인으로 들어오는 요청을 서버의 어떤 서비스로 전달할지 설정합니다. 설정 파일 하나로 여러 서비스를 동시에 연결할 수 있습니다.

① 설정 파일 생성

sudo nano ~/.cloudflared/config.yml

아래 내용을 입력합니다. TUNNEL_ID 부분을 앞서 메모한 실제 Tunnel ID로, mydomain.com을 본인의 도메인으로 교체하세요.

tunnel: TUNNEL_ID
credentials-file: /root/.cloudflared/TUNNEL_ID.json

ingress:
  # Jellyfin 미디어 서버
  - hostname: media.mydomain.com
    service: http://localhost:8096

  # 추가 서비스 예시 (필요 시 주석 해제)
  # - hostname: nas.mydomain.com
  #   service: http://localhost:8080

  # 위 규칙에 해당하지 않는 모든 요청 — 반드시 맨 마지막에 위치
  - service: http_status:404

저장은 Ctrl + O → Enter, 종료는 Ctrl + X입니다.

설정 항목 설명
tunnel 앞서 생성한 Tunnel의 UUID
credentials-file 터널 인증 정보가 담긴 JSON 파일 경로
hostname 외부에서 접속할 서브도메인 주소
service 요청을 전달할 로컬 서비스 주소와 포트
http_status:404 매칭되지 않는 요청에 404 응답 (필수 catch-all 규칙)

② DNS 레코드 등록

설정 파일에 적은 hostname이 실제로 Cloudflare DNS에 등록되어야 합니다. 아래 명령어 하나로 자동 등록됩니다.

# Jellyfin용 서브도메인 DNS 등록
cloudflared tunnel route dns homeserver media.mydomain.com

이 명령어는 Cloudflare DNS에 media.mydomain.com → 터널로 연결하는 CNAME 레코드를 자동으로 생성합니다.

③ 설정 파일 검증

설정 파일에 오류가 없는지 검증합니다.

cloudflared tunnel ingress validate

OK가 출력되면 설정이 올바른 것입니다.

✅ 여러 서비스를 하나의 터널로: ingress 규칙을 추가하면 nas.mydomain.com, blog.mydomain.com 등 여러 서브도메인으로 서버의 다른 서비스를 노출할 수 있습니다. 터널 1개로 무제한 서비스를 연결할 수 있어 매우 경제적입니다.

7. Tunnel 실행 및 시스템 서비스 등록

① 수동 실행으로 테스트

먼저 터널이 정상적으로 동작하는지 수동으로 실행해 봅니다.

cloudflared tunnel run homeserver

터미널에 Connection registered 메시지가 여러 줄 출력되면 터널이 정상적으로 Cloudflare 네트워크에 연결된 것입니다.

이 상태에서 PC나 스마트폰의 웹 브라우저를 열고 https://media.mydomain.com에 접속해 보세요. Jellyfin 로그인 화면이 나타나면 성공입니다! 🎉

✅ 놀라운 점: URL이 자동으로 https://입니다! Cloudflare가 SSL 인증서를 무료로 자동 발급·갱신해 주기 때문에, Let's Encrypt나 certbot 같은 별도 SSL 설정이 전혀 필요 없습니다.

테스트가 확인되면 Ctrl + C로 수동 실행을 중지합니다.

② 시스템 서비스로 등록 (자동 시작)

서버 재부팅 시에도 터널이 자동으로 시작되도록 systemd 서비스로 등록합니다.

sudo cloudflared service install

이 명령어 하나로 systemd 서비스 파일이 자동 생성되고, 부팅 시 자동 시작이 등록됩니다.

③ 서비스 상태 확인

sudo systemctl status cloudflared

Active: active (running)이 초록색으로 표시되면 터널이 백그라운드에서 정상적으로 동작 중입니다. q를 눌러 빠져나옵니다.

④ 유용한 서비스 관리 명령어

명령어 설명
sudo systemctl restart cloudflared 설정 변경 후 터널 재시작
sudo systemctl stop cloudflared 터널 중지
sudo systemctl enable cloudflared 부팅 시 자동 시작 활성화
sudo journalctl -u cloudflared -f 실시간 로그 확인 (디버깅용)

8. Cloudflare Access로 보안 강화하기

Cloudflare Tunnel로 외부 접속이 가능해졌지만, URL을 아는 사람이라면 누구나 Jellyfin 로그인 화면에 접근할 수 있습니다. Cloudflare Access를 활용하면 로그인 페이지 자체에 접근하기 전에 한 번 더 인증을 거치도록 설정할 수 있습니다.

① Cloudflare Zero Trust 대시보드 접속

  1. Cloudflare Zero Trust 대시보드에 접속합니다.
  2. 왼쪽 메뉴에서 Access → Applications를 클릭합니다.
  3. 'Add an Application' → 'Self-hosted'를 선택합니다.

② Application 설정

설정 항목 입력 값
Application name Jellyfin Media Server
Subdomain media
Domain mydomain.com
Session Duration 24시간 (권장)

③ 접근 정책(Policy) 설정

누가 접근할 수 있는지 정책을 설정합니다. 가장 간편한 방법은 이메일 인증(One-time PIN)입니다.

  1. Policy name: AllowMyEmail
  2. Action: Allow
  3. Include → Selector: Emails → Value: 본인 이메일 주소 입력

설정을 저장하면, https://media.mydomain.com에 접속할 때 먼저 Cloudflare 인증 화면이 나타나고, 허용된 이메일 주소로 전송된 인증 코드를 입력해야만 Jellyfin 페이지에 접근할 수 있습니다.

✅ 이중 보안 완성: 이제 외부 접속 경로는 Cloudflare Tunnel(암호화된 터널) + Cloudflare Access(이메일 인증) + Jellyfin 자체 로그인, 총 3중 보안으로 보호됩니다. 포트포워딩과는 차원이 다른 안전성입니다.
⚠️ Jellyfin 앱 사용 시 참고: Cloudflare Access를 활성화하면 스마트폰 Jellyfin 앱에서 직접 접속 시 인증 화면 처리가 복잡해질 수 있습니다. 이 경우 Access 정책에서 Bypass 규칙을 추가하거나, 앱 전용 Service Token을 발급하여 앱 헤더에 설정하는 방법이 있습니다. Jellyfin 웹 브라우저 접속만 사용하신다면 위 설정만으로 충분합니다.

9. 자주 발생하는 오류 및 해결 방법

증상 원인 해결 방법
502 Bad Gateway 로컬 서비스(Jellyfin 등)가 실행 중이 아님 sudo systemctl status jellyfin으로 확인 후 sudo systemctl start jellyfin으로 실행
ERR_NAME_NOT_RESOLVED DNS 레코드 미등록 또는 전파 미완료 cloudflared tunnel route dns homeserver media.mydomain.com 재실행 후 5~10분 대기
config.yml 오류 YAML 들여쓰기 오류 (탭 대신 스페이스 사용 필수) cloudflared tunnel ingress validate로 검증 후 오류 메시지 확인
tunnel not found 오류 config.yml의 tunnel ID가 실제 터널과 불일치 cloudflared tunnel list로 정확한 터널 ID 확인 후 config.yml 수정
서비스 시작 실패 config.yml 경로를 서비스가 찾지 못함 설정 파일을 /etc/cloudflared/config.yml로 복사: sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
💡 디버깅 팁: 문제가 발생하면 아래 명령어로 실시간 로그를 확인하세요. 대부분의 오류 원인을 로그에서 바로 파악할 수 있습니다.
sudo journalctl -u cloudflared -f --no-pager

마치며: 홈 서버의 완성, 세상 어디서나 내 서버에 접속하다

축하합니다! 🎉 1편에서 시작한 '집에 남는 PC로 나만의 서버 만들기' 시리즈가 이번 4편으로 하나의 완성된 시스템을 이루었습니다.

🏠 홈 서버 완성 로드맵

1편 VirtualBox + 우분투 서버 구축 서버 기반 마련
2편 Samba 설치로 NAS 구축 파일 공유 시스템
3편 Jellyfin 미디어 서버 설치 나만의 넷플릭스
4편 Cloudflare Tunnel 외부 접속 ← 지금 어디서나 안전한 접속
5편 윈도우11 VNC 원격 접속 가이드 GUI 원격 제어
비교 Tailscale vs Cloudflare WARP/터널 비교 외부 접속 솔루션 비교

이제 여러분의 홈 서버는 집 안에서만 쓸 수 있는 단순한 로컬 서버가 아닙니다. 전 세계 어디서든 안전하게 접속할 수 있는, 여러분만의 프라이빗 클라우드 인프라가 완성되었습니다.

  • 카페에서 노트북으로 NAS 파일에 접근하고
  • 출장 중 호텔에서 Jellyfin으로 영화를 스트리밍하고
  • 해외 여행 중에도 집 서버의 데이터를 안전하게 사용할 수 있습니다

이 모든 것이 매달 구독료 없이, 집에 남는 PC 한 대와 무료 소프트웨어만으로 가능합니다. 설정 중 궁금한 점이 있다면 댓글로 남겨주세요! [여행 하는 미식가 '늘산' 의 지적 호기심 때문에 몸과 마음 이 편리해집니다.]