OpenClaw 보안 강화: Traefik으로 Basic Auth 구축하기

OpenClaw 보안 강화: Traefik으로 Basic Auth 구축하기
Photo by Franck / Unsplash
OpenClaw Logo
🔐 OpenClaw Gateway에 Traefik 리버스 프록시Basic Authentication을 적용하여 보안을 한층 강화하는 방법을 알아봅니다.

왜 Basic Auth가 필요한가?

OpenClaw Gateway는 기본적으로 로컬호스트에서만 접근 가능하지만, 다음과 같은 상황에서는 추가 보안이 필요합니다:

🚨 보안이 필요한 시나리오

  • 원격 접속: VPN이나 공개 네트워크를 통한 접근
  • VPS 배포: 클라우드 서버에서 실행할 때
  • 네트워크 노출: LAN 환경에서 다른 기기의 접근 허용

✅ Basic Auth의 장점

  • 🔒 간단한 구현: 복잡한 OAuth 없이 빠른 구축
  • 🎯 효과적인 방어: 무단 접근 차단
  • 🔄 표준 프로토콜: 모든 브라우저와 호환
  • 📦 경량: 추가 리소스 거의 없음

Traefik 소개

Traefik은 현대적인 리버스 프록시이자 로드 밸런서입니다. Docker와의 완벽한 통합으로 마이크로서비스 환경에서 널리 사용됩니다.

🌟 Traefik의 주요 특징

  • 🐳 Docker 네이티브: 라벨 기반 자동 설정
  • 🔄 자동 디스커버리: 컨테이너 시작/종료 시 자동 반영
  • 🛡️ 미들웨어 지원: Basic Auth, HTTPS, 압축 등

사전 준비

시스템 요구사항

1. Docker 환경 확인

# Docker 버전 확인
docker --version
# Docker version 24.0.0 이상

# Docker Compose 확인
docker compose version
# Docker Compose version v2.0.0 이상

2. OpenClaw 이미지 준비

# OpenClaw 리포지토리에서
cd openclaw

# 이미지 빌드
docker build -t openclaw:local -f Dockerfile .

3. 디렉토리 구조 준비

# 프로젝트 디렉토리 생성
mkdir -p ~/openclaw-docker
cd ~/openclaw-docker

# 데이터 디렉토리 생성
mkdir -p data

# 디렉토리 구조 확인
tree -L 2

예상 구조:

~/openclaw-docker/
├── compose.yml         # Docker Compose 설정
├── .htpasswd           # Basic Auth 인증 파일
├── .env                # 환경 변수
└── data/               # OpenClaw 데이터
    └── .openclaw/
        └── workspace/

htpasswd 파일 생성

방법 1: htpasswd 명령어 사용 (권장)

macOS에서 htpasswd 설치

# Apache 도구 설치 (htpasswd 포함)
brew install httpd

인증 파일 생성

# 첫 번째 사용자 생성 (-c: 파일 생성)
htpasswd -c .htpasswd admin

프롬프트에서 비밀번호 입력:

New password: ********
Re-type new password: ********
Adding password for user admin

추가 사용자 생성

# 두 번째 사용자 추가 (-c 옵션 제거!)
htpasswd .htpasswd user2
⚠️ 주의: 두 번째 사용자부터는 -c 옵션을 빼야 합니다. -c를 사용하면 파일이 새로 생성되어 기존 사용자가 삭제됩니다!

방법 2: 온라인 생성기 (비권장)

보안상 로컬에서 생성하는 것을 권장하지만, 테스트 목적으로는:

  • https://hostingcanada.org/htpasswd-generator/
  • https://www.web2generators.com/apache-tools/htpasswd-generator
🔐 보안 팁: 프로덕션 환경에서는 반드시 로컬에서 생성하세요!

생성된 파일 확인

# .htpasswd 내용 확인
cat .htpasswd

출력 예시:

admin:$2y$05$EIBak0g7V8bQPjC9bLCJe.eXXRlMCDEXAMPLEHASH
user2:$2y$05$JDFak0g7V8bQPjC9bLCJe.eXXRlMEXAMPLEHASH2

Docker Compose 설정

compose.yml 수정

프로젝트 디렉토리의 docker-compose.yml 파일을 아래와 같이 수정합니다:

services:
  # OpenClaw Gateway 서비스
  openclaw-gateway:
    image: openclaw:local
    environment:
      TZ: ${TZ}
      HOME: /home/node
      TERM: xterm-256color
      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
    volumes:
      - ./data:/home/node
    expose:
      - "18789"
    labels:
      # Traefik 활성화
      traefik.enable: "true"
      
      # Basic Auth 미들웨어 정의
      traefik.http.middlewares.auth.basicauth.realm: "chat"
      traefik.http.middlewares.auth.basicauth.usersfile: "/auth/.htpasswd"
      
      # 라우팅 규칙
      traefik.http.routers.gateway.rule: "Host(`${GW_HOST}`)"
      traefik.http.routers.gateway.middlewares: "auth"
      traefik.http.routers.gateway.entrypoints: "web"
    networks:
      - openclaw
    init: true
    restart: unless-stopped
    command:
      [
        "node",
        "dist/index.js",
        "gateway",
        "--bind",
        "lan",
        "--port",
        "18789",
      ]

  # Traefik 리버스 프록시
  openclaw-proxy:
    image: traefik:v3.6
    restart: unless-stopped
    command:
      # 익명 사용 통계 비활성화
      - "--global.sendAnonymousUsage=false"
      
      # 액세스 로그 활성화
      - "--accesslog"
      - "--accesslog.fields.names.StartUTC=drop"
      
      # Docker 프로바이더 설정
      - "--providers.docker"
      - "--providers.docker.exposedByDefault=false"
      - "--providers.docker.network=openclaw"
      
      # HTTP 엔트리포인트 (포트 80)
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.forwardedHeaders.insecure=true"
    environment:
      - TZ=${TZ}
    ports:
      # 로컬호스트에만 포트 바인딩
      - "127.0.0.1:18789:80"
    volumes:
      # htpasswd 파일 마운트
      - ./.htpasswd:/auth/.htpasswd
      
      # Docker 소켓 (읽기 전용)
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - openclaw

  # OpenClaw CLI (선택사항)
  openclaw-cli:
    image: openclaw:local
    environment:
      HOME: /home/node
      TERM: xterm-256color
      BROWSER: echo
      OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
    volumes:
      - ./data:/home/node
    profiles:
      - manual
    network_mode: "service:openclaw-gateway"
    stdin_open: true
    tty: true
    init: true
    entrypoint: ["node", "dist/index.js"]
    depends_on:
      - openclaw-gateway

networks:
  openclaw:

설정 상세 분석

1. OpenClaw Gateway 설정

포트 노출:

expose:
  - "18789"
  • expose는 내부 네트워크에만 포트 공개
  • 외부에서 직접 접근 불가 (Traefik을 통해서만)

Traefik 라벨:

labels:
  traefik.enable: "true"
  traefik.http.middlewares.auth.basicauth.realm: "chat"
  traefik.http.middlewares.auth.basicauth.usersfile: "/auth/.htpasswd"
  traefik.http.routers.gateway.rule: "Host(`${GW_HOST}`)"
  traefik.http.routers.gateway.middlewares: "auth"

라벨 설명:

  • traefik.enable: Traefik에서 이 컨테이너 관리 활성화
  • basicauth.realm: 인증 창에 표시될 영역 이름
  • basicauth.usersfile: htpasswd 파일 경로 (Traefik 컨테이너 내부 경로)
  • router.rule: 라우팅 조건 (호스트명 매칭)
  • router.middlewares: 적용할 미들웨어 (여기서는 auth)

2. Traefik 프록시 설정

포트 바인딩:

ports:
  - "127.0.0.1:18789:80"
  • 로컬호스트에만 바인딩 (외부 접근 허용시에는 삭제)
  • 호스트 포트 18789 → 컨테이너 포트 80

볼륨 마운트:

volumes:
  - ./.htpasswd:/auth/.htpasswd
  - /var/run/docker.sock:/var/run/docker.sock:ro
  • .htpasswd: 인증 파일 (읽기/쓰기)
  • docker.sock: Docker API 접근 (읽기 전용)
⚠️ 보안 참고: Docker 소켓을 마운트하면 컨테이너가 호스트의 Docker를 제어할 수 있습니다. Traefik은 컨테이너 정보를 읽기 위해 필요하며, :ro 플래그로 읽기 전용으로 제한했습니다.

3. 네트워크 설정

networks:
  openclaw:

모든 서비스가 openclaw 네트워크에 연결되어 내부 통신이 가능합니다.

환경 변수 설정

기존 .env 파일에 환경 변수를 추가합니다:

# 타임존 설정
TZ=Asia/Seoul

# Gateway 도메인
GW_HOST=localhost

# 기타 openclaw 설정...

실행 및 테스트

1. 파일 확인

시작하기 전에 모든 파일이 준비되었는지 확인:

# 현재 디렉토리 구조
ls -la

필수 파일:

  • compose.yml
  • .htpasswd
  • .env
  • data/ 디렉토리

2. 서비스 시작

# 백그라운드로 서비스 시작
docker compose up -d

# 또는 로그를 보면서 시작
docker compose up

3. 상태 확인

# 실행 중인 컨테이너 확인
docker compose ps

정상 출력:

NAME                    IMAGE              STATUS
openclaw-gateway        openclaw:local     Up 30 seconds
openclaw-proxy          traefik:v3.6       Up 30 seconds

4. 로그 확인

# Gateway 로그
docker compose logs -f openclaw-gateway

# Traefik 로그
docker compose logs -f openclaw-proxy

# 모든 로그
docker compose logs -f

5. 웹 브라우저 테스트

브라우저에서 다음 주소로 접속하면 인증창이 표시됩니다:

http://localhost:18789

6. CLI 테스트 (선택사항)

Basic Auth가 적용되어도 CLI는 Gateway 네트워크를 직접 사용하므로 인증 없이 작동합니다:

# CLI 컨테이너 실행
docker compose run --rm openclaw-cli status

# 채널 목록 확인
docker compose run --rm openclaw-cli channels list

문제 해결

1. 인증 창이 나타나지 않음

증상: 브라우저에서 바로 접속되거나 502 에러

확인 사항:

# Traefik 로그 확인
docker compose logs openclaw-proxy | grep -i auth

# htpasswd 파일이 제대로 마운트되었는지 확인
docker compose exec openclaw-proxy cat /auth/.htpasswd

해결책:

# 서비스 재시작
docker compose restart openclaw-proxy

# 캐시 문제라면 완전 재시작
docker compose down
docker compose up -d

2. 401 Unauthorized (인증 실패)

증상: 비밀번호를 입력해도 계속 인증 창이 나타남

원인:

  • 비밀번호가 틀림
  • htpasswd 형식 오류

해결:

# 새로운 htpasswd 파일 생성
rm .htpasswd
htpasswd -c .htpasswd admin

# 서비스 재시작
docker compose restart openclaw-proxy

3. 502 Bad Gateway

증상: Traefik은 작동하지만 Gateway에 연결 불가

원인:

  • Gateway 컨테이너가 실행되지 않음
  • 네트워크 문제

확인:

# Gateway 상태 확인
docker compose ps openclaw-gateway

# Gateway 로그 확인
docker compose logs openclaw-gateway

# 네트워크 확인
docker network inspect openclaw_openclaw

해결:

# Gateway 재시작
docker compose restart openclaw-gateway

# 전체 재시작
docker compose down && docker compose up -d

4. 포트 충돌

증상: Error: port 18789 is already in use

해결:

# 사용 중인 프로세스 확인
lsof -i :18789

# 또는 compose.yml에서 포트 변경
ports:
  - "127.0.0.1:19000:80"  # 다른 포트 사용

5. Permission Denied (htpasswd 접근 오류)

증상: Error: cannot access /auth/.htpasswd: Permission denied

해결:

# htpasswd 파일 권한 수정
chmod 644 .htpasswd

# 재시작
docker compose restart openclaw-proxy

6. Docker 소켓 권한 오류

증상: Error: permission denied while trying to connect to Docker daemon socket

해결:

# 현재 사용자를 docker 그룹에 추가
sudo usermod -aG docker $USER

# 로그아웃 후 다시 로그인하거나
newgrp docker

# 또는 docker 소켓 권한 변경 (비권장)
sudo chmod 666 /var/run/docker.sock

보안 강화 팁

1. 강력한 비밀번호 사용

# 랜덤 비밀번호 생성
openssl rand -base64 20
# 출력: Kj9xMn2Vp5Qw8Rt7Yz4Ua6Gb3Nc

2. 파일 권한 설정

# .env 파일 (토큰 포함)
chmod 600 .env

# .htpasswd 파일
chmod 644 .htpasswd

3. HTTPS 적용 (선택사항)

프로덕션 환경에서는 HTTPS를 권장합니다:

# compose.yml에 HTTPS 엔트리포인트 추가
services:
  openclaw-proxy:
    command:
      # ... 기존 설정 ...
      - "--entrypoints.websecure.address=:443"
      - "[email protected]"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "127.0.0.1:443:443"
    volumes:
      # ... 기존 볼륨 ...
      - ./letsencrypt:/letsencrypt
HTTPS 사용을 원하는 경우에는 별도의 SSL 인증서가 필요하며 letsencrypt 와 같은 무료 인증서 발급 기관을 통해 인증서를 발급받아 사용하면 됩니다.

4. IP 화이트리스트

특정 IP만 허용하려면:

# compose.yml
services:
  openclaw-gateway:
    labels:
      # IP 화이트리스트 미들웨어 추가
      traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange: "192.168.1.0/24,127.0.0.1/32"
      
      # 미들웨어 체인에 추가
      traefik.http.routers.gateway.middlewares: "auth,ipwhitelist"

5. Rate Limiting

DDoS 공격 방어:

# compose.yml
services:
  openclaw-gateway:
    labels:
      # Rate Limit 미들웨어
      traefik.http.middlewares.ratelimit.ratelimit.average: "100"
      traefik.http.middlewares.ratelimit.ratelimit.burst: "50"
      
      # 미들웨어 체인에 추가
      traefik.http.routers.gateway.middlewares: "auth,ratelimit"

6. 로그 모니터링

# 실패한 인증 시도 모니터링
docker compose logs openclaw-proxy | grep "401"

# 특정 IP에서의 과도한 요청 감지
docker compose logs openclaw-proxy | awk '{print $1}' | sort | uniq -c | sort -nr

유용한 명령어 모음

서비스 관리

# 시작
docker compose up -d

# 중지
docker compose stop

# 재시작
docker compose restart

# 완전 종료 및 정리
docker compose down

# 볼륨까지 삭제
docker compose down -v

사용자 관리

# 사용자 추가
htpasswd .htpasswd newuser

# 사용자 삭제
htpasswd -D .htpasswd olduser

# 비밀번호 변경
htpasswd .htpasswd existinguser

# 사용자 목록 확인
cut -d: -f1 .htpasswd

로그 및 모니터링

# 실시간 로그
docker compose logs -f

# 특정 서비스 로그
docker compose logs -f openclaw-proxy

# 최근 100줄
docker compose logs --tail=100 openclaw-gateway

# 특정 시간 이후 로그
docker compose logs --since 2024-01-01T00:00:00

디버깅

# 컨테이너 내부 접속
docker compose exec openclaw-proxy sh

# htpasswd 파일 내용 확인
docker compose exec openclaw-proxy cat /auth/.htpasswd

# 네트워크 정보
docker network inspect openclaw_openclaw

# 리소스 사용량
docker stats

성능 최적화

1. 로그 로테이션

# compose.yml
services:
  openclaw-gateway:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
  
  openclaw-proxy:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

2. 리소스 제한

# compose.yml
services:
  openclaw-gateway:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          memory: 1G

3. Health Check

# compose.yml
services:
  openclaw-gateway:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:18789/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

마무리

이제 OpenClaw Gateway가 Traefik과 Basic Auth로 보호되고 있습니다! 🎉

유용한 링크