- 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>
13 KiB
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