zioinfo-mail/workspace/guardia-docs/22_GUARDiA_개방망_운영가이드.md
DESKTOP-TKLFCPR\ython cfe2901a55 refactor(structure): consolidate all projects under workspace/
- itsm/    -> workspace/guardia-itsm/
- manager/ -> workspace/guardia-manager/
- app/     -> workspace/guardia-messenger/
- manual/  -> workspace/guardia-docs/

workspace/zioinfo-web/ unchanged.
git mv preserves full commit history.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:50:56 +09:00

13 KiB

GUARDiA ITSM 개방망 운영 가이드

버전: 2.0.0 | 작성일: 2026-05-30
서버: zio-server (zioinfo.co.kr)


1. 개요

GUARDiA ITSM은 기본적으로 폐쇄망(Closed Network) 환경에서 동작하도록 설계되어 있습니다.
본 가이드는 GUARDiA를 개방망(Open Network) 에서도 안전하게 서비스하기 위한 구성 방법을 설명합니다.

1-1. 폐쇄망 vs 개방망 비교

항목 폐쇄망 (기본) 개방망 (이 가이드)
접근 범위 내부망 only 인터넷 외부 접근 허용
CORS localhost 만 허용 지정 외부 도메인 허용
HTTPS 선택 필수
API 인증 JWT JWT + API Key 추가
외부 AI 호출 금지 (Ollama only) 금지 유지 (변경 불가)
Rate Limiting 기본 강화 (30req/min)
보안 헤더 기본 HSTS 포함 강화

1-2. 개방망 지원 아키텍처

외부 클라이언트 (브라우저, 메신저봇, 외부시스템)
        │
        │ HTTPS (443 / 8443)
        ▼
┌─────────────────────────────────────────────────┐
│  Nginx (TLS 종료 프록시)                          │
│  ├── SSL/TLS (자체서명 or Let's Encrypt)          │
│  ├── Rate Limiting (30 req/min)                  │
│  ├── 보안 헤더 (HSTS, X-Frame, X-XSS)            │
│  └── CORS 정책 적용                              │
└─────────────────┬───────────────────────────────┘
                  │ HTTP (내부)
                  ▼
┌─────────────────────────────────────────────────┐
│  GUARDiA ITSM FastAPI (포트 8001)                │
│  ├── GUARDIA_NETWORK_MODE=open                  │
│  ├── CORS: 지정 외부 도메인 허용                  │
│  ├── 보안 미들웨어 (HSTS, X-Frame, CSP)          │
│  └── /api/external/* (API Key 인증)              │
└─────────────────┬───────────────────────────────┘
                  │
          ┌───────┴────────┐
          ▼                ▼
   PostgreSQL         Ollama LLM
   (내부 전용)        (내부 전용)
   localhost:5432     localhost:11434

핵심 원칙: LLM(Ollama)과 DB는 외부에서 직접 접근 불가. API 서버만 노출.


2. 설치 및 구성

2-1. 사전 요구사항

항목 요구 사항
OS Ubuntu 20.04+
Nginx 1.18+
SSL 인증서 자체서명 or Let's Encrypt
GUARDiA 2.0.0+
Python 3.11+

2-2. SSL 인증서 생성

자체 서명 인증서 (테스트/내부망):

mkdir -p /etc/ssl/guardia
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
    -keyout /etc/ssl/guardia/server.key \
    -out    /etc/ssl/guardia/server.crt \
    -subj   "/C=KR/ST=Seoul/O=YourOrg/CN=your-server-ip" \
    -addext "subjectAltName=IP:zioinfo.co.kr"
chmod 600 /etc/ssl/guardia/server.key

Let's Encrypt (도메인 보유 시 — 권장):

apt install certbot python3-certbot-nginx
certbot --nginx -d itsm.zioinfo.co.kr
# 자동 갱신 확인
certbot renew --dry-run

2-3. 환경변수 설정 (.env)

cp /opt/guardia/app/.env.open /opt/guardia/app/.env
nano /opt/guardia/app/.env

개방망 필수 설정:

# 개방망 모드 활성화
GUARDIA_NETWORK_MODE=open

# 허용할 외부 출처 (쉼표 구분)
GUARDIA_ALLOWED_ORIGINS=https://itsm.zioinfo.co.kr,https://portal.myorg.go.kr

# 웹훅 HMAC 시크릿 (반드시 변경)
GUARDIA_WEBHOOK_SECRET=your-strong-secret-here

# DB (특수문자 URL 인코딩 필수: @ → %40, ! → %21)
DATABASE_URL=postgresql+asyncpg://guardia:G%40urd1a_2026%21@localhost:5432/guardia_db

# LLM (내부 전용 — 절대 변경 금지)
OLLAMA_BASE_URL=http://localhost:11434
LLM_MODEL=llama3:8b

2-4. Nginx 개방망 설정

# Nginx http 블록에 rate limit zone 추가
nano /etc/nginx/nginx.conf
http {
    limit_req_zone $binary_remote_addr zone=guardia_api:10m rate=30r/m;
    ...
}

/etc/nginx/sites-available/guardia-https 생성:

server {
    listen 8443 ssl;
    server_name _;

    ssl_certificate     /etc/ssl/guardia/server.crt;
    ssl_certificate_key /etc/ssl/guardia/server.key;
    ssl_protocols       TLSv1.2 TLSv1.3;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;

    location /api/ {
        limit_req zone=guardia_api burst=10 nodelay;
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header X-Forwarded-Proto https;
    }
    location / {
        proxy_pass http://127.0.0.1:8001;
    }
}
ln -sf /etc/nginx/sites-available/guardia-https /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

2-5. 서비스 재시작

systemctl restart guardia
systemctl is-active guardia

3. 외부 API 사용법

3-1. API 엔드포인트 목록

엔드포인트 메서드 인증 설명
/api/external/health GET 불필요 헬스체크
/api/external/status GET 불필요 시스템 공개 상태
/api/external/keys GET JWT (관리자) API Key 목록
/api/external/keys POST JWT (관리자) API Key 발급
/api/external/keys/{id} DELETE JWT (관리자) API Key 비활성화
/api/external/sr GET API Key (read) SR 목록 조회
/api/external/sr POST API Key (write) SR 등록
/api/external/webhook POST HMAC (선택) 외부 메신저 웹훅
/docs GET 불필요 OpenAPI 문서

3-2. API Key 발급

1단계: 관리자 로그인 (JWT 획득)

curl -X POST https://zioinfo.co.kr:8443/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin@zioinfo2026!"}' \
  -k
# → {"access_token": "eyJ...", "token_type": "bearer"}

2단계: API Key 발급

TOKEN="eyJ..."
curl -X POST https://zioinfo.co.kr:8443/api/external/keys \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "카카오워크 봇",
    "scopes": "read,write,webhook",
    "expires_days": 365,
    "allowed_ips": ""
  }' -k

응답 (발급 후 1회만 노출):

{
  "id": 1,
  "name": "카카오워크 봇",
  "api_key": "grd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "scopes": "read,write,webhook",
  "expires_at": "2027-05-30T10:00:00",
  "warning": "이 키는 다시 조회할 수 없습니다. 안전한 곳에 저장하세요."
}

3-3. API Key로 SR 등록

API_KEY="grd_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# SR 등록
curl -X POST https://zioinfo.co.kr:8443/api/external/sr \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "웹서버 재시작 요청",
    "description": "nginx가 502 오류를 반환하고 있습니다.",
    "priority": "HIGH",
    "requester_name": "홍길동",
    "requester_email": "hong@example.go.kr"
  }' -k

3-4. 외부 메신저 웹훅 연동

# Gitea/Slack/카카오워크 웹훅 URL 설정
WEBHOOK_URL="https://zioinfo.co.kr:8443/api/external/webhook"
SECRET="guardia-webhook-secret-change-me-2026"

# 서명 생성 (Python)
python3 -c "
import hmac, hashlib, json
body = json.dumps({'command': '서버 상태 확인', 'user_id': 'user01'})
sig = 'sha256=' + hmac.new(b'$SECRET', body.encode(), hashlib.sha256).hexdigest()
print(sig)
"

# 웹훅 전송
curl -X POST $WEBHOOK_URL \
  -H "Content-Type: application/json" \
  -H "X-GUARDiA-Signature: sha256=<서명값>" \
  -H "X-Source: kakaotalk" \
  -d '{"command": "서버 상태 확인", "user_id": "홍길동"}' \
  -k

4. API Key 권한 스코프

스코프 설명 허용 API
read 읽기 전용 SR 목록 조회
write 쓰기 SR 등록, 상태 변경
admin 전체 권한 모든 외부 API
webhook 웹훅 전용 /api/external/webhook

스코프 조합 예시:

"scopes": "read,write"      // 조회 + 등록
"scopes": "webhook"         // 웹훅만
"scopes": "admin"           // 전체 (주의)

5. 보안 설정

5-1. 적용된 보안 헤더

헤더 효과
Strict-Transport-Security max-age=31536000 브라우저가 HTTPS만 사용
X-Frame-Options DENY iframe 삽입 차단
X-Content-Type-Options nosniff MIME 타입 스니핑 방지
X-XSS-Protection 1; mode=block XSS 공격 차단
Referrer-Policy strict-origin-when-cross-origin Referrer 정보 제한

5-2. Rate Limiting 설정

위치 제한
Nginx (기본) 30 req/min per IP
Nginx (burst) 최대 10 req 버스트 허용
FastAPI (ratelimit.py) 별도 설정 가능

5-3. IP 화이트리스트 (API Key)

특정 외부 시스템만 API Key를 사용할 수 있도록 IP를 제한할 수 있습니다:

{
  "name": "공공기관 포털",
  "scopes": "read,write",
  "allowed_ips": "203.10.20.30,203.10.20.31"
}

빈 문자열("")로 설정하면 모든 IP에서 접근 가능합니다.

5-4. 변경 불가 보안 정책

개방망 모드에서도 다음 정책은 절대 변경 불가합니다.

정책 내용
외부 LLM 금지 Ollama(localhost:11434)만 사용. OpenAI, Claude 등 외부 API 완전 금지
SSH 자격증명 보호 IP, 비밀번호, SSH 계정을 API 응답에 포함 금지
AES-256 암호화 서버 자격증명은 암호화 저장
root SSH 금지 opsagent 전용 계정 사용

6. 모드 전환

6-1. 폐쇄망 → 개방망

# .env 수정
echo "GUARDIA_NETWORK_MODE=open" >> /opt/guardia/app/.env
echo "GUARDIA_ALLOWED_ORIGINS=https://your-domain.go.kr" >> /opt/guardia/app/.env

# Nginx HTTPS 활성화
ln -sf /etc/nginx/sites-available/guardia-https /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

# 서비스 재시작
systemctl restart guardia

6-2. 개방망 → 폐쇄망 (롤백)

# .env 수정
sed -i 's/GUARDIA_NETWORK_MODE=open/GUARDIA_NETWORK_MODE=closed/' /opt/guardia/app/.env

# HTTPS 비활성화
rm /etc/nginx/sites-enabled/guardia-https
systemctl reload nginx

# 서비스 재시작
systemctl restart guardia

7. 테스트 결과

7-1. 테스트 환경

항목
서버 Ubuntu 24.04 LTS (zioinfo.co.kr)
GUARDiA 버전 2.0.0
Nginx 버전 1.24.0
테스트 일자 2026-05-30

7-2. 테스트 결과

테스트 항목 결과
T1 HTTP 헬스체크 (8001) HTTP 200
T2 HTTPS 헬스체크 (8443) HTTP 200
T3 홈페이지 HTTPS (443) HTTP 200
T4 미인증 API 접근 HTTP 401 반환
T5 CORS 외부 출처 허용 Access-Control-Allow-Origin 헤더
T6 HSTS 헤더 Strict-Transport-Security 적용
T7 X-Frame-Options DENY 설정
T8 Rate Limiting Nginx rate limit zone 설정
T9 시스템 상태 공개 operational
T10 개방망 모드 활성 NETWORK_MODE=open

8. 트러블슈팅

8-1. CORS 오류

증상: 브라우저에서 Access-Control-Allow-Origin 오류

# .env에 도메인 추가
GUARDIA_ALLOWED_ORIGINS=https://your-domain.com,https://other-domain.go.kr
systemctl restart guardia

8-2. HTTPS 인증서 오류

증상: SSL: CERTIFICATE_VERIFY_FAILED

# 자체서명 인증서인 경우 curl에 -k 플래그 사용
curl -k https://zioinfo.co.kr:8443/api/external/health

# 브라우저에서는 예외 추가 또는 Let's Encrypt 인증서 사용

8-3. Rate Limit 초과

증상: HTTP 429 Too Many Requests

# Nginx rate limit 완화
nano /etc/nginx/nginx.conf
# rate=60r/m 으로 변경
nginx -t && systemctl reload nginx

8-4. DATABASE_URL 연결 오류

증상: Name or service not known

# @ 특수문자 URL 인코딩 확인
# G@urd1a_2026! → G%40urd1a_2026%21
sed -i 's|G@urd1a_2026!|G%40urd1a_2026%21|g' /opt/guardia/app/.env
systemctl restart guardia

9. 접속 정보 요약

서비스 URL 비고
GUARDiA ITSM (HTTP) http://zioinfo.co.kr:8001 내부망 권장
GUARDiA ITSM (HTTPS) https://zioinfo.co.kr:8443 개방망 사용
외부 API https://zioinfo.co.kr:8443/api/external/ API Key 인증
OpenAPI 문서 https://zioinfo.co.kr:8443/docs 무인증
홈페이지 HTTPS https://zioinfo.co.kr 포트 443

GUARDiA ITSM v2.0.0 | (주)지오정보기술 | 2026-05-30