;

Cloudflare Tunnel로 집 서버 외부 접속 열기 본문

Programing

Cloudflare Tunnel로 집 서버 외부 접속 열기

WindowsHyun 2026. 7. 3. 21:40
반응형

개요

본 포스트는 Cloudflare Tunnel을 이용해 집 서버를 외부에 공개하는 과정을 설명합니다. 공유기에서 포트를 직접 열지 않고도 도메인으로 접속하게 만드는 흐름만 추려서 정리했습니다.

홈서버에 n8n이나 Firefly III 같은 웹 서비스를 올려 두었다면 외부 접속이 필요해지는 시점이 옵니다. 예전에 정리한 https://windowshyun.tistory.com/48 같은 셀프호스팅 글을 따라 했다면, 그 다음 단계가 보통 외부 공개입니다. 여기서는 공인 IP 노출과 포트포워딩 부담을 줄이는 방식에 집중합니다.

실제 문제 상황

집 서버를 외부에 열 때 처음 부딪히는 건 포트포워딩입니다. 공유기 설정을 바꿔야 하고, 공인 IP가 바뀌면 DDNS까지 같이 신경 써야 합니다. 서비스가 여러 개면 포트 관리도 금방 번거로워집니다.

Cloudflare Tunnel은 서버에서 Cloudflare 쪽으로 아웃바운드 연결을 만들고, 사용자는 Cloudflare 도메인으로 들어오게 하는 구조입니다. 그래서 집 네트워크 쪽 인바운드 포트를 따로 열지 않아도 됩니다.

전체 구성 흐름

집 서버: localhost:8080 같은 내부 주소에서 웹 서비스 실행.

cloudflared: 서버에서 Cloudflare Edge로 outbound tunnel 유지.

Cloudflare DNS: app.example.com을 tunnel에 연결.

외부 사용자: 집 공인 IP 대신 도메인으로 접속.

사전 준비 사항

  • Cloudflare에 연결된 도메인이 있어야 합니다.
  • 집 서버에서 cloudflared 명령을 실행할 수 있어야 합니다.
  • 외부에 공개할 웹 서비스가 http://localhost:8080 같은 내부 주소에서 이미 떠 있어야 합니다.
  • 테스트 단계에서는 서비스 방화벽과 로컬 bind 주소를 같이 확인해두시면 됩니다.

외부 공개 전에는 관리자 페이지, 데이터베이스 대시보드, 내부 전용 앱을 바로 열지 말고 인증 정책부터 같이 검토하는 것을 권장합니다.

적용 대상

홈서버 웹앱 공개: n8n, Firefly III, 개인 대시보드처럼 브라우저로 보는 서비스.

포트포워딩 회피: 공유기 설정 접근이 어렵거나 집 공인 IP를 직접 드러내고 싶지 않은 경우.

테스트 공개: 도메인 접속만 빠르게 확인하고 싶은 경우.

적용 제외: 대용량 파일 전송 위주 서비스나, 장시간 세션이 많은 환경은 바로 붙이기보다 성능과 정책을 우선 확인합니다.

1. cloudflared 로그인

Cloudflare 계정과 도메인 권한을 연결하려면 로그인합니다.

cloudflared tunnel login

브라우저가 열리면 사용할 zone을 선택해주시면 됩니다. 완료되면 ~/.cloudflared/ 아래에 인증서 파일이 생깁니다.

2. tunnel 생성

이제 이름을 정해 tunnel을 만듭니다.

cloudflared tunnel create home-server

실행 결과에는 tunnel UUID와 credentials 파일 경로가 같이 나옵니다. 이 값은 뒤에서 config.yml에 그대로 들어갑니다.

도메인을 연결할 때는 아래 명령을 사용합니다.

cloudflared tunnel route dns home-server app.example.com

이 단계가 끝나면 app.example.com이 방금 만든 tunnel로 연결됩니다.

3. 설정 파일 작성

반복 실행할 때는 실행 옵션을 매번 길게 쓰기보다 설정 파일로 고정하는 편이 관리하기 쉽습니다.

~/.cloudflared/config.yml 예시는 아래와 같습니다.

tunnel: 11111111-2222-3333-4444-555555555555
credentials-file: /home/<USER>/.cloudflared/11111111-2222-3333-4444-555555555555.json
ingress:
  - hostname: app.example.com
    service: http://localhost:8080
  - service: http_status:404

tunnel: cloudflared tunnel create 결과로 받은 UUID.

credentials-file: 생성된 JSON 파일 경로.

hostname: 외부에 공개할 도메인.

service: 실제 내부 웹 서비스 주소.

마지막 http_status:404는 매칭되지 않은 요청을 정리하는 기본 fallback입니다.

4. 포그라운드 실행 확인

설정 파일을 만든 뒤에는 포그라운드에서 접속이 되는지 확인합니다.

cloudflared tunnel run home-server

별도 설정 파일 경로를 쓰고 있다면 아래처럼 지정할 수 있습니다.

cloudflared tunnel --config ~/.cloudflared/config.yml run home-server

이 상태에서 브라우저로 https://app.example.com에 접속해보시면 됩니다. 내부 서비스 첫 화면이 열리면 기본 연결은 된 상태입니다.

5. 서비스 등록

부팅 후에도 자동으로 유지하려면 서비스 등록을 같이 해두면 됩니다.

sudo cloudflared service install

설치 후에는 운영체제 서비스 관리 방식으로 상태를 확인합니다. Linux라면 아래처럼 볼 수 있습니다.

systemctl status cloudflared

포그라운드 확인 없이 바로 서비스부터 올리면 문제 원인을 찾기 어려워집니다. 처음 한 번은 tunnel run으로 접속을 확인해두시면 됩니다.

주요 오류 및 해결 방안

브라우저에서 502나 503이 뜸: 제 경우 원인은 대부분 tunnel 문제가 아니라 내부 서비스가 localhost:8080에서 실제로 떠 있지 않은 경우였습니다. 서버 안에서 curl http://localhost:8080이 열리는지 확인합니다.

도메인이 연결되지 않음: cloudflared tunnel route dns를 실행할 때 zone 선택이 잘못됐을 가능성이 높습니다. 로그인한 계정에 해당 도메인 권한이 있는지 다시 확인합니다.

서비스 등록 후 접속이 안 됨: 포그라운드에서는 됐는데 서비스에서는 안 되는 경우가 있습니다. 이때는 서비스 계정이 읽는 config.yml 경로와 credentials 파일 권한이 다른 경우가 많습니다.

관리자 페이지를 바로 공개함: 외부 접속 자체는 열렸는데 인증 정책 없이 관리자 화면을 그대로 노출하는 경우가 있습니다. 이 경우 Access 정책이나 별도 인증 구성을 함께 붙이는 쪽이 안전합니다.

확인

마지막으로 아래 순서로 점검합니다.

cloudflared tunnel list
cloudflared tunnel route dns home-server app.example.com
cloudflared tunnel --config ~/.cloudflared/config.yml run home-server

app.example.com 접속 시 내부 웹 서비스가 열리면 정상적으로 연결된 것입니다.

반응형
Comments