
1. Cloudflare Tunnel이란?
Cloudflare Tunnel은 퍼블릭 클라우드 (Public Cloud) 환경과 온프레미스 (On-premise) 데이터 센터, 또는 다른 클라우드 환경과 같은 원격 네트워크를 안전하고 안정적으로 연결하는 기술이다. 인터넷과 같은 공용 네트워크 상에 가상의 암호화된 전용 경로, 즉 터널을 생성하여 데이터를 안전하게 전송하는 것으로 Cloudflare의 CLI 도구이자 Daemon Software인 Cloudflared를 통해 사용할 수 있다.
사실 다른 것보다 로컬 dev 서버를 쉽게 외부로 연결할 수 있다는 것이 강점이다. 이때문에 나는 개발 서버를 임시적으로 외부로 돌릴 때 많이 사용한다. (가령, Pub/Sub API에서 listening 엔드포인트를 넣어줘야 한다거나… 등등)
ngrok 등의 타사 서비스와 비교되는 강점도 많다.
자신이 소유하는 도메인에 한해 커스텀되고, 고정된 주소를 사용할 수 있으며 https 연결 지원, 터널 연결 경고페이지 등 ngrok에서는 유료로 사용하여야 하는 많은 서비스가 무료로 지원된다. (정기결제로 빠지는 돈보다는 당연히 1년 사서 펑펑쓰는 개인 도메인에 연결하는게 훨씬 싸다.)
당연히 직접 소유하는 도메인이 없더라도 Quick Tunnel을 이용하여 cloudflared가 자체적으로 호스팅하는 도메인에서 생성되는 무작위 서브도메인을 통해 이용할 수 있다.
1.1. 작동 원리
클라우드 터널은 터널링 프로토콜(Tunneling Protocol)을 기반으로 동작한다.
- 로컬에서 서버를 연다 생각했을 때, 클라우드 환경은 Cloudflare의 엣지 네트워크, 원격 네트워크는 내가 연 서버 환경으로 이해하면 된다.
터널링은 원래의 데이터 패킷을 다른 프로토콜의 패킷으로 감싸는 캡슐화 과정을 통해 이루어지는데, 이 과정을 통해 공용 네트워크를 통과하는 데이터는 외부에서 내용을 확인할 수 없도록 암호화하여 보호한다.
- 터널 생성: 클라우드 환경의 게이트웨이와 원격 네트워크의 게이트웨이 간에 가상의 터널을 설정한다. 이때 IPSec이나 SSL과 같은 보안 프로토콜을 주로 사용한다.
- 데이터 캡슐화 (Encapsulation): 원격 네트워크에서 클라우드로 전송되는 데이터 패킷은 터널의 입구에서 터널링 프로토콜을 사용하여 새로운 헤더와 함께 캡슐화된다. 이 과정에서 데이터가 암호화된다.
- 데이터 전송: 이렇게 캡슐화된 패킷은 인터넷을 통해 클라우드 게이트웨이로 전송된다. 공용망을 통과하지만, 당연히 데이터는 암호화되어 있어 중간에 가로채더라도 내용을 알 수 없다.
- 데이터 역캡슐화 (Decapsulation): 클라우드 게이트웨이에 도착한 패킷은 캡슐화가 해제되고 복호화되어, 원래의 데이터 패킷으로 복원된다.
이러한 과정을 통해 클라우드 터널은 지리적으로 떨어진 네트워크 간에 데이터 기밀성, 무결성, 인증을 보장하는 안전한 통신이 가능하다.
1.2. CLI 사용
1.2.1. CLI 설치
Cloudflared CLI는 binary, .deb, .rpm, brew, winget, docker, .exe, apt 등 웬만한 방법으로는 다 설치 가능하다. 아래 사이트에서 자신에게 적절한 방법을 찾아 다운로드하면 된다.
웬만한 경우 ~/.cloudflared 를 config directory로 하여 설정되며, 이 글에서는 축약하여 .cloudflared로 표시한다.
1.2.2. 인증
cloudflared 설치를 완료했다면, 쉘에서 로그인 과정을 먼저 거쳐야 한다. 이는 굳이 cloudflared에 도메인을 등록하지 않아도 서비스 이용을 위해 필수적이다.
cloudflared tunnel login위 커맨드를 입력하였을 때 제공되는 url을 통해 로그인하면 된다. 로그인을 하면 우리가 이 tunnel에서 사용할 cloudflared에 등록된 도메인을 하나 선택하게끔 한다. 물론 Quick Tunnel만을 이용할 생각이면 아무거나 선택하거나, 선택하지 않아도 무관하다.
이 과정을 거치면 우리가 선택한 도메인에 대한 인증 토큰이 .cloudflared/cert.pem에 저장된다.
1.3. Quick Tunnel
cloudflared 인증만 했다면, 어떠한 과정 없이 즉시 사용할 수 있는 터널이다.
cloudflared tunnel --url http://localhost:3000위의 커맨드를 사용하면 즉시 cloudflared의 trycloudflare.com 도메인에서 임시로 서브도메인을 생성하고 연결해준다.
...
2025-08-03T03:03:14Z INF +--------------------------------------------------------------------------------------------+
2025-08-03T03:03:14Z INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): |
2025-08-03T03:03:14Z INF | https://tx-movement-san-tests.trycloudflare.com |
2025-08-03T03:03:14Z INF +--------------------------------------------------------------------------------------------+
...위 실행에서 로컬호스트 http://localhost:3000이 https://tx-movement-san-tests.trycloudflare.com로 연결되었음을 알 수 있다.
1.4. 커스텀 터널
1.4.1. 터널 생성
Quick Tunnel이 아닌 우리가 직접 설정한 도메인의 터널을 만들고 싶은 경우 이 과정을 거친다.
쉘에서 아래의 커맨드를 입력하여 터널을 생성한다. <tunnel_name>에는 원하는 이름(별칭, alias)를 넣으면 된다. 이렇게 넣은 <tunnel_name>은 터널을 실행할 때 편하게 알아볼 수 있도록 하는 별칭 이외의 의미는 없으니 너무 고심해서 넣지 않아도 된다.
cloudflared tunnel create <tunnel_name>이 명령어를 실행하고 성공적으로 터널을 생성했다면 tunnel id를 출력한다. 이 터널 id를 잠시 기록해두자.
이로써 우리의 cloudflare 계정에 등록된 터널ID와 이름을 생성하고, 이 리소스를 Cloudflare의 원격 API에 등록한다. 또한 로컬에서 내부적으로 해당 터널과 연결하기 위한 UUID 기반의 설정 파일 .cloudflared/<UUID>.json 을 생성한다.
{
"AccountTag":"389b6b...",
"TunnelSecret":"gy1vDJ...",
"TunnelID":"31b2f5...",
"Endpoint":""
}1.4.2. 터널 설정
터널을 생성하고 이를 정상적으로 등록했으니, 이제 이 터널을 통해 어떤 서비스로 요청을 전달할지에 대한 라우팅 규칙을 정의해야 한다. 이는 .cloudflared/config.yml 을 작성하여 지정할 수 있다.
tunnel: 31b2f5...
credentials-file: /home/user/.cloudflared/31b2f5....json
ingress:
- hostname: subdomain1.mydomain.com
service: http://localhost:3000
- hostname: subdomain2.mydomain.com
service: http://localhost:4000
- service: http_status:404먼저 tunnel의 값으로는 우리가 기록해둔, 혹은 .cloudflared에 생성된 <UUID>.json 을 참고하여 원하는 터널의 id(uuid)를 입력한다. 이후 credentials-file에 해당 터널에 맞는 credential json파일 경로를 입력한다.
tunnel의 값으로는 꼭<tunnel_name>이 아닌 uuid가 들어가야 한다.
이후 inbound, Outbound 규칙을 작성하면 되는데 대부분 ingress 규칙만 정의하는 경우가 많을 것이다. 다만 Outbound 즉, egress 규칙도 원한다면 설정할 수 있다. ingress 에서는 hostname에 내가 미리 생성해둔 도메인의 원하는 서브 도메인을 결합해 입력하고, 해당 서비스가 실제 로컬의 어느 포트에 연결될지 적어주면 된다.
마지막의 service는 앞선 ingress내에 명시된 모든 hostname과 그 규칙이 맞지 않았을 때 404 응답을 반환하도록 한다. 404 이외에도 다음과 같은 옵션들을 지원한다.
service 값 | 설명 |
|---|---|
http://localhost:3000 | 일반 HTTP 프록시 대상 |
unix:/var/run/service.sock | UNIX 도메인 소켓 |
tcp://localhost:22 | TCP 포트 직접 포워딩 |
http_status:404 | 404 Not Found 응답 |
http_status:503 | 503 Service Unavailable |
http_status:403 | 403 Forbidden |
http_status:502 | 502 Bad Gateway 등도 가능 |
1.4.3. 터널 실행
cloudflared tunnel run <tunnel_name>이제 위의 명령어를 통해 우리가 정의한 터널을 실행할 수 있다.
<tunnel_name>에는 우리가 처음에 터널을 생성할 때 사용한 별칭 혹은, 해당 터널의 uuid 중 어떤 것을 써도 무관하다.