Skip to content

Commit 931b770

Browse files
committed
가이드 추가: 실제 Zabbix Agent 설치 + 배포 SSH 키/GitHub Secrets 설정
- docs/ZABBIX_AGENT_ACTIVE_SETUP.md 전면 재작성(7.4): Agent2 설치(Ubuntu/RHEL/mac) → 설정(Server/ServerActive/Hostname) → Zabbix Web Host 등록 → problem 발생 → mori-worker 폴링 → MORI Alert Triage 확인 → resolve 확인 + 트러블슈팅. - docs/DEPLOY_SSH_SETUP.md 신규: ed25519 배포키 생성 → 서버 authorized_keys → known_hosts → GitHub 6종 시크릿 등록 → 동작 확인 + 보안 메모. - README 참고문서 링크 추가.
1 parent 79181f0 commit 931b770

3 files changed

Lines changed: 211 additions & 91 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ docker compose up -d mori-api
583583
| `docs/PHASE1_INPUT_SOURCES_AND_SCHEMA.md` | Phase 1 입력 소스·스키마·질의 명세 |
584584
| `docs/PHASE1_LOGICAL_SCHEMA.md` | Phase 1 논리 스키마·테이블 관계 |
585585
| `docs/DEPLOYMENT.md` | 서버 배포·운영·트러블슈팅 가이드 |
586-
| `docs/ZABBIX_AGENT_ACTIVE_SETUP.md` | Zabbix Agent 온보딩 |
586+
| **`docs/DEPLOY_SSH_SETUP.md`** | 배포용 SSH 키 생성 + GitHub Actions 시크릿 설정 (단계별) |
587+
| **`docs/ZABBIX_AGENT_ACTIVE_SETUP.md`** | 실제 Zabbix Agent 2 설치 → MORI Triage 연동 (Zabbix 7.4) |
587588
| `docs/TRIVY_USAGE.md` | Trivy 파일시스템/이미지 스캔 가이드 |
588589
| `docs/FLEET_MACBOOK_ENROLLMENT_AND_TEST.md` | Fleet macOS 등록·검증 |
589590
| `docs/FLEET_RESET_AND_REINSTALL_GUIDE.md` | Fleet 초기화·재설치 |

docs/DEPLOY_SSH_SETUP.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# 배포용 SSH 키 & GitHub Actions 시크릿 설정 가이드
2+
3+
`deploy-mori-soc` 워크플로우(`.github/workflows/deploy.yml`)가 GitHub → 배포 서버로
4+
**SSH 접속하여 자동 배포**하려면 아래 시크릿이 필요합니다. 시크릿이 없으면
5+
워크플로우는 **자동으로 스킵**(초록)되므로, 자동 배포를 쓸 때만 설정하면 됩니다.
6+
7+
| 시크릿 | 용도 | 필수 |
8+
|---|---|---|
9+
| `DEPLOY_HOST` | 배포 서버 호스트/IP ||
10+
| `DEPLOY_PORT` | SSH 포트 (기본 22) ||
11+
| `DEPLOY_USER` | SSH 로그인 계정 ||
12+
| `DEPLOY_SSH_KEY` | **개인키**(private key) 전체 내용 ||
13+
| `DEPLOY_ENV_FILE` | 서버에서 쓸 `.env` 전체 내용(멀티라인) ||
14+
| `DEPLOY_KNOWN_HOSTS` | 서버의 known_hosts 라인 | 선택(없으면 ssh-keyscan 자동) |
15+
16+
---
17+
18+
## 1. 배포 전용 SSH 키쌍 생성 (로컬)
19+
20+
개인 계정 키를 재사용하지 말고 **배포 전용 키**를 새로 만드세요.
21+
22+
```bash
23+
ssh-keygen -t ed25519 -C "mori-deploy" -f ~/.ssh/mori_deploy -N ""
24+
# 생성물:
25+
# ~/.ssh/mori_deploy ← 개인키 (GitHub Secret DEPLOY_SSH_KEY 에 넣을 것)
26+
# ~/.ssh/mori_deploy.pub ← 공개키 (서버에 등록)
27+
```
28+
29+
> `-N ""` = 패스프레이즈 없음. CI는 대화형 입력을 못 하므로 배포 키는 패스프레이즈 없이 만듭니다. (대신 이 키는 배포에만 쓰고, 유출 시 서버에서 즉시 제거)
30+
31+
---
32+
33+
## 2. 공개키를 배포 서버에 등록
34+
35+
```bash
36+
# 방법 A) ssh-copy-id (가장 간단)
37+
ssh-copy-id -i ~/.ssh/mori_deploy.pub -p <DEPLOY_PORT> <DEPLOY_USER>@<DEPLOY_HOST>
38+
39+
# 방법 B) 수동 — 서버에서
40+
# ~/.ssh/authorized_keys 에 mori_deploy.pub 내용을 한 줄로 추가
41+
mkdir -p ~/.ssh && chmod 700 ~/.ssh
42+
cat mori_deploy.pub >> ~/.ssh/authorized_keys
43+
chmod 600 ~/.ssh/authorized_keys
44+
```
45+
46+
접속 테스트(개인키로):
47+
48+
```bash
49+
ssh -i ~/.ssh/mori_deploy -p <DEPLOY_PORT> <DEPLOY_USER>@<DEPLOY_HOST> "echo OK && docker --version"
50+
```
51+
52+
`OK` 가 나오면 성공입니다.
53+
54+
---
55+
56+
## 3. known_hosts 값 얻기 (선택)
57+
58+
`DEPLOY_KNOWN_HOSTS` 를 설정하면 CI가 매번 ssh-keyscan 하지 않아 더 안전합니다.
59+
60+
```bash
61+
ssh-keyscan -p <DEPLOY_PORT> <DEPLOY_HOST>
62+
# 출력된 라인들을 그대로 DEPLOY_KNOWN_HOSTS 값으로 복사
63+
```
64+
65+
설정하지 않으면 워크플로우가 `ssh-keyscan`으로 자동 처리합니다(TOFU).
66+
67+
---
68+
69+
## 4. GitHub 저장소에 시크릿 등록
70+
71+
GitHub 저장소 → **Settings → Secrets and variables → Actions → New repository secret** 에서
72+
아래를 각각 추가합니다.
73+
74+
| Name | Value |
75+
|---|---|
76+
| `DEPLOY_HOST` | 예: `mori.example.com` |
77+
| `DEPLOY_PORT` | 예: `22` |
78+
| `DEPLOY_USER` | 예: `deploy` |
79+
| `DEPLOY_SSH_KEY` | `cat ~/.ssh/mori_deploy` **전체 출력**(`-----BEGIN … END-----` 포함) |
80+
| `DEPLOY_ENV_FILE` | 서버용 `.env` 전체 내용(멀티라인 그대로) |
81+
| `DEPLOY_KNOWN_HOSTS` | 3단계 출력(선택) |
82+
83+
개인키 복사:
84+
85+
```bash
86+
cat ~/.ssh/mori_deploy # 이 전체를 DEPLOY_SSH_KEY 값에 붙여넣기
87+
```
88+
89+
> ⚠️ **`.pub`(공개키)가 아니라 개인키 파일 내용**을 넣습니다. `DEPLOY_SSH_KEY`가 비어 있으면 "The ssh-private-key argument is empty" 에러로 실패합니다(가드로 스킵되지만 자동 배포는 안 됨).
90+
91+
---
92+
93+
## 5. 동작 확인
94+
95+
- 시크릿 등록 후 `main`에 push하거나 **Actions → deploy-mori-soc → Run workflow**(수동 실행).
96+
- 성공 시: 서버에서 `rsync``.env` 업로드 → `docker compose pull && up -d` 순으로 배포됩니다.
97+
- 시크릿을 하나라도 안 넣었으면 워크플로우는 **스킵(초록)** — 실패로 뜨지 않습니다.
98+
99+
## 6. 보안 메모
100+
101+
- 배포 키는 **배포 전용**으로만 사용하고, 서버 `authorized_keys`에서 필요 시 즉시 제거할 수 있게 관리하세요.
102+
- 가능하면 `DEPLOY_USER``docker` 그룹만 가진 **최소 권한 계정**으로 두고, 서버 방화벽에서 SSH 포트를 신뢰 IP로 제한하세요.
103+
- `DEPLOY_ENV_FILE`에는 실운영 비밀번호가 들어가므로 **GitHub Secret으로만** 관리하고 저장소에 커밋하지 마세요.

docs/ZABBIX_AGENT_ACTIVE_SETUP.md

Lines changed: 106 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,151 @@
1-
# Zabbix Agent Active 등록 가이드
1+
# 실제 Zabbix Agent 설치 & MORI 연동 가이드 (Zabbix 7.4)
22

3-
## 1. 목적
3+
실제 서버/PC에 **Zabbix Agent 2**를 설치해 MORI 스택의 Zabbix Server에 연결하고,
4+
문제(problem)가 발생하면 **MORI Alert Triage로 흘러 들어오는 것까지** 확인하는 전체 절차입니다.
45

5-
이 문서는 개인 PC 또는 테스트 단말을 **Zabbix Agent Active 방식**으로
6-
MORI SOC-lite의 Zabbix Server에 연결하는 절차를 정리합니다.
7-
8-
## 2. 권장 방식
9-
10-
권장 방식은 **Active Agent**입니다.
6+
```
7+
[대상 서버] Zabbix Agent 2 ──(Active)──▶ [MORI] Zabbix Server(10051)
8+
9+
트리거 발생 → problem
10+
│ (mori-worker 30초 폴링)
11+
12+
MORI Alert Triage → Incident → 증적
13+
```
1114

12-
- 단말이 Zabbix Server로 직접 연결
13-
- NAT/사내망 환경에서 상대적으로 구성 단순
14-
- 서버가 단말의 `10050` 포트로 직접 들어올 필요 없음
15+
권장은 **Active Agent** 방식입니다 — 단말이 서버로 outbound 접속하므로 NAT/사내망에서 구성이 단순하고, 서버가 단말의 10050 포트로 들어올 필요가 없습니다.
1516

16-
현재 서버 공개 포트 기준:
17+
---
1718

18-
- Zabbix Web: `http://mori.rmstudio.co.kr:18081`
19-
- Zabbix Server: `mori.rmstudio.co.kr:10051`
19+
## 0. 사전 확인 (MORI 측)
2020

21-
## 3. 사전 조건
21+
MORI 스택이 떠 있으면 Zabbix Server/Web은 이미 실행 중입니다.
2222

23-
- 내 PC에서 `mori.rmstudio.co.kr:10051`로 outbound 연결 가능
24-
- Zabbix Web 로그인 가능
25-
- Host 이름을 직접 지정할 수 있음
23+
```bash
24+
docker compose ps zabbix-server zabbix-web
25+
```
2626

27-
초기 Zabbix Web 계정(초기 설치 기준):
27+
- **Zabbix Web**: `http://<서버>:18081` (`.env``MORI_ZABBIX_UI_URL`, 기본 `Admin` / `zabbix`)
28+
- **Zabbix Server(agent 접속 대상)**: `<서버>:10051` (compose에서 `10051:10051` 노출)
2829

29-
- ID: `Admin`
30-
- PW: `zabbix`
30+
대상 서버에서 `<서버>:10051` 로 outbound 연결이 가능해야 합니다.
3131

32-
## 4. 서버 측 Host 생성
32+
```bash
33+
nc -vz <서버> 10051 # succeeded 나오면 OK
34+
```
3335

34-
Zabbix Web에서 아래 순서로 등록합니다.
36+
---
3537

36-
1. `Data collection``Hosts`
37-
2. `Create host`
38-
3. 아래 값 입력
38+
## 1. 대상 서버에 Zabbix Agent 2 설치
3939

40-
- Host name: Agent 설정의 `Hostname`과 동일값
41-
- Templates:
42-
- Windows: `Windows by Zabbix agent active`
43-
- Linux: `Linux by Zabbix agent active`
44-
- macOS: 운영 환경에 맞는 active 템플릿 또는 범용 agent 템플릿
45-
- Host groups: 예) `Endpoints`
46-
- Interfaces: Active 전용만 사용할 경우 필수는 아니지만 관리 편의상 추가 가능
40+
### Ubuntu / Debian
4741

48-
## 5. Agent 설정 예시
42+
```bash
43+
# Zabbix 7.4 리포지토리 (배포판 버전에 맞게: ubuntu24.04, debian12 등)
44+
wget https://repo.zabbix.com/zabbix/7.4/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.4+ubuntu24.04_all.deb
45+
sudo dpkg -i zabbix-release_latest_7.4+ubuntu24.04_all.deb
46+
sudo apt update
47+
sudo apt install -y zabbix-agent2
48+
```
4949

50-
저장소 예시 파일:
50+
### RHEL / Rocky / AlmaLinux
5151

52-
- `config/zabbix_agent/zabbix_agent2.active.example.conf`
52+
```bash
53+
sudo rpm -Uvh https://repo.zabbix.com/zabbix/7.4/release/rhel/9/noarch/zabbix-release-latest-7.4.el9.noarch.rpm
54+
sudo dnf clean all
55+
sudo dnf install -y zabbix-agent2
56+
```
5357

54-
핵심 설정은 아래 4개입니다.
58+
### macOS (Homebrew — 테스트용)
5559

56-
- `Server=mori.rmstudio.co.kr`
57-
- `ServerActive=mori.rmstudio.co.kr:10051`
58-
- `Hostname=PC별_고유이름`
59-
- `HostMetadata=windows|linux|macos`
60+
```bash
61+
brew install zabbix
62+
# 설정 파일: $(brew --prefix)/etc/zabbix/zabbix_agent2.conf
63+
```
6064

61-
예시:
65+
---
6266

63-
```conf
64-
Server=mori.rmstudio.co.kr
65-
ServerActive=mori.rmstudio.co.kr:10051
66-
Hostname=SRANG-LAPTOP
67-
HostMetadata=windows
68-
```
67+
## 2. 에이전트 설정
6968

70-
## 6. OS별 적용 포인트
69+
설정 파일: `/etc/zabbix/zabbix_agent2.conf` (macOS는 brew 경로). 아래 3개만 맞추면 됩니다.
7170

72-
### Windows
71+
```ini
72+
# 수동 체크(Passive)용 — 서버 IP 허용
73+
Server=<MORI 서버 IP>
7374

74-
- Zabbix Agent 2 설치
75-
- 예시 설정 파일 내용을 `zabbix_agent2.conf`에 반영
76-
- 서비스 재시작
75+
# Active 체크용 — 에이전트가 접속할 서버:포트
76+
ServerActive=<MORI 서버 IP>:10051
7777

78-
권장 메타데이터:
78+
# 이 호스트의 고유 이름 — Zabbix Web에서 등록할 Host name 과 반드시 동일하게
79+
Hostname=my-web-01
80+
```
7981

80-
- `HostMetadata=windows`
82+
적용:
8183

82-
### Linux
84+
```bash
85+
sudo systemctl enable --now zabbix-agent2
86+
sudo systemctl restart zabbix-agent2
87+
sudo systemctl status zabbix-agent2 # active(running) 확인
88+
# 로그: /var/log/zabbix/zabbix_agent2.log
89+
```
8390

84-
- 패키지로 Zabbix Agent 2 설치
85-
- `/etc/zabbix/zabbix_agent2.conf` 수정
86-
- 서비스 재시작
91+
---
8792

88-
권장 메타데이터:
93+
## 3. Zabbix Web에서 Host 등록
8994

90-
- `HostMetadata=linux`
95+
Zabbix Web(`:18081`, Admin/zabbix) 접속 후:
9196

92-
### macOS
97+
1. **Data collection → Hosts → Create host**
98+
2. 값 입력:
99+
- **Host name**: 에이전트의 `Hostname`**동일값** (예: `my-web-01`)
100+
- **Templates**: `Linux by Zabbix agent` (또는 `Linux by Zabbix agent active`) 추가
101+
- **Host groups**: `Linux servers` 등 아무 그룹
102+
- **Interfaces → Add → Agent**: 대상 서버 IP / 포트 `10050`
103+
- (Active만 쓸 경우 인터페이스 IP는 형식상 넣어두면 됩니다)
104+
3. **Add** 저장
93105

94-
- Zabbix Agent 2 설치
95-
- 설정 파일에 Active 항목 반영
96-
- LaunchAgent/서비스 재시작
106+
수 분 뒤 **Monitoring → Latest data**에서 CPU/메모리/디스크 값이 들어오면 성공입니다.
97107

98-
권장 메타데이터:
108+
> 💡 **CLI로 등록**하고 싶으면 `host.create` + `templateid` API를 쓸 수 있습니다. 데모용 문제 발생은 `./scripts/mori-zabbix-demo-problem.sh` 참고.
99109
100-
- `HostMetadata=macos`
110+
---
101111

102-
## 7. 연결 확인 방법
112+
## 4. 문제(problem) 발생 → MORI로 흐르는지 확인
103113

104-
Zabbix Web에서 아래를 확인합니다.
114+
실제 트리거가 걸리는 상황(디스크 사용률 초과, 서비스 다운 등)을 만들거나,
115+
`Linux by Zabbix agent` 템플릿의 기본 트리거가 발화하면 **Monitoring → Problems**에 문제가 뜹니다.
105116

106-
- `Monitoring``Hosts`
107-
- Host 상태가 활성으로 보이는지 확인
108-
- `Latest data`에서 CPU/Memory/Disk 항목 수집 확인
117+
- **mori-worker**가 30초 주기로 `problem.get`을 폴링해 정규화 → PostgreSQL `alerts` 적재.
118+
- MORI `/ui`**🚨 Alert Triage** 탭에 `source=zabbix`로 표시됩니다(각 알림에 `Zabbix ↗` 딥링크).
119+
- 확인용:
109120

110-
처음 데이터 반영까지는 수 분 정도 걸릴 수 있습니다.
121+
```bash
122+
# MORI가 방금 폴링했는지 (source freshness)
123+
docker exec -it mori-soc-soc-postgres-1 psql -U mori -d mori_soc \
124+
-c "SELECT source,status,last_success_at FROM source_syncs WHERE source='zabbix';"
111125

112-
## 8. 추천 PoC 항목
126+
# 적재된 zabbix alert
127+
docker exec -it mori-soc-soc-postgres-1 psql -U mori -d mori_soc \
128+
-c "SELECT alert_id,severity,rule_name,resolved_at FROM alerts WHERE source='zabbix' ORDER BY observed_at DESC LIMIT 5;"
129+
```
113130

114-
처음에는 아래 항목만 확인해도 충분합니다.
131+
Zabbix에서 문제가 **해소(resolve)** 되면(복구 이벤트 발생) MORI alert의 `resolved_at`이 채워지고
132+
Triage에 "✓ 소스 해소" 뱃지가 표시됩니다.
115133

116-
- CPU utilization
117-
- Memory utilization
118-
- Disk usage
119-
- Network interface status
120-
- Agent availability
134+
---
121135

122-
## 9. 트러블슈팅
136+
## 5. 자주 겪는 문제
123137

124-
### 데이터가 안 들어올 때
138+
| 증상 | 원인 / 해결 |
139+
|---|---|
140+
| Latest data에 값이 안 옴 | `Hostname`(에이전트) ≠ Host name(Web) 불일치 / 방화벽에서 10051 outbound 막힘 |
141+
| Web에서 host가 빨간 ZBX | Passive 인터페이스 IP 오류 — Active만 쓰면 무시 가능, 또는 IP 교정 |
142+
| MORI Triage에 안 뜸 | Problems에 실제 problem이 있는지 확인 → `source_syncs` last_success 갱신 확인 → `mori-worker` 로그 확인 |
143+
| `mori-worker` 로그에 Zabbix 인증 오류 | `.env``MORI_ZABBIX_USER/PASSWORD` 확인 (기본 Admin/zabbix). 7.x는 반복 로그인 일시 차단 있음 |
125144

126-
- `Hostname`이 Zabbix Host 이름과 정확히 같은지 확인
127-
- `ServerActive=mori.rmstudio.co.kr:10051`로 설정했는지 확인
128-
- 단말 방화벽/사내망에서 outbound `10051/tcp` 차단이 없는지 확인
129-
- Active 템플릿을 연결했는지 확인
145+
---
130146

131-
### 로그인은 되는데 Host가 회색일 때
147+
## 6. 참고
132148

133-
- Host 템플릿이 맞지 않거나
134-
- Agent 서비스가 아직 재시작되지 않았거나
135-
- Active check 대상 호스트명이 일치하지 않는 경우가 많습니다.
149+
- MORI는 Zabbix를 **read-only**로 폴링만 합니다(에이전트 설치·Zabbix 설정 변경은 이 문서대로 사용자가 수행). MORI가 Zabbix 구성을 바꾸지 않습니다.
150+
- 데모 시나리오(실제 서버 없이 problem 발생)는 `./scripts/mori-zabbix-demo-problem.sh` 로 재현할 수 있습니다.
151+
- 배포 자동화(GitHub Actions)용 SSH 설정은 [DEPLOY_SSH_SETUP.md](./DEPLOY_SSH_SETUP.md) 참고.

0 commit comments

Comments
 (0)