headscale-tailscale-replace.../PREAUTH_KEY_MANAGEMENT_GUIDE.md
시골약사 35ecd4748e PharmQ SaaS 구독 서비스 관리 시스템 완전 구현
📋 기획 및 설계:
- PharmQ SaaS 서비스 기획서 작성
- 구독 서비스 라인업 정의 (클라우드PC, AI CCTV, CRM)
- DB 스키마 설계 및 API 아키텍처 설계

🗄️ 데이터베이스 구조:
- service_products: 서비스 상품 마스터 테이블
- pharmacy_subscriptions: 약국별 구독 현황 테이블
- subscription_usage_logs: 서비스 이용 로그 테이블
- billing_history: 결제 이력 테이블
- 샘플 데이터 자동 생성 (21개 구독, 월 118만원 매출)

🔧 백엔드 API 구현:
- 구독 현황 통계 API (/api/subscriptions/stats)
- 약국별 구독 조회 API (/api/pharmacies/subscriptions)
- 구독 상세 정보 API (/api/pharmacy/{id}/subscriptions)
- 구독 생성/해지 API (/api/subscriptions)

🖥️ 프론트엔드 UI 구현:
- 대시보드 구독 현황 카드 (월 매출, 구독 수, 구독률 등)
- 약국 목록에 구독 상태 아이콘 및 월 구독료 표시
- 약국 상세 페이지 구독 서비스 섹션 추가
- 실시간 구독 생성/해지 기능 구현

 주요 특징:
- 서비스별 색상 코딩 및 이모지 아이콘 시스템
- 실시간 업데이트 (구독 생성/해지 즉시 반영)
- 반응형 디자인 (모바일/태블릿 최적화)
- 툴팁 기반 상세 정보 표시

📊 현재 구독 현황:
- 총 월 매출: ₩1,180,000
- 구독 약국: 10/14개 (71.4%)
- AI CCTV: 6개 약국, CRM: 10개 약국, 클라우드PC: 5개 약국

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-11 19:48:12 +09:00

14 KiB

🔑 FARMQ Headscale Pre-auth Key 관리 가이드

📚 목차

  1. Pre-auth Key 개념
  2. 키 유형별 비교
  3. 약국 환경별 사용 전략
  4. 실제 명령어 예시
  5. 보안 관리
  6. 문제 해결
  7. 체크리스트

🧠 Pre-auth Key 개념

Pre-auth Key란?

  • 사전 인증 키: 클라이언트가 Headscale 서버에 자동 등록할 수 있는 "입장권"
  • 일회용 패스워드 개념으로, 관리자가 미리 생성해서 배포
  • 보안 계층: 무작위 접속을 방지하는 첫 번째 보안 장벽

작동 원리

sequenceDiagram
    participant Admin as 관리자
    participant Server as Headscale 서버
    participant Client as 클라이언트

    Admin->>Server: 1. PreAuth 키 생성
    Server-->>Admin: 2. 키 반환 (abc123def456...)
    Admin->>Client: 3. 키 전달
    Client->>Server: 4. 키와 함께 등록 요청
    Server->>Server: 5. 키 검증
    Server-->>Client: 6. 승인 및 VPN 설정 전송
    Server->>Server: 7. 키 사용됨 표시 (일회용인 경우)

🔄 키 유형별 비교

1. 일회용 키 (Single-use Key)

# 생성 명령어
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 1h

# 특징
✅ 최고 수준 보안
✅ 정확한 기기 추적 가능
❌ 매번 새 키 생성 필요
❌ 관리 복잡도 높음

2. 재사용 키 (Reusable Key)

# 생성 명령어
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 7d --reusable

# 특징
✅ 편리한 관리
✅ 여러 기기에서 동일 키 사용
⚠️ 키 노출 시 보안 위험
⚠️ 기기별 구분 어려움

3. 임시 키 (Ephemeral Key)

# 생성 명령어
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 30m --ephemeral

# 특징
✅ 일시적 접속용 최적
✅ 네트워크에서 자동 제거
❌ 영구 연결 불가
❌ 재시작 시 재등록 필요

🏥 약국 환경별 사용 전략

전략 1: 약국별 개별 키 (🌟 권장)

적용 대상

  • 정기적으로 운영되는 약국
  • 여러 POS 단말기가 있는 매장
  • 보안이 중요한 환경

설정 예시

# 1단계: 약국별 사용자 생성
docker exec headscale headscale users create pharmacy-gangnam
docker exec headscale headscale users create pharmacy-hongdae
docker exec headscale headscale users create pharmacy-itaewon

# 2단계: 사용자 ID 확인
docker exec headscale headscale users list
# 출력:
# ID | Name
# 1  | myuser
# 2  | pharmacy-gangnam  
# 3  | pharmacy-hongdae
# 4  | pharmacy-itaewon

# 3단계: 약국별 재사용 키 생성
docker exec headscale headscale preauthkeys create --user 2 --expiration 30d --reusable
# 강남약국용: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0

docker exec headscale headscale preauthkeys create --user 3 --expiration 30d --reusable  
# 홍대약국용: z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0f9e8d7c6b5a4z3y2x1w0

docker exec headscale headscale preauthkeys create --user 4 --expiration 30d --reusable
# 이태원약국용: m5n6o7p8q9r0s1t2u3v4w5x6y7z8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o3p4

장점

  • 약국별 구분: 네트워크에서 약국별로 명확히 구분
  • 부분적 보안: 한 약국의 키 노출이 다른 약국에 영향 없음
  • 관리 용이: 약국별로 키 갱신 및 관리 가능
  • 확장성: 새 약국 추가 시 독립적으로 관리

전략 2: 지역별 그룹 키

적용 대상

  • 같은 지역 내 여러 지점
  • 관리 구역별 분할 필요 시
  • 중간 규모 보안 요구사항
# 지역별 사용자 생성
docker exec headscale headscale users create region-seoul
docker exec headscale headscale users create region-busan
docker exec headscale headscale users create region-daegu

# 지역별 키 생성 (서울 지역 모든 약국이 공유)
docker exec headscale headscale preauthkeys create --user 2 --expiration 14d --reusable

전략 3: 단일 공통 키 (⚠️ 비권장)

적용 대상

  • 테스트 환경
  • 매우 소규모 운영 (5개 미만 약국)
  • 관리 리소스 극도로 제한적인 경우
# 모든 약국이 하나의 키 공유
docker exec headscale headscale preauthkeys create --user 1 --expiration 90d --reusable

단점

  • 보안 위험: 키 하나만 노출되면 전체 네트워크 위험
  • 관리 복잡: 문제 발생 시 원인 추적 어려움
  • 확장성 부족: 규모 증가 시 관리 한계

💻 실제 명령어 예시

FARMQ 표준 설정 (권장)

1단계: 약국 등록 준비

# 새 약국 등록 시 실행할 명령어들

# 약국명 변수 설정 (편의를 위해)
PHARMACY_NAME="pharmacy-myeongdong"
EXPIRATION="30d"  # 30일 만료

echo "🏥 새 약국 등록: $PHARMACY_NAME"

2단계: 사용자 생성

# 사용자 생성
docker exec headscale headscale users create "$PHARMACY_NAME"

# 생성 결과 확인
docker exec headscale headscale users list

3단계: 사용자 ID 확인

# 방법 1: 수동 확인
docker exec headscale headscale users list | grep "$PHARMACY_NAME"

# 방법 2: 자동 추출 (스크립트용)
USER_ID=$(docker exec headscale headscale users list | grep "$PHARMACY_NAME" | awk '{print $1}')
echo "사용자 ID: $USER_ID"

4단계: Pre-auth 키 생성

# 재사용 가능한 키 생성
PREAUTH_KEY=$(docker exec headscale headscale preauthkeys create --user "$USER_ID" --expiration "$EXPIRATION" --reusable | tail -1)

echo "🔑 생성된 Pre-auth Key:"
echo "$PREAUTH_KEY"

5단계: 클라이언트에서 사용

# 약국의 각 기기에서 실행
sudo tailscale up \
    --login-server=http://192.168.0.151:8070 \
    --authkey="$PREAUTH_KEY" \
    --hostname=myeongdong-pos1 \
    --accept-dns=false

sudo tailscale up \
    --login-server=http://192.168.0.151:8070 \
    --authkey="$PREAUTH_KEY" \
    --hostname=myeongdong-pos2 \
    --accept-dns=false

sudo tailscale up \
    --login-server=http://192.168.0.151:8070 \
    --authkey="$PREAUTH_KEY" \
    --hostname=myeongdong-office \
    --accept-dns=false

특수 상황별 명령어

임시 접속 (매니저 노트북)

# 2시간 짜리 일회용 키
docker exec headscale headscale preauthkeys create --user "$USER_ID" --expiration 2h

# 일시적 접속 (재부팅 시 자동 해제)
docker exec headscale headscale preauthkeys create --user "$USER_ID" --expiration 1h --ephemeral

기술 지원용 (원격 지원)

# 30분 짜리 ephemeral 키 (지원 완료 후 자동 삭제)
docker exec headscale headscale preauthkeys create --user "$USER_ID" --expiration 30m --ephemeral

테스트용 (개발/검증)

# 테스트 사용자 및 짧은 만료시간
docker exec headscale headscale users create test-environment
docker exec headscale headscale preauthkeys create --user [TEST_USER_ID] --expiration 15m --reusable

🔐 보안 관리

키 생명주기 관리

1. 키 생성 정책

# 권장 만료시간 설정
# - 일반 약국: 30일
# - 임시 접속: 2-8시간  
# - 기술 지원: 30분-1시간
# - 테스트: 15분-1시간

# 예시: 단계별 만료시간
docker exec headscale headscale preauthkeys create --user 2 --expiration 30d --reusable   # 운영
docker exec headscale headscale preauthkeys create --user 2 --expiration 4h              # 임시
docker exec headscale headscale preauthkeys create --user 2 --expiration 30m --ephemeral # 지원

2. 키 갱신 스케줄

# 월별 키 갱신 스크립트 (cron 등록 권장)
#!/bin/bash
# monthly-key-renewal.sh

PHARMACIES=("pharmacy-gangnam" "pharmacy-hongdae" "pharmacy-itaewon")

for pharmacy in "${PHARMACIES[@]}"; do
    echo "🔄 갱신 중: $pharmacy"
    
    # 기존 키 만료 처리 (수동)
    echo "⚠️ 기존 키를 수동으로 비활성화하세요"
    
    # 새 키 생성
    USER_ID=$(docker exec headscale headscale users list | grep "$pharmacy" | awk '{print $1}')
    NEW_KEY=$(docker exec headscale headscale preauthkeys create --user "$USER_ID" --expiration 30d --reusable | tail -1)
    
    echo "🔑 $pharmacy 새 키: $NEW_KEY"
    echo "📧 약국에 새 키 전달 필요"
done

3. 키 모니터링

# 활성 키 확인
docker exec headscale headscale preauthkeys list --user [USER_ID]

# 만료 예정 키 확인 (스크립트화 권장)
docker exec headscale headscale preauthkeys list --user [USER_ID] | grep -E "(expires|expired)"

보안 사고 대응

키 노출 시 대응 절차

# 1단계: 즉시 새 키 생성
EMERGENCY_KEY=$(docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 7d --reusable | tail -1)

# 2단계: 해당 약국에 긴급 연락
echo "🚨 긴급 키 교체 필요"
echo "새 키: $EMERGENCY_KEY"

# 3단계: 기존 키로 등록된 노드 확인
docker exec headscale headscale nodes list --user [USER_ID]

# 4단계: 의심스러운 노드 제거 (필요시)
# docker exec headscale headscale nodes delete [NODE_ID]

접근 제한 설정

태그 기반 접근 제어 (고급)

# 약국별 태그 설정
docker exec headscale headscale preauthkeys create \
    --user [USER_ID] \
    --expiration 30d \
    --reusable \
    --tags "pharmacy:gangnam,role:pos"

# 지역별 접근 제한
docker exec headscale headscale preauthkeys create \
    --user [USER_ID] \
    --expiration 30d \
    --reusable \
    --tags "region:seoul,type:retail"

🔧 문제 해결

일반적인 문제들

1. "invalid auth key" 오류

# 원인: 키 만료, 잘못된 키, 이미 사용된 일회용 키
# 진단:
docker exec headscale headscale preauthkeys list --user [USER_ID]

# 해결: 새 키 생성
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 1h --reusable

2. "user not found" 오류

# 원인: 존재하지 않는 사용자 ID
# 진단:
docker exec headscale headscale users list

# 해결: 사용자 생성
docker exec headscale headscale users create [USERNAME]

3. "foreign key constraint" 오류

# 원인: 데이터베이스 무결성 문제 (FARMQ 확장 테이블과 충돌)
# 해결: 기존 사용자 사용 또는 데이터베이스 정리
docker exec headscale headscale users list  # 기존 사용자 확인
# 기존 사용자 ID로 키 생성

디버깅 명령어

# 전체 키 목록 확인
docker exec headscale headscale preauthkeys list

# 특정 사용자의 키 목록
docker exec headscale headscale preauthkeys list --user [USER_ID]

# 노드 등록 상태 확인
docker exec headscale headscale nodes list

# 로그 확인
docker logs headscale | grep -i "preauth\|auth\|key"

📋 체크리스트

새 약국 등록 체크리스트

  • 약국명 결정 (naming convention 준수)
  • Headscale 사용자 생성
  • 사용자 ID 확인
  • 적절한 만료시간으로 Pre-auth 키 생성
  • 키를 안전한 방법으로 약국에 전달
  • 약국에서 클라이언트 등록 테스트
  • 네트워크 연결 확인
  • FARMQ 관리자 페이지에서 확인

정기 보안 점검 체크리스트

  • 만료 예정 키 확인 (30일 전 알림)
  • 사용되지 않는 키 정리
  • 의심스러운 노드 연결 확인
  • 키 사용 로그 검토
  • 백업된 키 정보 업데이트

긴급 상황 대응 체크리스트

  • 키 노출 확인 시 즉시 새 키 생성
  • 해당 약국에 긴급 연락
  • 의심스러운 노드 차단
  • 사고 경위 문서화
  • 재발 방지 대책 수립

📚 명령어 참조 카드

자주 사용하는 명령어

# === 사용자 관리 ===
docker exec headscale headscale users create [USERNAME]
docker exec headscale headscale users list

# === 키 생성 ===
# 일회용
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 1h

# 재사용 (일반적)
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 30d --reusable

# 임시 (ephemeral)
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 30m --ephemeral

# === 키 관리 ===
docker exec headscale headscale preauthkeys list --user [USER_ID]
docker exec headscale headscale preauthkeys expire [KEY_ID]

# === 노드 관리 ===  
docker exec headscale headscale nodes list
docker exec headscale headscale nodes list --user [USER_ID]
docker exec headscale headscale nodes delete [NODE_ID]

클라이언트 명령어

# 표준 등록
sudo tailscale up \
    --login-server=http://192.168.0.151:8070 \
    --authkey=[PREAUTH_KEY] \
    --hostname=[HOSTNAME] \
    --accept-dns=false

# 상태 확인
tailscale status
tailscale ip -4

# 연결 해제
sudo tailscale down
sudo tailscale logout

🎯 모범 사례 요약

DO

  • 약국별 개별 키 사용
  • 적절한 만료시간 설정 (30일 권장)
  • 정기적인 키 갱신
  • 키 전달 시 보안 채널 사용
  • 키 사용 로그 모니터링

DON'T

  • 모든 약국이 하나의 키 공유하지 않기
  • 만료시간 너무 길게 설정하지 않기 (90일 이상)
  • 키를 평문으로 이메일 전송하지 않기
  • 만료된 키 방치하지 않기
  • 키 백업 없이 운영하지 않기

🎊 체계적인 키 관리로 안전한 FARMQ 네트워크를 운영하세요!