홈 서버 만들기 시리즈
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을 처음부터 끝까지 설정하는 방법을 단계별로 안내합니다.
1. Cloudflare Tunnel이란? — 포트포워딩의 완벽한 대안
이전 편들에서 외부 접속을 위해 공유기의 포트포워딩을 사용했지만, 이 방식에는 근본적인 한계가 있습니다. 집의 공인 IP가 직접 노출되고, ISP가 특정 포트(445번 등)를 차단하며, 보안 취약점이 생깁니다.
Cloudflare Tunnel(이전 이름: Argo Tunnel)은 이 모든 문제를 해결합니다. 서버에서 Cloudflare의 글로벌 네트워크로 아웃바운드(나가는 방향) 연결을 먼저 맺기 때문에, 공유기에서 포트를 열 필요가 전혀 없습니다.
2. 시작 전 준비사항
이 가이드는 1편에서 우분투 서버 구축을 마친 상태를 기준으로 합니다. 아래 항목을 먼저 확인하세요.
| 준비사항 | 세부 내용 | 확인 |
|---|---|---|
| Ubuntu Server | Ubuntu 22.04 LTS 또는 24.04 LTS 실행 중 | ☐ |
| SSH 접속 | 터미널에서 서버에 SSH 접속 가능 | ☐ |
| 도메인 | 개인 도메인 1개 (없다면 섹션 3에서 구매 방법 안내) | ☐ |
| Cloudflare 계정 | 무료 계정 (섹션 3에서 생성 안내) | ☐ |
| 연결할 서비스 | Jellyfin(8096번 포트) 또는 기타 웹 서비스가 서버에서 실행 중 | ☐ |
.com 도메인 기준 연간 약 $10.44(약 14,000원)입니다.
3. Cloudflare 계정 생성 및 도메인 연결
① Cloudflare 무료 계정 생성
- Cloudflare 가입 페이지에 접속합니다.
- 이메일과 비밀번호를 입력하여 무료(Free) 플랜으로 가입합니다.
- 이메일 인증을 완료합니다.
② 도메인을 Cloudflare에 추가하기
이미 보유한 도메인이 있다면 Cloudflare에 추가하여 네임서버를 변경합니다. 도메인이 없다면 Cloudflare에서 직접 구매할 수도 있습니다.
- Cloudflare 대시보드에서 '사이트 추가(Add a Site)' 버튼을 클릭합니다.
- 보유한 도메인(예:
mydomain.com)을 입력하고 Free 플랜을 선택합니다. - Cloudflare가 기존 DNS 레코드를 자동으로 스캔합니다. 확인 후 '계속'을 클릭합니다.
- 화면에 표시되는 Cloudflare 네임서버 2개를 복사합니다.
- 도메인을 구매한 등록기관(가비아, 호스팅KR, Namecheap 등)의 관리 패널에서 네임서버를 Cloudflare에서 제공한 값으로 변경합니다.
- 네임서버 변경 후 Cloudflare 대시보드에서 '네임서버 확인'을 클릭합니다. 전파에 최대 24시간이 걸릴 수 있지만, 보통 10분~1시간 이내에 완료됩니다.
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 형태로 출력되면 설치가 완료된 것입니다.
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가 출력되면 설정이 올바른 것입니다.
nas.mydomain.com, blog.mydomain.com 등 여러 서브도메인으로 서버의 다른 서비스를 노출할 수 있습니다. 터널 1개로 무제한 서비스를 연결할 수 있어 매우 경제적입니다.
7. Tunnel 실행 및 시스템 서비스 등록
① 수동 실행으로 테스트
먼저 터널이 정상적으로 동작하는지 수동으로 실행해 봅니다.
cloudflared tunnel run homeserver
터미널에 Connection registered 메시지가 여러 줄 출력되면 터널이 정상적으로 Cloudflare 네트워크에 연결된 것입니다.
이 상태에서 PC나 스마트폰의 웹 브라우저를 열고 https://media.mydomain.com에 접속해 보세요. Jellyfin 로그인 화면이 나타나면 성공입니다! 🎉
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 대시보드 접속
- Cloudflare Zero Trust 대시보드에 접속합니다.
- 왼쪽 메뉴에서 Access → Applications를 클릭합니다.
- 'Add an Application' → 'Self-hosted'를 선택합니다.
② Application 설정
| 설정 항목 | 입력 값 |
|---|---|
| Application name | Jellyfin Media Server |
| Subdomain | media |
| Domain | mydomain.com |
| Session Duration | 24시간 (권장) |
③ 접근 정책(Policy) 설정
누가 접근할 수 있는지 정책을 설정합니다. 가장 간편한 방법은 이메일 인증(One-time PIN)입니다.
- Policy name:
AllowMyEmail - Action: Allow
- Include → Selector: Emails → Value: 본인 이메일 주소 입력
설정을 저장하면, https://media.mydomain.com에 접속할 때 먼저 Cloudflare 인증 화면이 나타나고, 허용된 이메일 주소로 전송된 인증 코드를 입력해야만 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 한 대와 무료 소프트웨어만으로 가능합니다. 설정 중 궁금한 점이 있다면 댓글로 남겨주세요! [여행 하는 미식가 '늘산' 의 지적 호기심 때문에 몸과 마음 이 편리해집니다.]