Skip to content

Commit 8e4959c

Browse files
committed
init
1 parent ca1de53 commit 8e4959c

16 files changed

Lines changed: 818 additions & 0 deletions

File tree

.env.example

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
PUBLIC_DOMAIN=mori.rmstudio.co.kr
2+
PUBLIC_PORT=37854
3+
PUBLIC_URL=http://mori.rmstudio.co.kr:37854
4+
TIMEZONE=Asia/Seoul
5+
6+
GRAFANA_ADMIN_USER=admin
7+
GRAFANA_ADMIN_PASSWORD=change_this_grafana_password
8+
9+
ZABBIX_DB_NAME=zabbix
10+
ZABBIX_DB_USER=zabbix
11+
ZABBIX_DB_PASSWORD=change_this_zabbix_password
12+
13+
FLEET_DB_ROOT_PASSWORD=change_this_mysql_root_password
14+
FLEET_DB_NAME=fleet
15+
FLEET_DB_USER=fleet
16+
FLEET_DB_PASSWORD=change_this_fleet_password
17+
FLEET_SERVER_PRIVATE_KEY=generate_with_openssl_rand_base64_32
18+
19+
ZABBIX_WEB_PORT=8080
20+
FLEET_PORT=1337
21+
WAZUH_DASHBOARD_PORT=8443

.github/workflows/deploy.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: deploy-mori-soc
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
env:
12+
DEPLOY_PATH: /backup/rmstudio/mori
13+
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
14+
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
15+
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Start SSH agent
21+
uses: webfactory/ssh-agent@v0.9.0
22+
with:
23+
ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }}
24+
25+
- name: Add SSH known hosts
26+
run: |
27+
mkdir -p ~/.ssh
28+
if [ -n "${{ secrets.DEPLOY_KNOWN_HOSTS }}" ]; then
29+
printf '%s\n' "${{ secrets.DEPLOY_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
30+
else
31+
ssh-keyscan -p "$DEPLOY_PORT" "$DEPLOY_HOST" >> ~/.ssh/known_hosts
32+
fi
33+
34+
- name: Ensure remote path exists
35+
run: ssh -p "$DEPLOY_PORT" "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p '$DEPLOY_PATH'"
36+
37+
- name: Sync repository
38+
run: |
39+
rsync -az --delete \
40+
--exclude '.git/' \
41+
--exclude '.env' \
42+
--exclude 'certs/' \
43+
--exclude 'reports/' \
44+
--exclude 'config/wazuh_indexer_ssl_certs/' \
45+
./ "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/"
46+
47+
- name: Upload deployment env
48+
env:
49+
DEPLOY_ENV_FILE: ${{ secrets.DEPLOY_ENV_FILE }}
50+
run: |
51+
printf '%s' "$DEPLOY_ENV_FILE" | \
52+
ssh -p "$DEPLOY_PORT" "$DEPLOY_USER@$DEPLOY_HOST" "cat > '$DEPLOY_PATH/.env'"
53+
54+
- name: Run remote deploy
55+
run: |
56+
ssh -p "$DEPLOY_PORT" "$DEPLOY_USER@$DEPLOY_HOST" <<EOF
57+
set -e
58+
cd "$DEPLOY_PATH"
59+
mkdir -p certs reports config/wazuh_indexer_ssl_certs
60+
if [ ! -f config/wazuh_indexer_ssl_certs/root-ca.pem ]; then
61+
docker compose -f generate-indexer-certs.yml run --rm generator
62+
fi
63+
docker compose pull
64+
docker compose up -d --remove-orphans
65+
docker compose ps
66+
EOF

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.env
2+
certs/
3+
reports/
4+
config/wazuh_indexer_ssl_certs/

README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# MORI SOC-lite
2+
3+
오픈소스 기반 **Security Visibility Platform (SOC-lite)** 배포 스캐폴드입니다.
4+
5+
이 저장소는 중소 규모 조직(SME)을 위한 보안 가시성 플랫폼을 `docker compose` 기반으로 구성하며,
6+
다음 영역을 한 번에 묶어 운영할 수 있도록 설계했습니다.
7+
8+
- Infrastructure Monitoring: Zabbix
9+
- Log Centralization: Loki + Fluent Bit
10+
- Endpoint Security / Compliance: FleetDM
11+
- Security Event Detection: Wazuh
12+
- Visualization: Grafana
13+
- Vulnerability Scan: Trivy
14+
15+
## 1. 배포 목표
16+
17+
- 공개 주소: `http://mori.rmstudio.co.kr:37854`
18+
- 배포 경로: `/backup/rmstudio/mori`
19+
- 배포 방식: GitHub Actions + SSH
20+
- 실행 방식: `docker compose`
21+
22+
현재 외부 공개 진입점은 **Grafana**입니다.
23+
24+
## 2. 현재 구성된 서비스
25+
26+
### Public Entry
27+
- `Grafana` (`37854`)
28+
29+
### Internal Services
30+
- `Loki`: 중앙 로그 저장소
31+
- `Fluent Bit`: 호스트 로그 수집 및 Loki 전송
32+
- `Zabbix Server/Web`: 인프라 모니터링
33+
- `FleetDM`: 엔드포인트/취약점 관리
34+
- `Wazuh Manager/Indexer/Dashboard`: 보안 이벤트 탐지 및 분석
35+
- `Trivy`: 파일시스템 취약점 스캔(Profile 기반)
36+
37+
## 3. 포트 구성
38+
39+
- Public
40+
- `37854` → Grafana
41+
42+
- Internal / localhost only
43+
- `127.0.0.1:8080` → Zabbix Web
44+
- `127.0.0.1:1337` → FleetDM
45+
- `127.0.0.1:8443` → Wazuh Dashboard
46+
47+
- Service ports
48+
- `10051` → Zabbix Server
49+
- `1514` → Wazuh agent traffic
50+
- `1515` → Wazuh registration
51+
- `514/udp` → Syslog
52+
- `55000` → Wazuh API
53+
54+
## 4. 저장소에 추가된 파일
55+
56+
- `docker-compose.yml`: 전체 SOC-lite 스택 구성
57+
- `.env.example`: 배포용 환경변수 예시
58+
- `generate-indexer-certs.yml`: Wazuh 인증서 생성용 compose 파일
59+
- `.github/workflows/deploy.yml`: GitHub Actions 배포 워크플로우
60+
- `docs/DEPLOYMENT.md`: 서버 준비 및 운영 가이드
61+
- `config/*`: 각 서비스별 설정 파일
62+
63+
## 5. 배포 방식
64+
65+
GitHub Actions가 아래 순서로 동작하도록 구성했습니다.
66+
67+
1. 저장소 체크아웃
68+
2. 서버 경로 `/backup/rmstudio/mori` 생성 확인
69+
3. `rsync`로 코드 동기화
70+
4. GitHub Secret의 `.env` 내용을 서버에 업로드
71+
5. Wazuh 인증서가 없으면 최초 1회 생성
72+
6. `docker compose pull`
73+
7. `docker compose up -d --remove-orphans`
74+
75+
## 6. 필수 환경변수
76+
77+
`.env.example` 기준으로 실제 `.env`를 작성해야 합니다.
78+
79+
반드시 변경해야 하는 값:
80+
81+
- `GRAFANA_ADMIN_PASSWORD`
82+
- `ZABBIX_DB_PASSWORD`
83+
- `FLEET_DB_ROOT_PASSWORD`
84+
- `FLEET_DB_PASSWORD`
85+
- `FLEET_SERVER_PRIVATE_KEY`
86+
87+
예시:
88+
89+
- `cp .env.example .env`
90+
- `openssl rand -base64 32`
91+
92+
## 7. 서버 사전 준비
93+
94+
- Docker Engine 설치
95+
- Docker Compose Plugin 설치
96+
- 배포 디렉터리 생성: `/backup/rmstudio/mori`
97+
- Wazuh Indexer용 커널 파라미터 적용
98+
99+
필수 설정:
100+
101+
- `vm.max_map_count=262144`
102+
103+
## 8. GitHub Secrets
104+
105+
워크플로우 실행을 위해 아래 Secret이 필요합니다.
106+
107+
- `DEPLOY_HOST`
108+
- `DEPLOY_PORT`
109+
- `DEPLOY_USER`
110+
- `DEPLOY_SSH_KEY`
111+
- `DEPLOY_ENV_FILE`
112+
- `DEPLOY_KNOWN_HOSTS` (선택)
113+
114+
## 9. 현재 검증 상태
115+
116+
완료된 검증:
117+
118+
- `docker compose config` 통과
119+
- `docker compose -f generate-indexer-certs.yml config` 통과
120+
121+
또한 Wazuh Dashboard의 설정 마운트 충돌 가능성을 제거하도록 compose를 보정했습니다.
122+
123+
## 10. 운영 메모
124+
125+
- 현재 공개 서비스는 Grafana만 노출합니다.
126+
- Zabbix / FleetDM / Wazuh Dashboard는 localhost 바인딩으로 제한했습니다.
127+
- Wazuh 기본 예제 계정은 공식 예시 기본값(`SecretPassword`)을 사용 중입니다.
128+
- Wazuh 비밀번호를 변경하려면 `config/wazuh_indexer/internal_users.yml`의 해시와 관련 설정을 함께 수정해야 합니다.
129+
- Trivy 스캔은 필요 시 profile로 실행합니다.
130+
131+
## 11. 다음 작업 후보
132+
133+
- Grafana 대시보드/프로비저닝 고도화
134+
- HTTPS 리버스 프록시(Nginx/Caddy) 추가
135+
- Wazuh/Fleet 초기 운영 설정 보강
136+
- 실제 서버 기동 후 헬스체크 및 초기 로그인 검증
137+
138+
---
139+
140+
이 저장소는 **초기 배포 스캐폴드와 자동화 기반**까지 정리된 상태이며,
141+
실서비스 운영 전에는 서버 리소스, 인증서, 초기 계정/비밀번호 정책에 맞춘 추가 보완이 필요합니다.

config/certs.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
nodes:
2+
indexer:
3+
- name: wazuh.indexer
4+
ip: wazuh.indexer
5+
server:
6+
- name: wazuh.manager
7+
ip: wazuh.manager
8+
dashboard:
9+
- name: wazuh.dashboard
10+
ip: wazuh.dashboard

config/fluent-bit/fluent-bit.conf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[SERVICE]
2+
Flush 5
3+
Daemon Off
4+
Log_Level info
5+
6+
[INPUT]
7+
Name tail
8+
Path /host/var/log/*.log,/host/var/log/*/*.log
9+
Tag host.logs
10+
Refresh_Interval 10
11+
Read_from_Head true
12+
Skip_Long_Lines On
13+
14+
[OUTPUT]
15+
Name loki
16+
Match *
17+
Host loki
18+
Port 3100
19+
Labels job=fluent-bit,source=host
20+
Line_Format key_value
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: 1
2+
3+
datasources:
4+
- name: Loki
5+
type: loki
6+
access: proxy
7+
url: http://loki:3100
8+
isDefault: true
9+
editable: false

config/loki/config.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
auth_enabled: false
2+
3+
server:
4+
http_listen_port: 3100
5+
6+
common:
7+
path_prefix: /loki
8+
storage:
9+
filesystem:
10+
chunks_directory: /loki/chunks
11+
rules_directory: /loki/rules
12+
replication_factor: 1
13+
ring:
14+
kvstore:
15+
store: inmemory
16+
17+
schema_config:
18+
configs:
19+
- from: 2024-01-01
20+
store: tsdb
21+
object_store: filesystem
22+
schema: v13
23+
index:
24+
prefix: index_
25+
period: 24h
26+
27+
limits_config:
28+
allow_structured_metadata: false
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<ossec_config>
2+
<global>
3+
<jsonout_output>yes</jsonout_output>
4+
<alerts_log>yes</alerts_log>
5+
<email_notification>no</email_notification>
6+
<agents_disconnection_time>10m</agents_disconnection_time>
7+
</global>
8+
9+
<alerts>
10+
<log_alert_level>3</log_alert_level>
11+
<email_alert_level>12</email_alert_level>
12+
</alerts>
13+
14+
<remote>
15+
<connection>secure</connection>
16+
<port>1514</port>
17+
<protocol>tcp</protocol>
18+
</remote>
19+
20+
<auth>
21+
<disabled>no</disabled>
22+
<port>1515</port>
23+
<use_password>no</use_password>
24+
<ssl_verify_host>no</ssl_verify_host>
25+
<ssl_manager_cert>etc/sslmanager.cert</ssl_manager_cert>
26+
<ssl_manager_key>etc/sslmanager.key</ssl_manager_key>
27+
</auth>
28+
29+
<wodle name="syscollector">
30+
<disabled>no</disabled>
31+
<interval>1h</interval>
32+
<scan_on_start>yes</scan_on_start>
33+
<hardware>yes</hardware>
34+
<os>yes</os>
35+
<network>yes</network>
36+
<packages>yes</packages>
37+
<ports all="yes">yes</ports>
38+
<processes>yes</processes>
39+
</wodle>
40+
41+
<sca>
42+
<enabled>yes</enabled>
43+
<scan_on_start>yes</scan_on_start>
44+
<interval>12h</interval>
45+
</sca>
46+
47+
<vulnerability-detection>
48+
<enabled>yes</enabled>
49+
<index-status>yes</index-status>
50+
<feed-update-interval>60m</feed-update-interval>
51+
</vulnerability-detection>
52+
53+
<indexer>
54+
<enabled>yes</enabled>
55+
<hosts>
56+
<host>https://wazuh.indexer:9200</host>
57+
</hosts>
58+
<ssl>
59+
<certificate_authorities>
60+
<ca>/etc/ssl/root-ca.pem</ca>
61+
</certificate_authorities>
62+
<certificate>/etc/ssl/filebeat.pem</certificate>
63+
<key>/etc/ssl/filebeat.key</key>
64+
</ssl>
65+
</indexer>
66+
67+
<localfile>
68+
<log_format>command</log_format>
69+
<command>df -P</command>
70+
<frequency>360</frequency>
71+
</localfile>
72+
73+
<ruleset>
74+
<decoder_dir>ruleset/decoders</decoder_dir>
75+
<rule_dir>ruleset/rules</rule_dir>
76+
<decoder_dir>etc/decoders</decoder_dir>
77+
<rule_dir>etc/rules</rule_dir>
78+
</ruleset>
79+
</ossec_config>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
server.host: 0.0.0.0
2+
server.port: 5601
3+
server.ssl.enabled: true
4+
server.ssl.key: "/usr/share/wazuh-dashboard/certs/wazuh-dashboard-key.pem"
5+
server.ssl.certificate: "/usr/share/wazuh-dashboard/certs/wazuh-dashboard.pem"
6+
opensearch.hosts: https://wazuh.indexer:9200
7+
opensearch.ssl.verificationMode: certificate
8+
opensearch.ssl.certificateAuthorities: ["/usr/share/wazuh-dashboard/certs/root-ca.pem"]
9+
opensearch.requestHeadersWhitelist: ["securitytenant", "Authorization"]
10+
opensearch_security.multitenancy.enabled: false
11+
uiSettings.overrides.defaultRoute: /app/wz-home

0 commit comments

Comments
 (0)