📋 기획 및 설계: - 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>
14 KiB
14 KiB
🔑 FARMQ Headscale Pre-auth Key 관리 가이드
📚 목차
🧠 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 네트워크를 운영하세요!