Ngrok 알아보기

본 글은 Claude Sonnet 4로 작성했습니다.


Ngrok란 무엇인가?

Ngrok는 로컬에서 실행되는 서버를 인터넷에 안전하게 노출시키는 도구이다. NAT나 방화벽 뒤에 있는 로컬 서버를 외부에서 접근할 수 있게 해주는 터널링 서비스이다.

간단히 말해, localhost:3000에서 실행되는 애플리케이션을 https://abc123.ngrok.io와 같은 공개 URL로 접근할 수 있게 만들어준다.

왜 Ngrok를 사용하나?

개발 환경에서의 활용

  • 웹훅 테스트: GitHub, Slack 등의 웹훅을 로컬에서 직접 테스트할 수 있다
  • 모바일 테스트: 같은 네트워크의 모바일 기기에서 로컬 서버에 접근할 수 있다
  • 외부 API 연동: 외부 서비스에서 콜백 URL이 필요할 때 유용하다

협업 및 데모

  • 실시간 공유: 동료에게 개발 중인 애플리케이션을 즉시 보여줄 수 있다
  • 클라이언트 데모: 별도 배포 없이 클라이언트에게 진행 상황을 공유할 수 있다

Ngrok 설치하기

1. 공식 사이트에서 다운로드

# macOS (Homebrew 사용)
brew install ngrok/ngrok/ngrok

# Linux/macOS (직접 다운로드)
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
tar -xvzf ngrok-v3-stable-linux-amd64.tgz

# Windows (Chocolatey 사용)
choco install ngrok

2. 계정 생성 및 인증

Ngrok 공식 사이트에서 무료 계정을 생성한 후, 토큰을 설정한다.

# 인증 토큰 설정 (한 번만 실행)
ngrok authtoken YOUR_AUTH_TOKEN

기본 사용법

HTTP 터널 생성

가장 기본적인 사용법이다. 로컬 HTTP 서버를 외부에 노출시킨다.

# 포트 3000에서 실행 중인 서버를 노출
ngrok http 3000

# 특정 호스트와 포트 지정
ngrok http localhost:8080

# HTTPS만 허용 (HTTP 요청 차단)
ngrok http --bind-tls=true 3000

HTTPS 터널 생성

# HTTPS 서버를 터널링 (SSL 검증 비활성화)
ngrok http https://localhost:8443

# 자체 서명된 인증서 허용
ngrok http --host-header=rewrite https://localhost:8443

TCP 터널 생성

HTTP가 아닌 TCP 프로토콜을 사용하는 서비스에 유용하다.

# SSH 서버 노출
ngrok tcp 22

# 데이터베이스 연결 노출
ngrok tcp 5432

FastAPI 예제

# main.py
from fastapi import FastAPI, Request

# FastAPI 애플리케이션 생성
app = FastAPI()

@app.get("/")
def home():
    """기본 라우트"""
    return {"message": "Ngrok으로 연결된 FastAPI 서버"}

@app.post("/webhook")
async def webhook(request: Request):
    """웹훅 수신 엔드포인트"""
    data = await request.json()
    print(f"웹훅 수신: {data}")
    return {"received": True}

@app.get("/users/{user_id}")
def get_user(user_id: int):
    """사용자 조회 API"""
    return {"id": user_id, "name": f"사용자{user_id}"}

터미널에서 실행:

# FastAPI 서버 실행
uvicorn main:app --port 8000

# 새 터미널에서 Ngrok 실행
ngrok http 8000

고급 설정 및 옵션

커스텀 도메인 사용

유료 계정에서는 커스텀 도메인을 사용할 수 있다.

# 커스텀 서브도메인 사용
ngrok http --subdomain=myapp 3000

# 결과: https://myapp.ngrok.io

기본 인증 추가

# HTTP 기본 인증 추가
ngrok http --auth="username:password" 3000

설정 파일 사용

반복적인 설정을 위해 YAML 설정 파일을 사용할 수 있다.

# ~/.ngrok2/ngrok.yml
version: "2"
authtoken: YOUR_AUTH_TOKEN

tunnels:
  webapp:
    proto: http
    addr: 3000
    subdomain: mywebapp
    auth: "user:pass"
    
  api:
    proto: http
    addr: 8080
    subdomain: myapi
    
  database:
    proto: tcp
    addr: 5432

설정 파일로 실행:

# 특정 터널 실행
ngrok start webapp

# 모든 터널 실행
ngrok start --all

로그 및 디버깅

# 상세 로그 출력
ngrok http --log=stdout --log-level=debug 3000

# 로그 파일로 저장
ngrok http --log=ngrok.log 3000

보안 고려사항

접근 제한

  • IP 화이트리스트: 특정 IP만 접근 허용
  • 기본 인증: 사용자명/패스워드로 접근 제한
  • HTTPS 강제: HTTP 요청 차단

민감한 데이터 보호

# FastAPI에서 환경별 설정 예제
import os
from fastapi import FastAPI, HTTPException, Request

app = FastAPI()

@app.middleware("http")
async def validate_host(request: Request, call_next):
    """Host 헤더 검증 미들웨어"""
    # 개발 환경에서만 Ngrok 허용
    if os.environ.get('ENV') != 'development':
        host = request.headers.get('host')
        if 'ngrok.io' in host:
            raise HTTPException(status_code=403, detail="접근 거부")
    
    response = await call_next(request)
    return response

문제 해결

1. "Your account is limited" 오류

# 해결: 계정 인증 확인
ngrok authtoken YOUR_TOKEN

2. "502 Bad Gateway" 오류

# 해결: 로컬 서버가 실행 중인지 확인
curl http://localhost:3000

3. 웹훅이 도달하지 않는 경우

# 해결: 올바른 URL과 포트 확인
ngrok http --inspect 3000
# 웹 인터페이스에서 요청 확인: http://127.0.0.1:4040

디버깅 팁

  • Ngrok 웹 인터페이스 (http://127.0.0.1:4040) 활용
  • 요청/응답 로그 확인
  • 네트워크 상태 점검

대안 도구들

Ngrok 외에도 비슷한 도구들이 있다:

  • LocalTunnel: 오픈소스 대안
  • PageKite: 자체 서버 구축 가능
  • Serveo: SSH 기반 터널링
  • Cloudflare Tunnel: Cloudflare의 무료 터널링 서비스

Ngrok는 개발자에게 매우 유용한 도구이다. 로컬 개발 환경을 외부와 연결하여 웹훅 테스트, 모바일 테스트, 실시간 협업을 가능하게 한다. 기본 사용법은 간단하지만, 고급 기능들을 활용하면 더욱 강력한 개발 워크플로우를 구축할 수 있다.

개발 단계에서는 매우 유용하지만, 프로덕션 환경에서는 보안을 충분히 고려해야 한다. 적절한 인증과 접근 제한을 통해 안전하게 활용하자.