🖥️

홈 서버 만들기 시리즈

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

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 IDcredentials 파일 경로를 메모해 둡니다. 이후 설정에서 사용합니다.


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 + OEnter, 종료는 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 외부 접속 ← 지금 어디서나 안전한 접속

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

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

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