DOCS/journey/troubleshooting/250716_auth_server_setup.md
happybell80 0252dd1a7f fix: 51123 서버 IP 주소 업데이트 (성수 이전)
192.168.219.45 → 192.168.0.100 일괄 변경

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:52:26 +09:00

7.9 KiB

중앙 인증 서버(auth.ro-being.com) 구축

날짜: 2025-07-16
관련 서비스: auth-server, nginx-infra
작성자: Claude AI Assistant

작업 개요

로빙 프로젝트의 모든 외부 서비스(Gmail, Slack, Notion 등) OAuth 인증을 중앙에서 관리하기 위한 auth.ro-being.com 서버를 구축했습니다.

주요 작업 내용

1. 인증 서버 아키텍처 설계

문제 상황:

  • Gmail OAuth 리디렉션 URI 설정 필요
  • 각 로빙 컨테이너가 개별적으로 인증을 관리하면 복잡도 증가
  • 토큰 관리의 중앙화 필요

해결 방안:

  • auth.ro-being.com을 중앙 인증 허브로 구축
  • 모든 OAuth 토큰을 중앙 DB에 저장
  • 로빙 컨테이너는 API를 통해 토큰 조회

2. auth-server 저장소 생성

# 저장소 생성
git.ro-being.com/ivada_Ro-being/auth-server

# 기본 구조
auth-server/
├── app/
│   ├── main.py              # FastAPI 메인
│   ├── providers/           # OAuth 제공자별 모듈
│   │   └── gmail.py        # Gmail OAuth (구현 예정)
│   └── api/                 # API 엔드포인트
│       └── tokens.py       # 토큰 관리 API
├── docker-compose.yml      # 포트 9000 설정
├── Dockerfile
└── requirements.txt

3. Nginx 리버스 프록시 설정

nginx-infra/default.conf 수정:

# Auth server configuration
server {
    listen 80;
    server_name auth.ro-being.com;
    
    location / {
        proxy_pass http://192.168.0.100:9000/;  # 끝에 / 중요!
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # OAuth 콜백 타임아웃 늘리기
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
    }
}

주의사항:

  • proxy_pass 끝에 / 필수 - 없으면 하위 경로 전달 안됨
  • 기존 서버 블록에 server_name 패턴 추가하여 auth 제외

4. Docker 구성

docker-compose.yml:

services:
  auth-server:
    build: .
    container_name: auth-server
    ports:
      - "9000:9000"
    environment:
      - PORT=9000
      - DATABASE_URL=${DATABASE_URL}
      - JWT_SECRET_KEY=${JWT_SECRET_KEY}
      - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
      - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
    networks:
      - appnet

전체 인증 플로우

1. 사용자 요청: "Gmail 읽어줘"
   ↓
2. 로빙 컨테이너: 토큰 확인
   ↓
3. 토큰 없음 → auth.ro-being.com/auth/gmail/login 링크 전송
   ↓
4. 사용자: 링크 클릭 → Google 로그인
   ↓
5. Google → auth.ro-being.com/auth/gmail/callback
   ↓
6. auth-server: 토큰 저장 (PostgreSQL)
   ↓
7. 로빙: API로 토큰 조회하여 Gmail 접근

다음 단계

  1. 서버 작업:

    • auth-server 클론 및 빌드
    • .env 파일 설정
    • docker-compose up -d 실행
    • nginx reload
  2. 개발 작업:

    • Gmail OAuth provider 구현
    • PostgreSQL 토큰 저장 모델
    • JWT 기반 API 인증
    • rb10508_test에 Gmail 스킬 통합

관련 파일

  • /home/happybell/projects/ivada/auth-server/ - 인증 서버
  • /home/happybell/projects/ivada/nginx-infra/default.conf - Nginx 설정
  • /home/happybell/projects/ivada/skill_email/ - Gmail 스킬 (통합 예정)

SSL/HTTPS 설정 추가

문제 상황

  • HTTP는 정상 작동하지만 HTTPS 접속 불가
  • SSL 인증서는 이미 발급되어 있음 (auth.ro-being.com)
  • nginx 설정에 HTTPS 서버 블록 누락

해결 과정

  1. nginx-infra 저장소 구조 파악:

    • default.conf: Docker nginx 설정 (legacy)
    • server-nginx-default: 실제 서버 nginx 설정 파일
    • Gitea Actions가 server-nginx-default를 서버의 /etc/nginx/sites-available/default로 복사
  2. HTTPS 서버 블록 추가:

# Auth server configuration
server {
    listen 80;
    server_name auth.ro-being.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name auth.ro-being.com;

    ssl_certificate /etc/letsencrypt/live/auth.ro-being.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.ro-being.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:9000/;  # 끝에 / 필수!
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # OAuth 콜백 타임아웃 늘리기
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
    }
}

최종 결과

  • HTTPS 접속: 정상 작동
  • HTTP → HTTPS 리다이렉션: 설정됨
  • SSL 인증서: 유효 (2025-10-14까지)
  • Health check: 정상 응답
  • OAuth 타임아웃: 300초로 설정

교훈

  1. Nginx proxy_pass 설정: 끝에 / 유무가 경로 전달에 중요한 영향
  2. 중앙 인증의 장점: 토큰 관리 일원화, 보안 강화, 확장성
  3. 마이크로서비스 구조: 각 서비스(인증, API, 로빙)를 독립적으로 관리
  4. SSL 설정 패턴: HTTP는 HTTPS로 리다이렉션, HTTPS 블록에 실제 프록시 설정
  5. nginx-infra 워크플로우: 로컬 수정 → Git push → Gitea Actions → 서버 배포

nginx/TLS 현재 상태 (2025-09-15 확인)

443 포트 사용 현황

sudo ss -tlnp | grep 443
# nginx (PID: 1732569)가 443 포트 사용 중

nginx 설정 파일 위치

  • 메인 설정: /etc/nginx/sites-available/default
  • 활성 설정: /etc/nginx/sites-enabled/default (심볼릭 링크)
  • 실행 중 설정 확인: sudo nginx -T

SSL 인증서 위치 및 상태

  • Let's Encrypt 인증서 디렉토리: /etc/letsencrypt/live/
    • ro-being.com/: fullchain.pem, privkey.pem, cert.pem, chain.pem (2025-09-12 갱신)
    • auth.ro-being.com/: 동일 구조
  • 인증서 유효기간: 2025-09-11 ~ 2025-12-10 (Let's Encrypt R13 발급)
  • Certbot 자동 갱신: 90일마다

HTTPS 활성화된 도메인 (sites-available/default)

  1. ro-being.com (161번 라인 server 블록)

    • listen 443 ssl; (Certbot 관리)
    • 문서 루트: /home/admin/frontend-customer/dist
  2. git.ro-being.com (314번 라인)

    • listen 443 ssl http2; (315번 라인)
    • 프록시: localhost:3000 (Gitea)
    • 인증서: /etc/letsencrypt/live/ro-being.com/
  3. auth.ro-being.com (348번 라인)

    • listen 443 ssl http2; (349번 라인)
    • 프록시: localhost:9000 (auth-server)
    • 인증서: /etc/letsencrypt/live/auth.ro-being.com/

프록시 설정 패턴

location /api/ {
    proxy_pass http://localhost:8000;  # 끝 / 주의
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

포트별 서비스

  • 80: nginx (HTTP → HTTPS 리다이렉트)
  • 443: nginx (HTTPS)
  • 3000: Gitea
  • 8000: 다른 서비스 (health check 응답)
  • 9000: auth-server
  • 9200: OpenSearch (HTTP only)
  • 5601: OpenSearch Dashboards

OpenSearch 상태

  • 컨테이너: opensearch (hostexecutor-opensearch-node)
  • TLS: 데모 인증서만 설정 (esnode.pem)
  • 접속: http://localhost:9200 (내부 HTTP)
  • 결정: nginx 리버스 프록시 방식 사용 (TLS 종료)

유용한 확인 명령어

# nginx 설정에서 443 포트 찾기
grep -n "listen 443" /etc/nginx/sites-available/default

# 인증서 확인
sudo ls -la /etc/letsencrypt/live/

# SSL 핸드셰이크 테스트
openssl s_client -connect localhost:443 -servername ro-being.com

# HTTPS 응답 확인
curl -I https://ro-being.com