본문 바로가기
IT/Nas

[Nas] Cloudflare Tunnel 연결 끊김? 5가지 해결법과 최적화 팁

by 수누다 2026. 6. 5.

안녕하세요, 13년차 인프라 엔지니어 '13년차의 서버실'입니다. 집에서 홈랩(Homelab)을 운영하며 다양한 서비스를 돌리는데, 외부에서 접속이 안 돼서 답답했던 경험, 다들 있으시죠?

저도 예전엔 공유기 포트포워딩(Port Forwarding)이나 VPN(Virtual Private Network) 서버 구축으로 해결했어요. 근데 보안적으로나 관리적으로나 신경 쓸 게 한두 가지가 아니더라고요. 특히 포트포워딩은 외부 공격에 노출될 위험이 있어서 항상 불안했습니다.

이런 고민을 한 방에 날려준 게 바로 Cloudflare Tunnel(클라우드플레어 터널)입니다. 제로 트러스트(Zero Trust) 개념을 기반으로 안전하고 쉽게 내부망 자원에 접근할 수 있거든요. 마치 클라우드플레어 네트워크가 우리 서버의 '문지기' 역할을 해주면서, 외부에서 직접 들어오는 길을 완전히 막아버리는 셈이죠.

근데 이게 가끔 말썽을 부릴 때가 있어요. Cloudflare Tunnel이 연결이 끊기거나 아예 접속이 안 되는 경우 말이죠. 저도 처음엔 '뭐가 문제지?' 싶어서 삽질을 꽤 했습니다. ㅎㅎ 오늘은 제가 직접 겪었던 Cloudflare Tunnel 연결 문제를 해결하는 5단계와 더 안정적으로 운영할 수 있는 최적화 팁까지 풀어보겠습니다. 비슷한 경험을 하고 계시다면 꼭 도움이 될 거예요!

Cloudflare Tunnel을 이용한 안전한 원격 접속 환경의 전체 구성도입니다. 클라이언트, Cloudflare 엣지, Tunnel, 그리고 내부 서버 간의 연결 흐름을 한눈에 볼 수 있습니다.

💡 Cloudflare Tunnel이란? (쉽게 풀어보기)

Cloudflare Tunnel은 내부 네트워크의 자원(웹 서버, SSH, RDP 등)을 인터넷에 직접 노출하지 않고, Cloudflare의 글로벌 엣지(Edge) 네트워크를 통해 안전하게 접근할 수 있도록 해주는 서비스입니다. 기존의 포트포워딩이나 VPN과 다르게, 내부망으로 들어오는 인바운드(Inbound) 포트를 열 필요가 없다는 게 가장 큰 장점이에요.

우리 서버에 cloudflared라는 경량 데몬(daemon)을 설치하면, 이 데몬이 Cloudflare 엣지 네트워크와 아웃바운드(Outbound) 연결을 맺어요. 클라이언트가 특정 도메인으로 접속하면, Cloudflare 엣지가 요청을 받아 cloudflared가 만들어놓은 터널을 통해 내부 자원으로 안전하게 전달하는 방식입니다. 모든 트래픽은 암호화되어 흐르기 때문에 보안성도 정말 높습니다. 매력적이죠?

✅ Cloudflare Tunnel 연결 문제 해결 5단계

자, 이제 Cloudflare Tunnel 오류를 해결하고 더 안정적으로 운영할 수 있는 실전 가이드를 알아볼게요. 제가 직접 해보면서 터득한 5단계를 따라가시면 대부분의 문제를 해결할 수 있습니다.

1. cloudflared 서비스 상태 확인

가장 먼저 확인해야 할 건 역시 cloudflared 데몬이 잘 실행되고 있는지입니다. 이게 멈춰있으면 당연히 Cloudflare Tunnel 연결이 안 되겠죠? 서버에 접속해서 다음 명령어로 상태를 확인해 보세요.

sudo systemctl status cloudflared

만약 inactive (dead) 상태라면, 서비스를 재시작합니다.

sudo systemctl start cloudflared
sudo systemctl enable cloudflared # 재부팅 시 자동 시작 설정

서비스가 active (running)상태인데도 문제가 있다면 로그를 확인해야 해요. journalctl 명령어로 최근 로그를 보면 단서를 찾을 수 있습니다.

sudo journalctl -u cloudflared.service --since "5 minutes ago"

에러 메시지나 경고(Warning)가 보인다면, 그 내용을 바탕으로 구글링을 시작할 수 있어요.

2. Tunnel 설정 파일(config.yml) 점검

다음은 설정 파일이 정확한지 확인해야 합니다. /etc/cloudflared/config.yml (혹은 다른 경로)의 설정 파일은 YAML(YAML Ain't Markup Language) 문법으로 작성되는데, 스페이스나 탭, 오타 하나에도 오류가 생기기 쉬워요. 특히 hostname이나 service 경로에 오타가 없는지 꼼꼼히 확인해 보세요.

Cloudflare에서 제공하는 유틸리티로 설정 파일의 유효성을 검사할 수 있습니다.

cloudflared tunnel validate --config /etc/cloudflared/config.yml

설정 파일에 문제가 있으면 어떤 부분이 잘못되었는지 알려줍니다. 저는 자주 service URL을 http://localhost:80 대신 http://localhost:80/ 처럼 슬래시를 빼먹거나 더 넣는 실수를 했어요. 아래는 일반적인 config.yml 예시입니다.

tunnel: <YOUR_TUNNEL_UUID>
credentials-file: /root/.cloudflared/<YOUR_TUNNEL_UUID>.json

ingress:
  - hostname: myapp.example.com
    service: http://localhost:8080
  - hostname: ssh.example.com
    service: ssh://localhost:22
    # Cloudflare Access를 통한 SSH 접근 시 필요
    originRequest:
      noTLSVerify: true # 개발 환경에서만 사용 권장
  - service: http_status:404 # 일치하는 규칙이 없을 경우 404 반환

3. DNS 레코드 확인

Cloudflare Tunnel은 DNS(Domain Name System) 레코드와 연동되어 작동합니다. 설정한 도메인이 터널과 제대로 연결되어 있는지 확인해 보세요. Cloudflare 대시보드(Dashboard)에서 해당 도메인의 DNS 설정으로 이동해 CNAME(Canonical Name) 레코드를 확인합니다.

보통 Cloudflare Tunnel을 만들고 도메인을 연결하면 자동으로 CNAME 레코드가 생성되는데, 가끔 이게 삭제되거나 잘못 변경되곤 해요. CNAME 레코드의 Name은 접속할 도메인(예: myapp), Target<YOUR_TUNNEL_UUID>.cfargotunnel.com 형태여야 합니다.

# cloudflared 명령어로 DNS 라우팅 상태를 확인해볼 수도 있습니다.
cloudflared tunnel route dns myapp.example.com <YOUR_TUNNEL_NAME_OR_UUID>
Cloudflare 대시보드에서 Tunnel의 DNS CNAME 레코드 설정 화면

Cloudflare 대시보드에서 Tunnel에 연결된 DNS CNAME 레코드를 확인하는 화면입니다. 올바른 호스트네임과 Tunnel ID가 지정되었는지 점검하는 데 필수적인 부분이죠.

4. Cloudflare 엣지 네트워크 연결 확인

간혹 Cloudflare 엣지 네트워크 자체에 문제가 생기거나, 우리 서버와 엣지 간의 네트워크 경로에 이상이 생길 수 있어요. 드물지만 이런 경우도 있더라고요.

  • cloudflared tunnel health 확인: 터널의 전반적인 상태를 한눈에 볼 수 있습니다.
cloudflared tunnel health <YOUR_TUNNEL_NAME_OR_UUID>
  • 네트워크 연결 테스트: 서버에서 Cloudflare의 공용 DNS 서버(예: 1.1.1.1)로 ping이나 traceroute를 시도해서 네트워크 상태를 확인해 보세요.
ping 1.1.1.1
traceroute 1.1.1.1
  • 방화벽(Firewall) 확인: 서버의 방화벽(ufw, firewalld 등)에서 cloudflared의 아웃바운드 연결을 막고 있지는 않은지 확인합니다. Cloudflare 엣지 네트워크로의 443/TCP 아웃바운드 트래픽은 꼭 허용되어야 합니다.

5. cloudflared 재설치 또는 버전 업그레이드

위 단계를 다 해봐도 Cloudflare Tunnel 연결 문제가 해결되지 않는다면, cloudflared 자체에 문제가 있거나 버전이 너무 오래되었을 가능성이 있어요. 저도 예전에 구버전 때문에 꽤나 애먹었거든요. 최신 버전으로 업데이트하거나 재설치해보세요.

  • 업데이트:
cloudflared update
  • 재설치 (Debian/Ubuntu 기준):
sudo apt remove cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
sudo cloudflared service install # 서비스 재설치
sudo systemctl start cloudflared

업데이트 후엔 항상 서비스를 재시작하는 것 잊지 마세요! sudo systemctl restart cloudflared

⚠️ 제가 겪었던 흔한 삽질들 (Troubleshooting Tips)

13년차 엔지니어라고 다 아는 건 아니더라고요. Cloudflare Tunnel 운영하면서 다양한 삽질을 겪었는데, 몇 가지 공유해 드릴게요.

  • 높은 메모리(Memory)/CPU 사용량: 가끔 cloudflared 프로세스가 과도하게 리소스를 사용할 때가 있어요. top이나 htop 명령어로 확인하고, 그렇다면 터널 설정을 점검하거나 너무 많은 서비스를 하나의 터널에 연결한 건 아닌지 확인해 보세요. 용도에 따라 터널을 분리하는 것도 좋은 방법입니다.
  • Cloudflare WAF(Web Application Firewall) 또는 Rate Limiting: Cloudflare에서 설정한 보안 규칙이 의도치 않게 여러분의 트래픽을 막을 수 있어요. Cloudflare 대시보드의 'Security(보안)' 섹션에서 'Events(이벤트)' 로그를 확인해 보세요.
  • Origin(오리진) 서버의 문제: 터널 자체는 잘 작동하는데, 뒤에 있는 실제 서비스(웹 서버 등)가 죽어있을 수도 있어요. http://localhost:8080 같은 로컬 URL로 직접 접속해서 서비스가 살아있는지 확인해 보세요.
  • 로그 레벨(Log Level) 조정: 문제 발생했을 때 config.yml 파일에 loglevel: debug를 추가하면 더 자세한 로그를 얻을 수 있어요. 디버그 로그는 정말 신의 한 수입니다.
Cloudflare Tunnel의 연결 상태 및 트래픽 현황을 보여주는 대시보드 시각화 차트

Cloudflare 대시보드에서 Tunnel의 실시간 연결 상태와 트래픽 패턴을 모니터링하는 차트입니다. 연결이 끊어졌을 때 어떤 지표가 변하는지 확인할 수 있죠.

🚀 Cloudflare Tunnel 최적화 팁

연결 끊김 문제를 해결했다면, 이제 더 안정적이고 효율적으로 터널을 운영하기 위한 최적화 팁들을 알아볼까요?

1. 로드 밸런싱(Load Balancing) 활용

하나의 Origin 서버에 트래픽이 몰리는 것을 피하기 위해 여러 개의 Origin을 설정하고 로드 밸런싱을 활용할 수 있습니다. 특히 홈랩에서 Docker Swarm이나 Kubernetes(쿠버네티스) 환경에서 여러 인스턴스를 띄워두고 연결할 때 정말 유용하더라고요.

ingress:
  - hostname: myapp.example.com
    service: http://localhost:8080
    originRequest:
      originMaxConcurrentConnections: 200 # 동시 연결 수 제한
  - hostname: myapp.example.com
    service: http://192.168.1.100:8080 # 다른 서버의 동일 서비스
  - service: http_status:404

2. 제로 트러스트 액세스 정책(Zero Trust Access Policies) 강화

Cloudflare Access(클라우드플레어 액세스)를 활용해서 사용자 인증 및 접근 정책을 강화해 보세요. 이메일, SSO(Single Sign-On) 연동 등 다양한 방법을 지원하기 때문에 보안을 한층 더 높일 수 있습니다. '누구도 믿지 않는다'는 제로 트러스트 원칙을 따르는 거죠.

3. 헬스 체크(Health Checks) 설정

config.yml 파일에 health_check를 설정하면 Origin 서버의 상태를 주기적으로 체크할 수 있어요. 서버가 죽었을 때 자동으로 다른 Origin으로 트래픽을 돌리거나 알림을 받을 수 있어서 서비스 안정성에 정말 큰 도움이 됩니다.

ingress:
  - hostname: myapp.example.com
    service: http://localhost:8080
    originRequest:
      httpHostHeader: myapp.example.com
      noTLSVerify: true # 개발 환경에서만 사용
      connectTimeout: 5s
      tcpKeepAlive: 30s
      retries: 3

4. 지속적인 연결(Persistent Connection) 유지

config.yml 파일 내 originRequest 섹션에서 tcpKeepAlive 같은 옵션을 활성화하면 터널 연결을 더 오래 유지할 수 있어요. 짧은 시간 동안의 네트워크 불안정으로 인한 Cloudflare Tunnel 연결 끊김을 줄일 수 있습니다.

🎉 검증 및 결과 확인

이 모든 단계를 거치고 나면, 드디어 Cloudflare Tunnel이 안정적으로 작동하는 걸 볼 수 있을 겁니다! 브라우저에서 설정한 도메인으로 접속해보고, cloudflared 로그를 다시 확인해 보세요. 에러 없이 깔끔하게 연결되는 걸 보면 정말 뿌듯해요.

특히 Cloudflare 대시보드의 'Analytics(분석)' 섹션에서 트래픽이 정상적으로 흐르는 걸 확인하면, '아, 이제 좀 안심이다!' 싶어요. 연결 끊김 없이 안정적으로 서비스가 제공되는 모습을 보면 그동안의 삽질이 다 보상받는 기분이죠. 드디어 됐다!

Cloudflare Tunnel 최적화 팁을 시각적으로 요약한 인포그래픽

Cloudflare Tunnel 최적화 팁들을 한눈에 보기 쉽게 정리한 인포그래픽입니다. 로드 밸런싱, Zero Trust Access, Health Checks 등 핵심적인 개선 방안들을 담고 있습니다.

마무리하며: 삽질은 성장의 밑거름!

Cloudflare Tunnel은 정말 강력하고 편리한 도구지만, 가끔씩 예상 밖의 문제로 우리를 당황하게 만들 때가 있어요. 그래도 대부분의 문제는 오늘 제가 알려드린 5단계 점검과 최적화 팁으로 충분히 해결할 수 있을 거예요. 저도 처음엔 헷갈렸는데, 몇 번 겪어보니 '아, 이거구나!' 싶더라고요.

인프라 엔지니어의 삶이란 게 결국 삽질의 연속이잖아요? ㅎㅎ 그 삽질을 통해 얻은 경험이 다른 분들께 조금이라도 도움이 되었으면 좋겠어요. 항상 새로운 기술을 실험하고, 문제를 해결하는 과정에서 성장하는 것 같습니다.

다음 글에서는 Cloudflare Tunnel과 Docker를 연동해서 서비스 배포를 자동화하는 방법에 대해 좀 더 깊이 다뤄볼 예정이니 기대해주세요! 그때까지 모두 안정적인 서버실 운영하시길 바랍니다!