headscale-tailscale-replace.../HEADSCALE_COMPLETE_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

424 lines
13 KiB
Markdown

# 🌐 FARMQ Headscale 완전 가이드
## 📚 목차
1. [개념 정리](#개념-정리)
2. [아키텍처 개요](#아키텍처-개요)
3. [포트 구성](#포트-구성)
4. [설치 및 구성](#설치-및-구성)
5. [클라이언트 연결 워크플로우](#클라이언트-연결-워크플로우)
6. [실제 사용 시나리오](#실제-사용-시나리오)
7. [문제 해결](#문제-해결)
---
## 🧠 개념 정리
### Tailscale vs Headscale vs Headplane
#### 1. **Tailscale** (원본 서비스)
- **정의**: 상용 VPN 서비스 (SaaS)
- **특징**:
- 클라우드 기반 coordination server 사용
- 구독 기반 유료 서비스
- 자동화된 관리
- **단점**:
- 데이터가 외부 서버를 거침
- 비용 발생
- 프라이버시 우려
#### 2. **Headscale** (오픈소스 서버)
- **정의**: Tailscale의 coordination server를 대체하는 오픈소스 구현
- **특징**:
- 자체 호스팅 가능
- 완전한 프라이버시 제어
- 무료 사용
- REST API 제공
- **역할**:
- 클라이언트 인증 및 등록
- IP 주소 할당
- 라우팅 테이블 관리
- 키 교환 coordination
#### 3. **Headplane** (웹 UI)
- **정의**: Headscale을 관리하기 위한 웹 인터페이스
- **특징**:
- 브라우저에서 노드 관리
- 시각적 네트워크 상태 확인
- 사용자 및 키 관리
#### 4. **클라이언트 (Tailscale 클라이언트)**
- **정의**: 실제 VPN 연결을 담당하는 클라이언트 프로그램
- **중요**: Tailscale의 **클라이언트 소프트웨어**를 그대로 사용
- **변경점**: 서버 주소만 Headscale 서버로 지정
---
## 🏗️ 아키텍처 개요
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 클라이언트 PC │ │ Headscale │ │ 클라이언트 PC │
│ │ │ 서버 │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Tailscale │◄────┼─┤ Headscale │─┼────┤ │ Tailscale │ │
│ │ Client │ │ │ │ Server │ │ │ │ Client │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
│ │ │ ┌─────────────┐ │ │ │
│ │ │ │ Headplane │ │ │ │
│ │ │ │ Web UI │ │ │ │
│ │ │ └─────────────┘ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────────────┼────────────────────────┘
┌─────────────────┐
│ FARMQ Flask │
│ Admin Panel │
└─────────────────┘
```
### 데이터 흐름
1. **등록**: 클라이언트 → Headscale 서버 (인증)
2. **키 교환**: Headscale 서버 → 클라이언트들 (P2P 키 정보)
3. **실제 통신**: 클라이언트 ↔ 클라이언트 (직접 P2P)
4. **관리**: Headplane/Flask UI → Headscale API
---
## 🔌 포트 구성
### 현재 FARMQ 설정
| 서비스 | 포트 | 프로토콜 | 용도 | 접근 |
|--------|------|----------|------|------|
| **Headscale Server** | `8070` | HTTP | 클라이언트 등록/관리 | 클라이언트 ← → 서버 |
| **Headplane UI** | `3000` | HTTP | 웹 관리 인터페이스 | 관리자 → 웹브라우저 |
| **FARMQ Admin** | `5001` | HTTP | 한국어 관리 페이지 | 관리자 → 웹브라우저 |
### 중요한 포인트
- **클라이언트가 사용하는 포트**: `8070` (Headscale 서버)
- **관리자가 사용하는 포트**: `3000` (Headplane), `5001` (FARMQ Admin)
- **내부 컨테이너 포트**: `8080` (Docker 내부에서만 사용)
---
## 🛠️ 설치 및 구성
### 1. 서버 구성 (이미 완료)
```bash
# 서버 시작
cd /srv/headscale-setup
docker-compose up -d
# 서비스 확인
docker-compose ps
```
### 2. 클라이언트 설치 과정
#### Step 1: Tailscale 클라이언트 설치
```bash
# Ubuntu/Debian
curl -fsSL https://tailscale.com/install.sh | sh
# 또는 수동 설치
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/$(lsb_release -cs).noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/$(lsb_release -cs).tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt update
sudo apt install tailscale
```
#### Step 2: Headscale 서버에 등록
```bash
# 기본 명령어 형식
sudo tailscale up --login-server=http://[서버IP]:8070 --authkey=[PreAuth키]
# FARMQ 실제 명령어 예시
sudo tailscale up \
--login-server=http://192.168.0.151:8070 \
--authkey=YOUR_PREAUTH_KEY_HERE \
--hostname=pharmacy-busan-pc1 \
--accept-dns=false
```
---
## 🔄 클라이언트 연결 워크플로우
### 전체 프로세스
```mermaid
sequenceDiagram
participant Admin as 관리자
participant Server as Headscale 서버
participant Client as 클라이언트 PC
participant Network as VPN 네트워크
Admin->>Server: 1. 사용자 생성
Admin->>Server: 2. PreAuth 키 생성
Admin->>Client: 3. PreAuth 키 전달
Client->>Client: 4. Tailscale 클라이언트 설치
Client->>Server: 5. 등록 요청 (PreAuth 키 포함)
Server->>Client: 6. 인증 완료 및 설정 전달
Client->>Network: 7. VPN 네트워크 참여
Network->>Client: 8. 다른 노드들과 P2P 연결
```
### 상세 단계별 설명
#### 1. 서버 측 작업 (관리자)
```bash
# 1-1. 사용자 생성 (한 번만)
docker exec headscale headscale users create pharmacy-busan
# 1-2. 사용자 목록 확인
docker exec headscale headscale users list
# 1-3. PreAuth 키 생성
docker exec headscale headscale preauthkeys create --user 1 --expiration 1h
# 출력 예시:
# f8d9c7e4b2a6c8f4d9e7b3a5c8f4d9e7b3a5c8f4d9e7b3a5c8f4d9e7b3a5c8f4
```
#### 2. 클라이언트 측 작업
```bash
# 2-1. 기존 연결 해제 (있다면)
sudo tailscale logout
sudo tailscale down
# 2-2. Headscale 서버에 등록
sudo tailscale up \
--login-server=http://192.168.0.151:8070 \
--authkey=f8d9c7e4b2a6c8f4d9e7b3a5c8f4d9e7b3a5c8f4d9e7b3a5c8f4d9e7b3a5c8f4 \
--hostname=pharmacy-busan-pc1 \
--accept-dns=false
# 2-3. 연결 상태 확인
tailscale status
# 2-4. IP 주소 확인
tailscale ip -4
```
#### 3. 결과 확인
```bash
# 서버에서 노드 목록 확인
docker exec headscale headscale nodes list
# 웹 UI에서 확인
# - Headplane: http://192.168.0.151:3000
# - FARMQ Admin: http://192.168.0.151:5001
```
---
## 🏥 실제 사용 시나리오
### 시나리오 1: 새 약국 등록
```bash
# 서버 작업 (관리자)
docker exec headscale headscale users create pharmacy-seoul
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 2h
# 클라이언트 작업 (약국 PC)
curl -O http://192.168.0.151:8000/add-client.sh
chmod +x add-client.sh
./add-client.sh pharmacy-seoul pos-terminal-1
# PreAuth 키 입력 시 위에서 생성한 키 사용
```
### 시나리오 2: 여러 PC가 있는 약국
```bash
# 같은 사용자로 여러 머신 등록 가능
sudo tailscale up --login-server=http://192.168.0.151:8070 --authkey=[KEY] --hostname=busan-pos1
sudo tailscale up --login-server=http://192.168.0.151:8070 --authkey=[KEY] --hostname=busan-pos2
sudo tailscale up --login-server=http://192.168.0.151:8070 --authkey=[KEY] --hostname=busan-office
```
### 시나리오 3: 임시 접속 (노트북)
```bash
# 짧은 만료시간으로 키 생성
docker exec headscale headscale preauthkeys create --user [USER_ID] --expiration 30m
# 노트북에서 임시 연결
sudo tailscale up --login-server=http://192.168.0.151:8070 --authkey=[TEMP_KEY] --hostname=manager-laptop
```
---
## 🔍 상태 확인 및 관리
### 명령어 모음
```bash
# === 서버 측 (Headscale) ===
# 사용자 관리
docker exec headscale headscale users list
docker exec headscale headscale users create [username]
# 노드 관리
docker exec headscale headscale nodes list
docker exec headscale headscale nodes expire [node_id]
# PreAuth 키 관리
docker exec headscale headscale preauthkeys list --user [user_id]
docker exec headscale headscale preauthkeys create --user [user_id] --expiration [time]
# === 클라이언트 측 (Tailscale) ===
# 상태 확인
tailscale status # 네트워크 상태 및 연결된 노드들
tailscale ip # 내 IP 주소들
tailscale netcheck # 네트워크 연결성 테스트
tailscale ping [node] # 특정 노드 ping
# 연결 관리
tailscale up # 연결 시작
tailscale down # 연결 중단
tailscale logout # 로그아웃
# 로그 확인
sudo journalctl -u tailscaled -f
```
### 웹 UI 접근
```bash
# Headplane (기본 관리 UI)
http://192.168.0.151:3000
# API 키: 8qRr1IB.tV95CmA0fLaCiGGIgBfeoN9daHceFkzI
# FARMQ 관리자 페이지 (한국어)
http://192.168.0.151:5001
```
---
## ⚠️ 중요한 주의사항
### 1. 포트 혼동 방지
- **클라이언트 등록**: `8070` 포트 사용
- **웹 관리**: `3000`, `5001` 포트 사용
- **Docker 내부**: `8080` 포트 (외부에서 직접 접근 불가)
### 2. PreAuth 키 보안
- 키는 일회용 또는 제한된 횟수만 사용 가능
- 짧은 만료시간 설정 권장 (1h ~ 24h)
- 키 노출 시 즉시 새 키 생성
### 3. 네트워크 구성
- 모든 클라이언트는 `100.64.0.0/10` 대역 IP 할당
- 첫 번째 클라이언트: `100.64.0.1` (서버 역할도 함)
- 이후 클라이언트들: `100.64.0.2`, `100.64.0.3`, ...
### 4. 방화벽 설정
```bash
# 서버 측 방화벽 (필요시)
sudo ufw allow 8070/tcp # Headscale
sudo ufw allow 3000/tcp # Headplane
sudo ufw allow 5001/tcp # FARMQ Admin
# 클라이언트 측 (Tailscale이 자동 처리)
sudo ufw allow in on tailscale0
```
---
## 🚨 문제 해결
### 일반적인 문제들
#### 1. "connection refused" 오류
```bash
# 원인: 서버 포트 접근 불가
# 해결:
docker-compose ps # 서버 실행 확인
sudo ufw status # 방화벽 확인
ping 192.168.0.151 # 서버 연결 확인
```
#### 2. "invalid auth key" 오류
```bash
# 원인: PreAuth 키 만료 또는 잘못된 키
# 해결:
docker exec headscale headscale preauthkeys create --user [user_id] --expiration 1h
```
#### 3. "user not found" 오류
```bash
# 원인: 존재하지 않는 사용자
# 해결:
docker exec headscale headscale users list # 사용자 확인
docker exec headscale headscale users create [username] # 사용자 생성
```
#### 4. IP 할당되지 않음
```bash
# 진단:
tailscale status # 연결 상태 확인
tailscale netcheck # 네트워크 테스트
sudo journalctl -u tailscaled -f # 로그 확인
# 해결:
sudo systemctl restart tailscaled # 서비스 재시작
```
### 로그 위치
```bash
# Headscale 서버 로그
docker logs headscale
# Headplane 로그
docker logs headplane
# Tailscale 클라이언트 로그
sudo journalctl -u tailscaled -f
```
---
## 📋 체크리스트
### 서버 설치 완료 확인
- [ ] Docker 및 Docker Compose 설치됨
- [ ] Headscale 컨테이너 실행 중 (포트 8070)
- [ ] Headplane 컨테이너 실행 중 (포트 3000)
- [ ] FARMQ Admin 실행 중 (포트 5001)
- [ ] 방화벽에서 필요 포트 열림
### 클라이언트 연결 확인
- [ ] Tailscale 클라이언트 설치됨
- [ ] 서버에 사용자 생성됨
- [ ] PreAuth 키 생성됨 (유효한 만료시간)
- [ ] `tailscale up` 명령어 성공
- [ ] `tailscale status`에서 다른 노드들 보임
- [ ] VPN IP 주소 할당됨 (`100.64.0.x`)
### 네트워크 연결 확인
- [ ] 서버 ping 성공 (`ping 100.64.0.1`)
- [ ] 다른 클라이언트와 ping 성공
- [ ] 웹 UI 접근 가능
---
## 🎯 다음 단계
1. **자동화 스크립트 활용**: `add-client.sh`, `create-preauth-key.sh` 사용
2. **모니터링 설정**: FARMQ Admin에서 실시간 상태 확인
3. **백업 전략**: Headscale 설정 및 데이터베이스 백업
4. **확장**: 새로운 약국 및 지점 추가
---
**🎊 이제 완전한 프라이빗 VPN 네트워크를 운영할 수 있습니다!**