docs: migrate infrastructure troubleshooting from robeing
This commit is contained in:
parent
715e134a64
commit
ef666e6fc0
@ -19,6 +19,22 @@
|
||||
- 실행 중 문제가 생기면 `worklog`가 아니라 `troubleshooting`으로 기록합니다.
|
||||
|
||||
## 현재 문서
|
||||
- [260307 gateway SSOT runtime/secrets 분리 적용 및 검증](./troubleshooting/260307_gateway_SSOT_runtime_secrets_분리_적용_및_검증.md)
|
||||
- [260307 NAS(192.168.0.101) SSOT 전환 및 CIFS 실마운트 복구](./troubleshooting/260307_NAS_192_168_0_101_SSOT_전환_및_CIFS_실마운트_복구.md)
|
||||
- [260307 Gitea LFS NAS 권한정렬 및 실업로드 검증](./troubleshooting/260307_Gitea_LFS_NAS_권한정렬_및_실업로드_검증.md)
|
||||
- [260307 51123 서버 성수 이전 네트워크 변경 운영기록](./troubleshooting/260307_51123_성수이전_네트워크변경_운영기록.md)
|
||||
- [260306 51123 Gitea LFS 권한 오류 502 복구](./troubleshooting/260306_51123_gitea_lfs_permission_denied_502_복구.md)
|
||||
- [260305 51124 다운 상태 및 복구 예정](./troubleshooting/260305_51124_다운_상태_및_복구예정.md)
|
||||
- [260305 23 임시배포 env.deploy SSOT 및 배포실패 근본원인 해결](./troubleshooting/260305_23임시배포_envdeploy_ssot_및_배포실패_근본원인_해결.md)
|
||||
- [260304 51123 임시복구 서비스 연속성 조치내역](./troubleshooting/260304_51123_임시복구_서비스연속성_조치내역.md)
|
||||
- [260303 51123 DB 5432 차단사고 복구 및 의존 포트 점검](./troubleshooting/260303_51123_DB5432_차단사고_복구_및_의존포트_점검.md)
|
||||
- [260303 51123 서버 UFW 외부 포트 차단 하드닝](./troubleshooting/260303_51123_ufw_외부포트_차단_하드닝.md)
|
||||
- [260303 23 서버 전달사항: gateway-rb8001 연결 점검 결과](./troubleshooting/260303_51123_gateway_rb8001_연결점검_23서버_전달사항.md)
|
||||
- [260226 51124 bot 계정 SSH 침해 대응 및 박멸 기록](./troubleshooting/260226_51124_bot_account_compromise_and_eradication.md)
|
||||
- [260226 51124 openclaw-gateway 상주 프로세스 정리](./troubleshooting/260226_51124_openclaw_gateway_상주프로세스_정리.md)
|
||||
- [260226 51123 SSH 브루트포스 차단 및 fail2ban 교정](./troubleshooting/260226_51123_SSH_브루트포스_차단_및_fail2ban_교정.md)
|
||||
- [260226 NAS(192.168.219.51) 접속불가 임시 백업 복구](./troubleshooting/260226_NAS_192_168_219_51_접속불가_임시백업복구.md)
|
||||
- [260217 starsandi DNS/nginx/SSL 분리 적용](./troubleshooting/260217_starsandi_dns_nginx_ssl_분리적용.md)
|
||||
- [51123 구 IP 하드코딩과 런타임 SSOT 불일치 이슈](./troubleshooting/260309_51123_구IP하드코딩_런타임SSOT불일치_이슈.md)
|
||||
- [24서버 우분투 터미널 불가, 네트워크 대역 오류, python3-apt 복구 기록](./troubleshooting/260309_24서버_우분투터미널불가_네트워크대역오류_python3apt복구.md)
|
||||
- [23서버 워크스페이스 인프라 구조정리 이슈](./troubleshooting/260307_23서버_워크스페이스_인프라_구조정리_이슈.md)
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
# 260217 starsandi DNS/nginx/SSL 분리 적용
|
||||
|
||||
## 배경
|
||||
- 목표: 51123 서버에서 `ro-being.com`과 `starsandi.com`을 충돌 없이 분리 운영.
|
||||
- 요구사항:
|
||||
- DNS: `A @ -> 124.55.18.179`, `CNAME www -> @`
|
||||
- nginx: `starsandi.com`, `www.starsandi.com` 전용 서버 블록 분리
|
||||
- HTTPS: certbot으로 인증서 발급 및 80 -> 443 적용
|
||||
- 경로: starsandi 앱은 현재 `basePath=/starsandi` 유지
|
||||
|
||||
## 원인 및 이슈
|
||||
- 초기 조회에서 `starsandi.com`이 Namecheap 주차 IP(`192.64.119.114`)로 응답되어 인증서 발급 타이밍 이슈 존재.
|
||||
- 권한 DNS(8.8.8.8, 1.1.1.1) 기준으로는 `124.55.18.179` 조회되어 전파 진행 중 상태 확인.
|
||||
|
||||
## 적용 내용
|
||||
|
||||
### 1) nginx 도메인 분리
|
||||
- 파일 추가: `/etc/nginx/sites-available/starsandi.conf`
|
||||
- 심볼릭 링크: `/etc/nginx/sites-enabled/starsandi.conf`
|
||||
- 핵심 설정:
|
||||
- `server_name starsandi.com www.starsandi.com;`
|
||||
- `location = / { return 301 /starsandi; }` (basePath 유지)
|
||||
- `location /starsandi { proxy_pass http://127.0.0.1:3010; ... }`
|
||||
|
||||
### 2) ro-being 경로 충돌 방지
|
||||
- 파일 수정: `/etc/nginx/sites-enabled/default`
|
||||
- 변경 내용:
|
||||
- `ro-being.com` 블록의 `/startsandi`, `/zari`, `/starsandi` 요청을 `https://starsandi.com...`으로 301 리다이렉트
|
||||
|
||||
### 3) SSL(certbot)
|
||||
- 실행 명령:
|
||||
- `sudo certbot --nginx -d starsandi.com -d www.starsandi.com --non-interactive --agree-tos -m admin@starsandi.com --redirect`
|
||||
- 결과:
|
||||
- 인증서 발급 성공
|
||||
- 경로: `/etc/letsencrypt/live/starsandi.com/fullchain.pem`
|
||||
- 만료일: `2026-05-18`
|
||||
- certbot이 nginx 설정에 443 블록 자동 반영
|
||||
|
||||
## 검증 결과
|
||||
- `sudo nginx -t` 성공
|
||||
- `sudo systemctl reload nginx` 성공
|
||||
- 로컬 강제 해석(`--resolve`) 검증:
|
||||
- `http://starsandi.com` -> `https://starsandi.com/` 301
|
||||
- `https://starsandi.com` -> `/starsandi` 301
|
||||
- `https://www.starsandi.com` -> `/starsandi` 301
|
||||
- `https://ro-being.com/starsandi` -> `https://starsandi.com/starsandi` 301
|
||||
|
||||
## 운영 메모
|
||||
- DNS 캐시/전파 구간에서는 일부 클라이언트가 Namecheap 응답(주차/포워딩)을 잠시 볼 수 있음.
|
||||
- 실제 서비스 판별은 `dig @8.8.8.8 starsandi.com A`, `dig @1.1.1.1 starsandi.com A`로 재확인.
|
||||
- 용어 표기는 서버 규칙에 따라 `robeing` 기준 유지.
|
||||
@ -0,0 +1,35 @@
|
||||
# 260226 51123 SSH 브루트포스 차단 및 fail2ban 교정
|
||||
|
||||
## 시간
|
||||
- 기준일: 2026-02-26
|
||||
|
||||
## 배경
|
||||
- 51123 SSH(포트 51123)로 무차별 대입 시도가 대량 유입됨
|
||||
- 집계 기준(당일): `Failed password 56,613`, `Invalid user 48,030`
|
||||
|
||||
## 조치
|
||||
1. UFW 수동 차단
|
||||
- 허용(관리자 예외): `112.146.113.214`, `220.85.143.128`
|
||||
- 차단(반복 실패 상위): `134.209.249.168`, `164.92.167.107`, `209.38.245.39`
|
||||
|
||||
2. fail2ban 설정 교정
|
||||
- 파일: `/etc/fail2ban/jail.d/ssh-custom.conf`
|
||||
- 핵심 변경:
|
||||
- `port = 51123` (기존 `ssh` 포트 기본값 의존 제거)
|
||||
- `ignoreip = 127.0.0.1/8 ::1 192.168.219.0/24 112.146.113.214 220.85.143.128`
|
||||
- `sshd`: `maxretry=5`, `findtime=600`, `bantime=86400`
|
||||
- `sshd-aggressive`: `maxretry=3`, `findtime=300`, `bantime=604800`
|
||||
|
||||
3. 서비스 반영
|
||||
- `systemctl restart fail2ban`
|
||||
- `fail2ban-client status`로 `sshd`, `sshd-aggressive` 정상 활성 확인
|
||||
|
||||
## 확인 결과
|
||||
- fail2ban 재시작 후 양쪽 jail에서 실시간 차단 동작 확인
|
||||
- 화이트리스트 IP는 수동 `unbanip` 실행으로 차단 예외 재확인
|
||||
- SSH 설정은 `Port 51123`, `PermitRootLogin no`, `PasswordAuthentication yes` 상태
|
||||
|
||||
## 후속 권장
|
||||
1. 가능하면 `PasswordAuthentication no`로 전환(키 기반만 허용)
|
||||
2. 비상 접속 계정 1개만 비밀번호 허용 + 소스 IP 제한
|
||||
3. 월 1회 `fail2ban`/`ufw` 룰 정리 및 화이트리스트 검증
|
||||
@ -0,0 +1,76 @@
|
||||
# 51124 bot 계정 SSH 침해 대응 및 박멸 기록
|
||||
|
||||
**날짜**: 2026-02-26
|
||||
**작성자**: admin
|
||||
**관련 파일**: `/var/log/auth.log*`, `/home/bot/.configrc7/*`, `/var/spool/cron/crontabs/bot`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 51124 서버에서 비정상 고메모리 프로세스(`kauditd0`) 발견
|
||||
- 실체 확인 결과 `/home/bot/.configrc7/a/kswapd00` 실행 파일로 위장 동작
|
||||
- `bot` crontab에 재실행 지속성(`*/30 * * * * /tmp/.kswapd00 || /home/bot/.configrc7/a/kswapd00`) 존재
|
||||
|
||||
## 침해 지표(IOC)
|
||||
- 프로세스/파일
|
||||
- `kauditd0`, `kswapd00`, `edac0`
|
||||
- `/home/bot/.configrc7/a/*`, `/home/bot/.configrc7/b/*`
|
||||
- `/tmp/.kswapd00`, `/tmp/.X28-unix/.rsync/c/aptitude`
|
||||
- SSH/지속성
|
||||
- `~/.ssh/authorized_keys`에 `mdrfckr` 주석의 `ssh-rsa` 키 주입 흔적
|
||||
- `chattr +/-ia`를 이용한 `.ssh` 잠금 시도
|
||||
- 네트워크
|
||||
- 공격 유입 성공 IP: `179.43.139.82`
|
||||
- 감염 프로세스 외부 연결 IP: `179.43.139.85:80`
|
||||
|
||||
## 로그 기반 사실 확인
|
||||
- `2026-02-18 18:46:05 KST`: `Accepted password for bot from 179.43.139.82`
|
||||
- `2026-02-18 18:54:06 KST`: `Accepted password for bot from 179.43.139.82`
|
||||
- `root` 계정 `Accepted` 로그인 성공 기록은 보관 로그 기준 미검출
|
||||
- `admin` 계정은 정상 운영 접속으로 보이는 `Accepted` 기록 다수 존재
|
||||
|
||||
## 원인 판정
|
||||
- SSH 비밀번호 인증 허용 상태(`passwordauthentication yes`)에서 `bot` 계정 비밀번호 기반 침입 성공
|
||||
- `bot` 계정이 `sudo`/`docker` 권한 보유(`sudo ALL`) 상태여서 감염 스크립트 설치 및 지속성 확보가 가능했던 구조
|
||||
|
||||
## 조치 내역
|
||||
1. 악성 프로세스 종료
|
||||
- `kauditd0/kswapd00/edac0` 관련 프로세스 킬
|
||||
2. 지속성 제거
|
||||
- `crontab -u bot -r`로 `bot` 사용자 크론 제거
|
||||
3. 악성 파일 제거
|
||||
- `/home/bot/.configrc7`, `/tmp/.kswapd00`, `/tmp/.X28-unix/.rsync` 삭제
|
||||
4. 백도어 키 제거
|
||||
- `/home/bot/.ssh/authorized_keys`의 `mdrfckr` 키 제거
|
||||
- 백업: `/home/bot/.ssh/authorized_keys.bak.20260226212628`
|
||||
5. 계정 비밀번호 교체
|
||||
- `2026-02-26` 기준 `admin`, `root`, `bot` 비밀번호 변경 완료
|
||||
|
||||
## 검증 결과
|
||||
- `kauditd0/kswapd00/edac0` 프로세스 미검출
|
||||
- `bot` crontab 미존재 확인
|
||||
- IOC 경로(`/home/bot/.configrc7`, `/tmp/.kswapd00`, `/tmp/.X28-unix/.rsync`) 미존재 확인
|
||||
- `mdrfckr` 키 미검출 확인
|
||||
- 서비스 영향 없음: `docker ps` 전체 `Up`, `curl http://localhost:8001/health` HTTP 200
|
||||
|
||||
## 남은 리스크
|
||||
- 보관 로그 한계로 과거 데이터 조회/유출 여부를 100% 확정할 수 없음
|
||||
- `bot` 계정으로 읽기 접근된 비밀값(API 키, 토큰, DB 접속정보)은 노출 가능성 배제 불가
|
||||
|
||||
## 후속 권고
|
||||
1. SSH 하드닝
|
||||
- `PasswordAuthentication no`
|
||||
- `AllowUsers admin` 등 접속 사용자 제한
|
||||
2. 계정 정리
|
||||
- `bot` 계정 업무 불필요 시 잠금(`usermod -L`) 또는 삭제
|
||||
- `sudo`/`docker` 최소 권한 재설계
|
||||
3. 비밀값 로테이션
|
||||
- `.env` 기반 토큰/Gitea 토큰/외부 API 키 전면 교체
|
||||
4. 모니터링 강화
|
||||
- `auth.log`의 `Accepted password` 이상 탐지 알림
|
||||
- 크론/시스템 서비스 신규 등록 이벤트 모니터링
|
||||
|
||||
## 교훈
|
||||
- 비밀번호 SSH 허용 + 고권한 사용자 조합은 자동화 봇넷 침해에 매우 취약함
|
||||
- 박멸은 `프로세스 종료`만으로 끝나지 않고 `크론/파일/SSH 키`까지 함께 제거해야 재감염을 막을 수 있음
|
||||
- 침해 대응 후에는 서비스 정상 여부(`docker ps`, healthcheck)와 보안 후속조치를 같은 작업 단위로 처리해야 함
|
||||
@ -0,0 +1,38 @@
|
||||
# 51124 openclaw-gateway 상주 프로세스 정리
|
||||
|
||||
**날짜**: 2026-02-26
|
||||
**작성자**: admin
|
||||
**관련 파일**: `/home/admin/.nvm/versions/node/v24.4.0/lib/node_modules/openclaw/package.json`, `/proc/1127450/*`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 메모리 상위 프로세스 점검 중 `openclaw-gateway`(PID 1127458) 발견
|
||||
- 51124 운영 대상 서비스 목록(AGENTS.md)에는 `openclaw`가 포함되지 않아 비관리 상주 프로세스로 판단
|
||||
- 장기 상주 상태로 메모리 점유 및 운영 혼선 가능성 존재
|
||||
|
||||
## 사실 확인
|
||||
- 시작 시각: `2026-02-05 09:33:48 KST` (`ps -o lstart` 기준)
|
||||
- 실행 주체: `admin` 계정 SSH 세션(`session-60400.scope`, `SSH_CLIENT=192.228.158.63`)
|
||||
- 실행 형태: systemd 서비스/크론 등록 없음, 수동 실행 후 orphan 상주
|
||||
- 프로세스 체인: `systemd(1) -> openclaw(PID 1127450) -> openclaw-gateway(PID 1127458)`
|
||||
- 패키지 정체: npm 글로벌 `openclaw@2026.2.2-3` (`description: WhatsApp gateway CLI ...`)
|
||||
|
||||
## 해결 방안
|
||||
1. 비관리 프로세스 종료
|
||||
- `pkill -f '^openclaw$'`
|
||||
- `pkill -f 'openclaw-gateway'`
|
||||
2. 잔여 프로세스/포트 검증
|
||||
- `ps`, `pgrep`, `ss -tlnp` 재확인으로 `openclaw` 관련 미검출 확인
|
||||
3. 리소스 재확인
|
||||
- 종료 전후 메모리 비교에서 `free/available` 증가, swap 사용량 감소 확인
|
||||
|
||||
## 검증 결과
|
||||
- `openclaw`, `openclaw-gateway` 프로세스 미검출
|
||||
- openclaw 관련 리슨 포트 미검출
|
||||
- 운영 필수 컨테이너(`rb8001`, `skill-*`, `robeing_monitor`) 영향 없음
|
||||
|
||||
## 교훈
|
||||
- 운영 대상 외 프로세스는 발견 즉시 실행 주체/시작 시각/자동실행 경로(systemd·cron)까지 함께 확인해야 함
|
||||
- 비관리 상주 프로세스는 종료 후 반드시 `ps/pgrep/ss` 3중 검증으로 잔존 여부를 확인해야 함
|
||||
- 운영 문서(DOCS)에 즉시 기록해 동일 유형 이슈 재발 시 판단 시간을 단축해야 함
|
||||
@ -0,0 +1,40 @@
|
||||
# 260226 NAS(192.168.219.51) 접속불가 임시 백업 복구
|
||||
|
||||
## 시간
|
||||
- 기준일: 2026-02-26
|
||||
- 발생 시각: 2026-02-26 20:4x KST
|
||||
- 임시 복구 완료: 2026-02-26 20:55 KST
|
||||
|
||||
## 증상
|
||||
- `51123`에서 `/mnt/nas` 접근 시 `Host is down` 발생
|
||||
- `192.168.219.51`에 `ping` 100% 손실
|
||||
- SMB(445) 접근 시 `No route to host`
|
||||
|
||||
## 원인 판정
|
||||
- `51123`/`51124` 양쪽에서 동일하게 `192.168.219.51` 불통 확인
|
||||
- 로컬 서버(51123) 네트워크 자체는 정상(`192.168.219.1`, `192.168.219.52` 통신 정상)
|
||||
- 판정: 서버 로컬 이슈가 아니라 NAS 전원/링크/스위치 구간 장애 가능성 높음
|
||||
|
||||
## 즉시 조치 (백업 공백 방지)
|
||||
1. 기존 `/mnt/nas` 마운트 해제
|
||||
2. 로컬 대체 경로 생성: `/mnt/hdd/nas-fallback/backup/{weekly,current,archives}`
|
||||
3. bind 마운트 적용: `/mnt/hdd/nas-fallback` -> `/mnt/nas`
|
||||
4. `weekly-backup.sh` 수동 실행으로 동작 검증
|
||||
|
||||
## 검증 결과
|
||||
- `/mnt/nas/backup/weekly/20260226` 생성 확인
|
||||
- `weekly-backup-20260226.log` 기준 백업 완료 크기: `30M`
|
||||
- 임시 상태에서 주간 백업 크론 경로(`/mnt/nas/backup/weekly`) 정상 유지
|
||||
|
||||
## 원복 절차 (NAS 복구 후)
|
||||
1. NAS(192.168.219.51) 통신 복구 확인 (`ping`, SMB 445)
|
||||
2. `sudo umount /mnt/nas`
|
||||
3. `sudo mount /mnt/nas` (fstab의 CIFS 원마운트 복귀)
|
||||
4. `/mnt/nas/backup` 실제 NAS 경로 접근 확인
|
||||
5. 임시 데이터(`/mnt/hdd/nas-fallback/backup`)를 NAS로 동기화 후 정리
|
||||
|
||||
## 참고
|
||||
- 기존 NAS 백업 체계 문서: `./250729_서버백업및로그관리체계구축.md`
|
||||
|
||||
## 후속 문서
|
||||
- 다음 단계: [260307_NAS_192_168_0_101_SSOT_전환_및_CIFS_실마운트_복구](./260307_NAS_192_168_0_101_SSOT_전환_및_CIFS_실마운트_복구.md)
|
||||
140
journey/troubleshooting/260303_51123_DB5432_차단사고_복구_및_의존포트_점검.md
Normal file
140
journey/troubleshooting/260303_51123_DB5432_차단사고_복구_및_의존포트_점검.md
Normal file
@ -0,0 +1,140 @@
|
||||
# 260303 51123 DB 5432 차단 사고 복구 및 의존 포트 점검
|
||||
|
||||
## 발생 일시
|
||||
- 장애 징후 시작: 2026-03-03 10:59 KST 전후
|
||||
- 원인 확인/복구: 2026-03-03 11:18~11:22 KST
|
||||
|
||||
## 문제 요약
|
||||
- 51124의 `skill-email`이 `192.168.219.45:5432` 연결 타임아웃으로 `ReadTimeout/500`을 반환.
|
||||
- 앱 로직 문제가 아니라 DB 접속 경로(포트 5432) 차단으로 인한 네트워크 레벨 장애.
|
||||
|
||||
## 직접 원인
|
||||
- 2026-03-03 오전 포트 하드닝 작업 중, UFW의 `5432/tcp` 외부 허용 규칙을 제거함.
|
||||
- 이때 51124(`192.168.219.52`)의 DB 직접 접근도 함께 차단됨.
|
||||
|
||||
## 사실 확인 (51123)
|
||||
1. PostgreSQL 리스닝: 정상
|
||||
- `ss -lntp` 결과: `0.0.0.0:5432`, `[::]:5432` LISTEN
|
||||
|
||||
2. PostgreSQL 설정: 원격 수신 가능
|
||||
- `postgresql.conf`: `listen_addresses='*'`, `port=5432`
|
||||
- `pg_hba.conf`: `host all all 0.0.0.0/0 scram-sha-256`
|
||||
|
||||
3. 방화벽: 장애 시점 기준 5432 허용 누락
|
||||
- `ufw status`에서 `5432` 허용 규칙이 없었음
|
||||
|
||||
## 조치
|
||||
- 최소권한 원칙으로 51124 IP만 5432 허용 재개:
|
||||
|
||||
```bash
|
||||
sudo ufw allow from 192.168.219.52 to any port 5432 proto tcp
|
||||
```
|
||||
|
||||
## 복구 검증
|
||||
1. 네트워크
|
||||
- 51124 -> 51123 포트 테스트:
|
||||
- `5432 open` (복구)
|
||||
- `3000 blocked`, `7474 blocked` (의도된 차단 유지)
|
||||
- `7687/9000/8100/8000/9200 open`
|
||||
|
||||
2. 컨테이너 내부
|
||||
- `skill-email` 컨테이너에서 `192.168.219.45:5432` TCP 연결 성공 (`tcp_ok`).
|
||||
- `skill-email` 컨테이너에서 `asyncpg`로 `select 1` 성공 (`asyncpg_ok 1`).
|
||||
|
||||
3. 서비스
|
||||
- `rb8001 /health` 정상(`200`).
|
||||
- 장애 핵심 경로였던 DB 접속 타임아웃은 네트워크 기준 해소.
|
||||
|
||||
## 분리 이슈 (별도 추적 필요)
|
||||
- 복구 후에도 `skill-email`의 `/messages`, `/messages/{id}` 일부 호출에서 `500`이 재현됨.
|
||||
- 근거:
|
||||
- DB 네트워크/인증/쿼리 기본 경로는 정상(`5432 open`, `asyncpg_ok 1`).
|
||||
- 그럼에도 `docker logs skill-email`에 `메시지 조회 중 오류`/`메시지 상세 조회 중 오류`가 지속.
|
||||
- 판단: 이번 5432 차단 사고와는 별개의 애플리케이션 레이어 오류 가능성이 높음.
|
||||
|
||||
## 분리 이슈 최종 판정 (2026-03-03 11:40 KST)
|
||||
- 위 "별도 앱 오류"로 분리했던 건 오판이었고, 실제로는 같은 5432 방화벽 영향이었다.
|
||||
- auth-server 컨테이너 DB 설정:
|
||||
- `DATABASE_URL=postgresql://robeings:robeings@host.docker.internal:5432/main_db`
|
||||
- 당시 UFW는 `5432`를 `192.168.219.52`만 허용해서, Docker 브리지(172.17/18/20/21 대역)에서 들어오는 auth-server DB 연결이 차단됨.
|
||||
- 결과적으로 `auth-server /auth/naverworks/passport/refresh`에서 `asyncpg.connect` `TimeoutError`가 발생했고, 이를 호출하던 `skill-email /messages*`가 연쇄 500.
|
||||
|
||||
### 추가 조치 (최종 복구)
|
||||
```bash
|
||||
sudo ufw allow from 172.16.0.0/12 to any port 5432 proto tcp
|
||||
```
|
||||
|
||||
### 최종 검증
|
||||
- `auth-server` 컨테이너 내부 DB 테스트: `auth_db_ok 1`
|
||||
- `http://127.0.0.1:9000/auth/naverworks/passport/refresh` 호출: 타임아웃 미발생(즉시 405 반환, 경로 응답 정상)
|
||||
- 51124 `skill-email` 호출:
|
||||
- `GET /messages?provider=naverworks&user_id=...&limit=3` -> `200 OK` (약 0.54s)
|
||||
|
||||
## 영향 범위 점검 결과 (51124 -> 51123 의존)
|
||||
다음 서비스/환경변수들이 `192.168.219.45:5432`를 사용 중:
|
||||
- `skill_email`
|
||||
- `skill-calendar`
|
||||
- `skill-news`
|
||||
- `skill-rag-file`
|
||||
- `rb8001`
|
||||
- `robeing-monitor`
|
||||
- 일부 `admin-dashboard` 구성(호스트 브리지 기반)
|
||||
|
||||
즉, 5432 차단 시 `skill-email`만이 아니라 위 서비스 전반에서 동일 장애 가능.
|
||||
|
||||
실행중 컨테이너 환경변수 점검 결과(2026-03-03 11:22 KST):
|
||||
- `rb8001`: `5432`, `7687`, `9000`, `8100` 의존
|
||||
- `skill-email`: `5432`, `9000` 의존
|
||||
- `skill-calendar`, `skill-slack`, `skill-rag-file`, `robeing_monitor`: `5432` 의존
|
||||
- `admin-dashboard-backend`: `172.17.0.1:5432` 의존(호스트 브리지)
|
||||
|
||||
## 재발 방지
|
||||
1. 포트 하드닝 전 의존성 체크 필수
|
||||
- 51124에서 `192.168.219.45:<port>` 참조를 `.env`/`compose`에서 선조회
|
||||
|
||||
2. 변경 절차 고정
|
||||
- `차단 전`: 의존 포트 목록 작성
|
||||
- `차단 직후`: 51124 원격 TCP 매트릭스 테스트
|
||||
- `완료 전`: 핵심 서비스 헬스 + 최근 오류로그 교차 확인
|
||||
|
||||
3. UFW 정책 원칙
|
||||
- 전면 허용(`Anywhere`) 대신 **의존 출발지 단위 최소 허용**으로 운영
|
||||
- `5432`는 최소 `192.168.219.52` + Docker 브리지 `172.16.0.0/12`를 포함해야 함
|
||||
|
||||
## 운영 보강: 서버별 마운트 아키텍처 분기
|
||||
NAS 관련 장애 점검은 51123/51124가 서로 다른 구조임을 전제로 수행해야 함.
|
||||
|
||||
- 51123: NAS/fallback 구조
|
||||
- `/mnt/nas`, `/mnt/hdd/nas-fallback`
|
||||
- `/etc/fstab`에 CIFS 항목(`//192.168.219.51/home /mnt/nas cifs ...`)
|
||||
- 51124: sshfs 연계 구조
|
||||
- `/mnt/51123data`, `/mnt/51123logs` (sshfs)
|
||||
- NAS CIFS/fallback 항목 없음
|
||||
|
||||
즉, 같은 NAS 불통이어도 "경로가 다르다"는 사실 자체는 장애가 아니라 서버별 아키텍처 차이임.
|
||||
|
||||
### NAS 실패 판정 규칙
|
||||
- `No route to host`와 `Timeout`은 둘 다 **연결 실패**로 동일 분류한다.
|
||||
- 에러 문구 차이는 시점/라우팅 상태에 따라 달라질 수 있으므로, 원인 분류 키로 사용하지 않는다.
|
||||
|
||||
### 완료 전 필수 게이트 (고정)
|
||||
1. 컨테이너 env 기반 의존성 스캔
|
||||
2. 51124 -> 51123 포트 매트릭스 (`5432/9000/8100/7687`)
|
||||
3. 핵심 API 실호출
|
||||
- `auth-server /auth/naverworks/passport/refresh`
|
||||
- `skill-email /messages*`
|
||||
4. 서버별 스토리지 분기 점검
|
||||
- 51123: NAS/fallback 경로
|
||||
- 51124: sshfs 경로
|
||||
|
||||
## 명령어 체크리스트
|
||||
```bash
|
||||
# 51123
|
||||
ss -lntp | grep 5432
|
||||
sudo ufw status numbered
|
||||
|
||||
# 51124에서 51123 연결 점검
|
||||
for p in 5432 3000 7474 7687 9000 8100 8000 9200; do
|
||||
timeout 2 bash -lc "cat < /dev/null > /dev/tcp/192.168.219.45/$p" && echo "$p open" || echo "$p blocked"
|
||||
done
|
||||
```
|
||||
@ -0,0 +1,56 @@
|
||||
# 23 서버 전달사항: 게이트웨이-8001 연결 점검 결과
|
||||
|
||||
**날짜**: 2026-03-03
|
||||
**작성자**: Codex
|
||||
**관련 파일**: `robeing-gateway/app/main.py`, `robeing-gateway/app/routers/slack.py`, `robeing-gateway/app/services/slack_proxy.py`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 요청사항: `51124 rb8001(8001) 배포본`이 `51123 robeing-gateway(8100)`를 통해 계획대로 전달되는지 확인.
|
||||
- 제약: `수정금지` 조건으로 코드/설정 변경 없이 확인만 수행.
|
||||
|
||||
## 확인한 사실
|
||||
- 게이트웨이 상태
|
||||
- `robeing-gateway` 컨테이너: `Up (healthy)`
|
||||
- `GET /healthz`: `200 {"status":"ok"}`
|
||||
- 게이트웨이 대상 설정
|
||||
- 컨테이너 환경변수: `ROBEING_DEFAULT_HOST=192.168.219.52`, `ROBEING_DEFAULT_PORT=8001`, `ROBEING_DEFAULT_ID=rb8001`
|
||||
- Run ID 전파 구현
|
||||
- `app/main.py`의 `/api/chat`에서 `X-Run-Id` 생성/전달 및 응답 `run_id` 기본값 주입 확인
|
||||
- `app/routers/slack.py` + `app/services/slack_proxy.py`에서 `X-Run-Id` 헤더 생성/전달 확인
|
||||
|
||||
## 핵심 점검 결과
|
||||
- 아키텍처 적합성(게이트웨이 단일 진입) 관점에서 **부분 불일치** 확인.
|
||||
- 근거:
|
||||
- 게이트웨이 범용 프록시는 `GET /api/{path:path}`만 존재 (`robeing-gateway/app/main.py`)
|
||||
- 계획 핵심 신규 API는 `POST` 중심 (`/api/self-improvement/*`, `/api/prompt-db/*`)
|
||||
- 실제 호출 결과:
|
||||
- `POST /api/self-improvement/runs` -> `405 Method Not Allowed (allow: GET)`
|
||||
- `POST /api/prompt-db/templates` -> `405 Method Not Allowed (allow: GET)`
|
||||
- `POST /api/self-improvement/policy-versions` -> `405 Method Not Allowed (allow: GET)`
|
||||
- 대조 확인:
|
||||
- 동일 경로를 rb8001(192.168.219.52:8001)로 직접 호출 시 `401 Unauthorized` 반환
|
||||
- 즉, rb8001 경로 자체는 존재하며 인증이 필요한 상태이고, 게이트웨이에서 먼저 `POST`가 차단되고 있음.
|
||||
|
||||
## 부가 관찰
|
||||
- Slack 검증 스크립트 실행 시 등록 사용자 이벤트가 `403` 발생.
|
||||
- 게이트웨이 로그에서 `No bot token found`, `No UUID found`가 함께 관찰됨.
|
||||
- 이 항목은 신규 self-improvement/prompt-db 경로 이슈와 별개로, Slack 사용자 매핑/토큰 데이터 상태 점검이 필요함.
|
||||
|
||||
## 24서버 전달사항 (rb8001 측 확인 결과)
|
||||
- `rb8001` 현재 배포 커밋: `54f74d70fc7f2e72368a1ca081d0f52a8dfcba2b` (`Up (healthy)` 확인).
|
||||
- 신규 경로 존재 확인:
|
||||
- `POST /api/self-improvement/policy-versions`
|
||||
- `POST /api/self-improvement/runs`
|
||||
- `POST /api/prompt-db/templates`, `.../versions`, `.../activate/...`, `POST /api/prompt-db/events`
|
||||
- DB 테이블 상태:
|
||||
- `robeing_self_improvement_runs`, `robeing_policy_versions`, `prompt_templates`, `prompt_versions`, `prompt_events`, `prompt_metrics_daily` 모두 생성됨.
|
||||
- API 직접 호출 시 `self_improvement_runs`/`prompt_events` 적재 정상 확인.
|
||||
- 유의사항:
|
||||
- 현재 `/api/message` 호출만으로는 `run_id` 기준 `self_improvement_runs`/`prompt_events` 자동 적재가 연결되지 않음.
|
||||
- 즉, 현재 기준 자기개선 루프 적재는 API 수동 호출 경로는 동작, 메시지 E2E 자동 폐루프는 미연결 상태.
|
||||
|
||||
## 교훈
|
||||
- `51123 gateway`가 단일 진입점인 구조에서는 신규 백엔드 API가 추가될 때 `HTTP method(특히 POST/PUT/DELETE)`까지 포함한 프록시 경로를 동시에 열어야 한다.
|
||||
- `직접 upstream 성공`과 `gateway 경유 성공`은 별도 검증 항목이므로 배포 완료 판단 전에 둘 다 확인해야 한다.
|
||||
70
journey/troubleshooting/260303_51123_ufw_외부포트_차단_하드닝.md
Normal file
70
journey/troubleshooting/260303_51123_ufw_외부포트_차단_하드닝.md
Normal file
@ -0,0 +1,70 @@
|
||||
# 260303 51123 서버 UFW 외부 포트 차단 하드닝
|
||||
|
||||
## 발생 일시
|
||||
2026-03-03 10:43~10:53 KST
|
||||
|
||||
## 배경
|
||||
외부 공개 포트 점검 중, 운영 원칙(외부는 80/443 + 관리 SSH만 공개) 대비 과다 노출이 확인됨.
|
||||
|
||||
## 확인된 원인
|
||||
- UFW에서 아래 포트가 `Anywhere`/`Anywhere (v6)`로 허용되어 있었음.
|
||||
- `5432/tcp` (PostgreSQL)
|
||||
- `3000/tcp` (Gitea 직접 포트)
|
||||
- `7474/tcp` (Neo4j HTTP)
|
||||
- 이 상태는 도메인/nginx 경유가 아닌 직접 포트 접근 경로를 열어두는 구성임.
|
||||
|
||||
## 조치 내용
|
||||
실서버(51123)에서 아래 명령으로 공개 허용 규칙 제거:
|
||||
|
||||
```bash
|
||||
sudo ufw --force delete allow 5432/tcp
|
||||
sudo ufw --force delete allow 3000/tcp
|
||||
sudo ufw --force delete allow 7474/tcp
|
||||
```
|
||||
|
||||
## 검증 결과
|
||||
조치 직후 실시간 검증:
|
||||
|
||||
- 도메인 응답
|
||||
- `https://ro-being.com` → `HTTP/2 200`
|
||||
- `https://git.ro-being.com` → `HTTP/2 200`
|
||||
- `https://auth.ro-being.com` → `HTTP/2 404` (기존 동작 동일)
|
||||
- 내부 서비스 헬스
|
||||
- `http://127.0.0.1:9000/health` → `200`
|
||||
- `http://127.0.0.1:8000/health` → `200`
|
||||
- UFW 규칙
|
||||
- `5432/3000/7474`의 `Anywhere`, `Anywhere (v6)` 허용 규칙 삭제 확인
|
||||
|
||||
## 영향도
|
||||
- 사용자 도메인 경유 트래픽 영향 없음
|
||||
- `git.ro-being.com` 기반 Gitea 사용 영향 없음
|
||||
- 직접 포트 우회 접근 경로만 차단됨
|
||||
|
||||
## 현재 공개 정책(2026-03-03 기준)
|
||||
- 외부 공개 유지: `80/tcp`, `443/tcp`, `51123/tcp(관리 SSH)`
|
||||
- 내부/제한 네트워크 허용: `7687`, `7474(172.17.0.0/16)`
|
||||
|
||||
## 후속 권장
|
||||
- Docker 퍼블리시 포트(`8000/8100/8200/9000/9200/9600`)의 외부 노출 축소(가능한 `127.0.0.1` 또는 내부 네트워크만 사용)
|
||||
- PostgreSQL `listen_addresses`, `pg_hba.conf`를 내부 대역 기반으로 추가 제한
|
||||
|
||||
## 사후 정정 (2026-03-03 11:40 KST)
|
||||
초기 차단 조치만으로는 충분하지 않았고, 실제 운영 의존 경로를 일부 누락한 상태였다.
|
||||
|
||||
- 누락된 의존 경로:
|
||||
- 51124 직접 경로: `192.168.219.52 -> 51123:5432`
|
||||
- Docker 브리지 경로: `172.16.0.0/12 -> 51123:5432` (예: auth-server `host.docker.internal:5432`)
|
||||
- 결과:
|
||||
- `auth-server /auth/naverworks/passport/refresh` 타임아웃
|
||||
- `skill-email /messages*` 연쇄 500
|
||||
|
||||
복구 시 최종 반영한 규칙:
|
||||
|
||||
```bash
|
||||
sudo ufw allow from 192.168.219.52 to any port 5432 proto tcp
|
||||
sudo ufw allow from 172.16.0.0/12 to any port 5432 proto tcp
|
||||
```
|
||||
|
||||
최종 정책(정정):
|
||||
- "5432는 무조건 전체 차단"이 아니라, **실제 의존 출발지 단위 최소 허용**이 원칙.
|
||||
- 하드닝 변경 시 반드시 컨테이너 env 기반 의존성 스캔 + 변경 직후 연계 API 실호출을 완료해야 한다.
|
||||
116
journey/troubleshooting/260304_51123_임시복구_서비스연속성_조치내역.md
Normal file
116
journey/troubleshooting/260304_51123_임시복구_서비스연속성_조치내역.md
Normal file
@ -0,0 +1,116 @@
|
||||
# 260304 51123 임시복구 서비스 연속성 조치내역
|
||||
|
||||
## 1. 목적
|
||||
- 51124 서버 장애 상황에서 51123 단독으로 robeing 핵심 서비스 연속성을 임시 복구한다.
|
||||
- 2026-03-04 기준, 내일(2026-03-05) 오전 9시~10시 일정/이메일 경로 중단을 방지한다.
|
||||
|
||||
## 2. 장애 징후 및 운영 영향
|
||||
- `/api/message` 응답이 3초 제한 내 타임아웃(`HTTP:000`, `curl (28)`)으로 실패.
|
||||
- 게이트웨이 경유 일부 경로에서 422/500이 혼재되어 호출 신뢰도가 저하.
|
||||
- PostgreSQL 연결 슬롯 고갈(Idle 세션 누적)로 신규 작업 지연.
|
||||
- 51124 불가 상태로 기존 이중서버 가정(23 인프라 + 24 실행)이 깨짐.
|
||||
|
||||
## 3. 확인된 근본 원인
|
||||
1. Docker 브리지 대역(`172.21.0.0/16`)에서 호스트 포트(8001, 9024, 8512) 접근이 방화벽에 막혀 내부 연계가 단절됨.
|
||||
2. PostgreSQL Idle 세션 누적으로 커넥션 풀 여유가 줄어 응답 지연이 증폭됨.
|
||||
3. rb8001 런타임에서 고비용 경로(의도/검색 그래프 포함)가 활성화된 상태로 느린 경로가 잦게 호출됨.
|
||||
4. gateway 환경변수 일부가 운영 실IP 기준과 어긋나 헬스/검증 경로가 불안정했음.
|
||||
|
||||
## 4. 실제 조치 내역(51123)
|
||||
### 4.1 네트워크/방화벽
|
||||
- UFW allow 규칙 추가:
|
||||
- `from 172.21.0.0/16 to any port 8001 proto tcp`
|
||||
- `from 172.21.0.0/16 to any port 9024 proto tcp`
|
||||
- `from 172.21.0.0/16 to any port 8512 proto tcp`
|
||||
|
||||
### 4.2 데이터베이스
|
||||
- Idle 커넥션 92건 정리(`pg_terminate_backend`)로 슬롯 회복.
|
||||
- 즉시 재접속 정상화 확인.
|
||||
|
||||
### 4.3 rb8001 성능 안전모드(임시)
|
||||
- `/home/admin/rb8001/.env` 오버라이드 적용:
|
||||
- `INTENT_ENGINE=v1`
|
||||
- `INTENT_USE_LANGGRAPH=false`
|
||||
- `INTENT_USE_COT=false`
|
||||
- `WEB_SEARCH_USE_GRAPH=false`
|
||||
- 적용 방식: `docker compose down && docker compose up -d --build`
|
||||
|
||||
### 4.4 gateway 운영값 정합화
|
||||
- `/home/admin/robeing-gateway/.env` 수정:
|
||||
- `ROBEING_DEFAULT_HOST=192.168.219.45`
|
||||
- `MONITOR_URL="http://192.168.219.45:9024"`
|
||||
- 적용 방식: `docker compose down && docker compose up -d --build`
|
||||
|
||||
## 5. 검증 결과(2026-03-04)
|
||||
1. 컨테이너 상태
|
||||
- `robeing-gateway(8100)`, `rb8001(8001)`, `robeing_monitor(9024)`, `skill-calendar(8512)`, `skill-email(8501)` running 확인.
|
||||
|
||||
2. 헬스/응답
|
||||
- gateway `/healthz` 200.
|
||||
- gateway `/api/message` 정상 응답 복구(측정 약 0.5~1.7초 구간).
|
||||
|
||||
3. 핵심 기능
|
||||
- 일정성 문구 포함 메시지 요청 시 응답 정상.
|
||||
- `self-improvement`, `prompt-db`는 유효 스키마 요청에서 성공, 비유효 payload는 기대대로 422/500.
|
||||
|
||||
4. 이메일 경로(내일 9~10시 핵심)
|
||||
- `skill-email` `/health` 200.
|
||||
- rb8001 컨테이너 -> skill-email 내부 호출 200.
|
||||
- NaverWorks 메일 리스트 API(실 UUID `3550cef6-63e1-4ceb-8802-a25c9d1c6917`) 200, 목록 수신 확인.
|
||||
|
||||
5. 스케줄 DB
|
||||
- `scheduled_jobs` 활성 항목 확인:
|
||||
- `naverworks_daily`: `0 9 * * mon-fri`
|
||||
- `coldmail_daily`: `5 9 * * mon-fri`
|
||||
- `daily_headlines`: `10 9 * * mon-fri`
|
||||
- `companyx_news`: `0 10 * * mon-fri`
|
||||
|
||||
## 6. 잔여 리스크 및 운영 주의
|
||||
- `skill-embedding(8515)` 미기동 상태는 지속. rb8001 로그에 임베딩 연결 에러가 간헐적으로 남을 수 있음.
|
||||
- 현재 복구는 "핵심 연속성 확보" 기준의 임시 안정화이며, 51124 복구 후 원래 분리구조로 되돌리는 재배치가 필요.
|
||||
- 스케줄 실행 직전/직후(2026-03-05 08:55~10:10) 구간 모니터링을 강화해야 함.
|
||||
|
||||
## 7. 24 서버 인계 메모
|
||||
- 51124 복구 후 우선순위:
|
||||
1. rb8001/skill/chromadb 원복 배치
|
||||
2. gateway 대상 upstream 재점검
|
||||
3. 임시 성능 플래그(`INTENT_USE_LANGGRAPH=false` 등) 단계적 해제 여부 성능 측정 후 결정
|
||||
- 본 문서는 51123 임시복구 기준 운영 기록이며, 24 원복 시 별도 후속 문서로 분리 기록 권장.
|
||||
|
||||
## 8. 추가 복구/배포 안전화 기록 (2026-03-04 03:00~03:30 KST)
|
||||
### 8.1 스킬 복구 상태(51123)
|
||||
- 실행 확인:
|
||||
- `robeing-skill-news` (`8505`) healthy
|
||||
- `skill-slack` (`8502`) healthy
|
||||
- `skill-rag-file` (`8508`) healthy
|
||||
- `skill-embedding` (`8515`) healthy
|
||||
- 헬스 응답 확인:
|
||||
- `GET http://192.168.219.45:8505/health` -> `{"status":"healthy"}`
|
||||
- `GET http://192.168.219.45:8502/health` -> healthy 응답
|
||||
- `GET http://192.168.219.45:8508/healthz` -> healthy 응답
|
||||
- `GET http://192.168.219.45:8515/healthz` -> `{"status":"ok"}`
|
||||
|
||||
### 8.2 근본 원인과 조치(embedding)
|
||||
- 근본 원인:
|
||||
- `skill-embedding` 재시작 루프 원인은 `/models/onnx/ko-sroberta-multitask/model.onnx` 파일 부재.
|
||||
- 로그 근거: `FileNotFoundError: ONNX 모델 파일을 찾을 수 없습니다`.
|
||||
- 조치:
|
||||
- `jhgan/ko-sroberta-multitask`를 ONNX로 변환해 `model.onnx` 생성.
|
||||
- 생성 경로: `/home/admin/robeing/onnx_models/ko-sroberta-multitask/model.onnx` (약 423MB).
|
||||
- 이후 `skill-embedding` `docker compose down && up -d --build`로 정상화.
|
||||
|
||||
### 8.3 배포 안전화(23/24 경로 일반화) 및 푸시
|
||||
- `skill-rag-file`:
|
||||
- `DOCUMENT_MOUNT_ROOT`, `DOCUMENT_BASE_PATH` 기반으로 볼륨/경로를 서버별 `.env` 오버라이드 가능하게 일반화.
|
||||
- 반영 커밋: `ab3ac78` (`main` 푸시 완료).
|
||||
- `skill-embedding`:
|
||||
- `ONNX_MODELS_HOST_PATH` 기반으로 모델 마운트 경로 일반화.
|
||||
- 24 자동배포 기본값은 `/home/admin/ivada_project/onnx_models`로 고정.
|
||||
- 23 임시복구는 `.env` 오버라이드로 유지.
|
||||
- 반영 커밋: `5a0f357`, 추가 교정 `ede5896` (`main` 푸시 완료).
|
||||
|
||||
### 8.4 Gitea workflow 점검 결과
|
||||
- 점검 대상: `rb8001`, `skill-news`, `skill-slack`, `skill-email`, `skill-calendar`, `skill-rag-file`, `skill-embedding`, `robeing-monitor`의 `.gitea/workflows/*.yml`.
|
||||
- 결론:
|
||||
- 이번 이슈 기준(서버 경로 하드코딩)으로는 workflow YAML 추가 수정 없이 `.env`/compose 일반화로 대응 가능.
|
||||
- 별도 개선 후보: `skill-calendar` workflow의 `runs-on` 위치가 비표준 구조라 안정성 점검 필요(후속 과제 분리).
|
||||
@ -0,0 +1,42 @@
|
||||
# 260305 23임시배포 env.deploy SSOT 및 배포실패 근본원인 해결
|
||||
|
||||
**날짜**: 2026-03-05
|
||||
**작성자**: Codex
|
||||
**관련 파일**: `robeing/skill-rag-file/app/core/config.py`, `robeing/skill-rag-file/.gitea/workflows/deploy.yml`, `robeing/skill-embedding/config.py`, `robeing/robeing-monitor/.gitea/workflows/deploy.yml`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 51124 다운 상태에서 51123 임시운영 중, 일부 스킬 배포가 반복 실패했다.
|
||||
- `skill-rag-file`, `skill-embedding`은 컨테이너 기동 직후 `ValidationError`로 헬스체크 실패가 발생했다.
|
||||
- `robeing-monitor`는 배포 스크립트 단계에서 권한 오류로 중단됐다.
|
||||
|
||||
## 확인된 근본 원인
|
||||
1. `skill-rag-file`/`skill-embedding` 설정 모델이 `.env`의 추가 키를 허용하지 않아 런타임 시작이 실패했다.
|
||||
2. 워크플로우의 배포 경로가 서비스별 하드코딩 경로를 사용해 SSOT(`DEPLOY_PROJECT_DIR`)가 깨져 있었다.
|
||||
3. `robeing-monitor` 배포 스크립트의 `chmod 777 logs`가 실제 권한 정책과 충돌해 즉시 실패했다.
|
||||
|
||||
## 해결 방안
|
||||
1. 설정 파서 수정(원인 직접 수정)
|
||||
- `skill-rag-file/app/core/config.py`: `SettingsConfigDict(..., extra="ignore")` 적용.
|
||||
- `skill-embedding/config.py`: `SettingsConfigDict(..., extra="ignore")` 적용.
|
||||
|
||||
2. 배포 경로 SSOT 정리
|
||||
- `skill-rag-file/.gitea/workflows/deploy.yml`: `cd /home/admin/...` 하드코딩 제거, `DEPLOY_PROJECT_DIR` 사용으로 통일.
|
||||
- `robeing-monitor/.gitea/workflows/deploy.yml`: 하드코딩 경로 제거, `DEPLOY_PROJECT_DIR` 기반으로 통일.
|
||||
|
||||
3. 권한 충돌 제거
|
||||
- `robeing-monitor/.gitea/workflows/deploy.yml`: 실패 원인인 `chmod 777 logs` 제거.
|
||||
|
||||
## 검증 결과
|
||||
- `skill-embedding` 최신 커밋 `f89109c` 실행: Gitea Actions `task 2106` `Job succeeded`.
|
||||
- `skill-rag-file` 최신 커밋 `ddc4693` 실행: Gitea Actions `task 2107` `Job succeeded`.
|
||||
- `robeing-monitor` 최신 커밋 `c62794c` 실행: Gitea Actions `task 2108` `Job succeeded`.
|
||||
|
||||
## 운영 결론
|
||||
- 51123 임시운영 기준 배포 실패 이슈는 해결 완료 상태다.
|
||||
- 51124 복구 시 코드 수정 없이 각 레포 `.env.deploy`의 배포 대상 값만 24 서버 값으로 전환하면 된다.
|
||||
|
||||
## 교훈
|
||||
- 배포 실패는 폴백 추가보다 실패 지점의 단일 원인(설정/권한/경로)을 직접 수정해야 재발이 줄어든다.
|
||||
- 배포 경로는 서비스별 하드코딩이 아니라 `DEPLOY_PROJECT_DIR` 단일 기준으로 유지해야 운영 전환(23↔24)이 단순해진다.
|
||||
9
journey/troubleshooting/260305_51124_다운_상태_및_복구예정.md
Normal file
9
journey/troubleshooting/260305_51124_다운_상태_및_복구예정.md
Normal file
@ -0,0 +1,9 @@
|
||||
# 260305 51124 다운 상태 및 복구 예정
|
||||
|
||||
- 기준일: 2026-03-05
|
||||
- 대상 서버: 51124 (192.168.219.52)
|
||||
- 현재 상태: 다운(미가동)
|
||||
- 복구 계획일: 2026-03-06
|
||||
- 임시 운영 상태: 51123에서 robeing 임시 가동 중 (rb8001, skill 계열)
|
||||
- 원래 실행 위치: 51124 (robeing/skill 실행 서버)
|
||||
- 비고: 본 상태/일정은 사용자 운영 지시 기준으로 기록함
|
||||
@ -0,0 +1,44 @@
|
||||
# 51123 Gitea LFS 권한 오류로 인한 git.ro-being.com 502 복구
|
||||
|
||||
tags: [gitea, lfs, nas, recovery]
|
||||
|
||||
**날짜**: 2026-03-06
|
||||
**작성자**: admin
|
||||
**관련 파일**: `/etc/gitea/app.ini`, `/etc/nginx/sites-enabled/default`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- 2026-03-06 19:04 KST 전후 `https://git.ro-being.com/` 접속 시 `HTTP/2 502` 발생.
|
||||
- nginx는 `git.ro-being.com`을 `http://localhost:3000/`으로 프록시 중이었고, upstream인 gitea가 비정상 상태였음.
|
||||
|
||||
## 원인 확인
|
||||
1. 서비스 상태
|
||||
- `systemctl status gitea`에서 `failed (Result: exit-code)` 확인.
|
||||
|
||||
2. gitea 로그
|
||||
- `journalctl -u gitea`에서 아래 치명 오류 반복 확인:
|
||||
- `storage.Init failed: mkdir /mnt/nas/gitea-lfs: permission denied`
|
||||
- 19:04:28~19:04:31 KST 사이 재시작 반복 후 `Failed to start Gitea` 상태 진입.
|
||||
|
||||
3. 설정 경로
|
||||
- `/etc/gitea/app.ini`에서 LFS 저장 경로가 `/mnt/nas/gitea-lfs`로 설정됨.
|
||||
|
||||
## 복구 상태 확인
|
||||
- 2026-03-06 19:21:08 KST: `Started Gitea` 로그 확인.
|
||||
- 현재 `gitea.service`는 `active (running)` 상태.
|
||||
- 외부 검증: `curl -I https://git.ro-being.com/` 결과 `HTTP/2 200`.
|
||||
|
||||
## 추가 관찰 사항
|
||||
- 현재 시점 확인 결과:
|
||||
- `/mnt/nas`는 `findmnt /mnt/nas` 기준 `not-mounted`
|
||||
- 디렉터리 권한은 `/mnt/nas`(root:root), `/mnt/nas/gitea-lfs`(git:git) 상태
|
||||
- 즉, gitea는 현재 경로 접근은 가능하지만 NAS 마운트 상태와 실제 저장 위치 일치 여부는 별도 운영 점검이 필요함.
|
||||
|
||||
## 교훈
|
||||
- Gitea LFS가 NAS 경로를 사용하면, 서비스 기동 전 `마운트 상태 + 대상 디렉터리 소유권`이 동시에 만족되어야 함.
|
||||
- `502`만 보고 nginx 문제로 단정하면 오판 가능성이 높고, 반드시 `nginx(upstream) + systemd(gitea) + journal`을 같은 시각대로 교차 확인해야 함.
|
||||
- 스토리지 경로가 마운트 의존일 때는 마운트 해제/권한 변동 감시를 운영 체크리스트에 포함해야 함.
|
||||
|
||||
## 후속 문서
|
||||
- 다음 단계: [260307_Gitea_LFS_NAS_권한정렬_및_실업로드_검증](./260307_Gitea_LFS_NAS_권한정렬_및_실업로드_검증.md)
|
||||
18
journey/troubleshooting/260307_51123_성수이전_네트워크변경_운영기록.md
Normal file
18
journey/troubleshooting/260307_51123_성수이전_네트워크변경_운영기록.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 260307 51123 서버 성수 이전 네트워크 변경 운영기록
|
||||
|
||||
## 1. 배경
|
||||
- 51123 서버 운영 위치가 서울 양재에서 성수로 이전됨.
|
||||
- 이전 과정에서 공인 IP, 공유기, 내부 사설 IP 대역이 변경됨.
|
||||
- DNS 설정은 완료했고, 내부 사설 IP 정리 작업을 진행 중임.
|
||||
|
||||
## 2. 현재 기준 주소(운영 사실)
|
||||
- 51123 임시 운용 서버 내부 사설 IP: `192.168.0.100`
|
||||
- NAS 내부 사설 IP: `192.168.0.101`
|
||||
|
||||
## 3. 운영 반영 메모
|
||||
- 기존 `192.168.219.x` 기준 문서/환경변수/프록시/헬스체크 경로는 순차적으로 `192.168.0.x` 기준으로 정리 필요.
|
||||
- gateway 및 연계 서비스의 upstream 대상 주소는 실제 바인딩/노출 포트와 함께 재검증 필요.
|
||||
- NAS 마운트/백업 경로는 `192.168.0.101` 기준으로 재점검 필요.
|
||||
|
||||
## 4. 기록 출처
|
||||
- 2026-03-07 사용자 전달 사실 기반 운영 기록.
|
||||
@ -0,0 +1,73 @@
|
||||
# 260307 Gitea LFS NAS 권한정렬 및 실업로드 검증
|
||||
|
||||
tags: [gitea, lfs, nas, cifs, ssot]
|
||||
|
||||
**날짜**: 2026-03-07
|
||||
**작성자**: admin
|
||||
**관련 파일**: `/etc/gitea/app.ini`, `/usr/local/bin/mount-nas-ssot.sh`, `/etc/systemd/system/mount-nas-ssot.service`, `/home/admin/infra-config/runtime.env`, `/home/admin/infra-config/secrets.env`
|
||||
|
||||
---
|
||||
|
||||
## 문제 상황
|
||||
- Gitea는 기동 중이었고 `git.ro-being.com` 일반 Git push/pull도 정상 동작했다.
|
||||
- 하지만 실제 `git lfs push` 검증에서는 `500 Internal Server Error`로 실패했다.
|
||||
- 즉 "LFS 경로가 설정돼 있다"와 "실제 대용량 파일 업로드가 된다"가 분리된 상태였다.
|
||||
|
||||
## 검증으로 확인한 사실
|
||||
1. 일반 Git 경로는 정상
|
||||
- `git push`, `git pull`은 정상
|
||||
|
||||
2. LFS 경로는 비정상
|
||||
- 실제 `git lfs` 업로드 테스트에서 반복적으로 `500` 발생
|
||||
- `journalctl -u gitea` 기준 실패 시각(2026-03-07 09:35 KST) 로그:
|
||||
- `mkdir /mnt/nas/gitea-lfs/18: permission denied`
|
||||
|
||||
3. 근본 원인
|
||||
- `gitea.service`는 `git:git (uid=131 gid=138)`로 실행
|
||||
- NAS CIFS 마운트는 `uid=1001,gid=1000,file_mode=0755,dir_mode=0755` 기준
|
||||
- 결과적으로 `/mnt/nas/gitea-lfs`는 `admin:xusers` 소유처럼 보였고, `git` 사용자는 쓰기 불가
|
||||
|
||||
## 실제 조치
|
||||
### 1. 마운트 권한 정렬
|
||||
- `/usr/local/bin/mount-nas-ssot.sh`의 CIFS 옵션을 아래 기준으로 조정
|
||||
- `uid=1001`
|
||||
- `gid=1000`
|
||||
- `forceuid,forcegid`
|
||||
- `file_mode=0664`
|
||||
- `dir_mode=0775`
|
||||
|
||||
### 2. Gitea 실행 사용자 그룹 정렬
|
||||
- `git` 사용자를 `xusers` 그룹에 추가
|
||||
- 결과: `git` 사용자가 `/mnt/nas/gitea-lfs`에 그룹 쓰기 가능
|
||||
|
||||
### 3. 서비스 반영
|
||||
- NAS 재마운트 실행
|
||||
- `gitea.service` 재시작
|
||||
- `sudo -u git` 기준 직접 쓰기 테스트 성공
|
||||
|
||||
## 재검증 결과
|
||||
1. 권한
|
||||
- `id git` -> `groups=138(git),1000(xusers)`
|
||||
- `/mnt/nas/gitea-lfs` -> `drwxrwxr-x`
|
||||
|
||||
2. 실업로드 검증
|
||||
- `test-meta-skill` 저장소에 임시 브랜치 생성 후 1MB 바이너리 파일을 `git lfs`로 push
|
||||
- 재클론 후 `git lfs pull` 수행
|
||||
- 원본과 재다운로드 파일 SHA256 일치
|
||||
|
||||
3. NAS 저장 확인
|
||||
- 실제 생성 경로:
|
||||
- `/mnt/nas/gitea-lfs/4a/22/ae83cbb68dcdcddb9e053fdce9466e63463881c981597bb6c797ca4a0f7b`
|
||||
- 검증 시점 기준 LFS 파일 수:
|
||||
- before=0
|
||||
- after_push=1
|
||||
- after_pull=1
|
||||
|
||||
## 결론
|
||||
- 현재 Gitea LFS는 설정상 연결된 수준이 아니라, 실제로 NAS에 대용량 파일을 저장하는 상태까지 검증 완료됐다.
|
||||
- 이번 조치로 `git lfs push -> Gitea -> /mnt/nas/gitea-lfs` 경로가 실동작함을 확인했다.
|
||||
- 이후 동일 계열 문제 재발 시, `Gitea 상태`보다 먼저 `gitea 실행 사용자`와 `NAS 마운트 권한`을 함께 봐야 한다.
|
||||
|
||||
## 전후 관계 문서
|
||||
- 이전: [260306_51123_gitea_lfs_permission_denied_502_복구](./260306_51123_gitea_lfs_permission_denied_502_복구.md)
|
||||
- 관련: [260307_NAS_192_168_0_101_SSOT_전환_및_CIFS_실마운트_복구](./260307_NAS_192_168_0_101_SSOT_전환_및_CIFS_실마운트_복구.md)
|
||||
@ -0,0 +1,74 @@
|
||||
# 260307 NAS(192.168.0.101) SSOT 전환 및 CIFS 실마운트 복구
|
||||
|
||||
## 시간
|
||||
- 기준일: 2026-03-07
|
||||
- 작업 시각: 2026-03-07 오전
|
||||
|
||||
## 배경
|
||||
- 서버 이전 후 NAS 내부 사설 IP가 `192.168.219.51`에서 `192.168.0.101`로 변경되었다.
|
||||
- 51123은 임시운영 상태에서 `/mnt/nas`를 다시 실NAS로 연결해야 했고, 동시에 SSOT 원칙에 맞게 NAS 설정을 정리할 필요가 있었다.
|
||||
- 기존 `/mnt/nas`는 실제 마운트가 아니라 로컬 디렉터리처럼 남아 있었고, `weekly-backup.sh`가 기대하는 `/mnt/nas/backup/weekly`도 실NAS 기준으로는 정합성이 깨져 있었다.
|
||||
|
||||
## 확인된 사실
|
||||
1. `192.168.0.101`은 실제 응답하는 NAS였다.
|
||||
- `ping` 정상 응답
|
||||
- `22/80/443/139/445/5000/5001` 포트 오픈 확인
|
||||
- `5000/5001` 응답 기준 Synology DSM 장비 확인
|
||||
|
||||
2. NAS 내부에는 기존 백업 구조가 남아 있었다.
|
||||
- `home` 공유 접근 가능
|
||||
- `backup/current/{robing,gitea,config}` 존재
|
||||
- `gitea-lfs` 디렉터리 존재
|
||||
|
||||
3. 서버 쪽 마운트 설정은 구식 값이 남아 있었다.
|
||||
- `/etc/fstab`에 `//192.168.219.51/home /mnt/nas cifs username=admin,password=...` 형태의 평문 설정 존재
|
||||
- 이는 이전 IP 기준이며, SSOT 원칙에도 맞지 않았다.
|
||||
|
||||
## 실제 조치
|
||||
### 1. NAS 접근 확인
|
||||
- `smbclient -L //192.168.0.101 -U admin%...` 로 `home`, `homes` 공유 확인
|
||||
- `smbclient //192.168.0.101/home ...` 로 `backup`, `gitea-lfs` 실제 존재 확인
|
||||
|
||||
### 2. SSOT 반영
|
||||
- `/home/admin/infra-config/runtime.env`
|
||||
- `NAS_HOST=192.168.0.101`
|
||||
- `NAS_SMB_PORT=445`
|
||||
- `NAS_SHARE=home`
|
||||
- `NAS_MOUNT_PATH=/mnt/nas`
|
||||
- `/home/admin/infra-config/secrets.env`
|
||||
- `NAS_USERNAME=admin`
|
||||
- `NAS_PASSWORD=...`
|
||||
|
||||
### 3. 마운트 방식 교체
|
||||
- `/etc/fstab`의 평문 CIFS 항목은 주석 처리
|
||||
- `/usr/local/bin/mount-nas-ssot.sh` 생성
|
||||
- `runtime.env`, `secrets.env`를 읽어 CIFS 마운트 수행
|
||||
- `/etc/systemd/system/mount-nas-ssot.service` 생성 및 enable
|
||||
- 부팅 후 SSOT 기준으로 NAS 마운트 복구 가능하도록 구성
|
||||
|
||||
### 4. 권한 정합화
|
||||
- 초기 마운트는 `uid=1000` 기준이라 현재 사용자 `admin(uid=1001)`가 쓰기 불가
|
||||
- 마운트 옵션을 `uid=1001,gid=1000`으로 교정
|
||||
- 이후 `/mnt/nas/backup/weekly` 생성 및 쓰기 가능 확인
|
||||
|
||||
## 검증 결과
|
||||
1. 마운트 상태
|
||||
- `//192.168.0.101/home on /mnt/nas type cifs` 확인
|
||||
- `df -h /mnt/nas` 기준 5.3T 마운트 정상
|
||||
|
||||
2. 구조 확인
|
||||
- `/mnt/nas/backup/current`
|
||||
- `/mnt/nas/backup/archives`
|
||||
- `/mnt/nas/gitea-lfs`
|
||||
|
||||
3. 쓰기 확인
|
||||
- `/mnt/nas/backup/weekly/latest.txt` 생성 및 기록 성공
|
||||
|
||||
## 결론
|
||||
- 51123의 `/mnt/nas`는 다시 실NAS(`192.168.0.101`)를 바라보도록 복구되었다.
|
||||
- NAS 접속 정보는 `infra-config/runtime.env` + `secrets.env` 기준으로 SSOT화되었다.
|
||||
- 기존 `nas-fallback` 임시 우회 상태에서 한 단계 진전했지만, fallback 데이터 동기화 여부는 별도 점검이 필요하다.
|
||||
|
||||
## 전후 관계 문서
|
||||
- 이전: [260226_NAS_192_168_219_51_접속불가_임시백업복구](./260226_NAS_192_168_219_51_접속불가_임시백업복구.md)
|
||||
- 관련: [260307_51123_성수이전_네트워크변경_운영기록](./260307_51123_성수이전_네트워크변경_운영기록.md)
|
||||
@ -0,0 +1,76 @@
|
||||
# 260307 gateway SSOT(runtime/secrets) 분리 적용 및 검증
|
||||
|
||||
## 1. 목적
|
||||
- 51123 임시 운용 환경에서 분산된 설정값을 1차 정리한다.
|
||||
- 우선순위가 높은 `robeing-gateway`부터 `runtime.env`(비민감)와 `secrets.env`(민감)로 분리 적용한다.
|
||||
|
||||
## 2. 변경 사항
|
||||
### 2.1 SSOT 파일 신설
|
||||
- `/home/admin/infra-config/runtime.env` 생성
|
||||
- 운영 비민감값(예: `HOST_51123`, `NAS_HOST`, `ROBEING_DEFAULT_HOST`, `MONITOR_URL`) 관리
|
||||
- `/home/admin/infra-config/secrets.env` 생성
|
||||
- 민감값(예: `DATABASE_URL`, `JWT_SECRET_KEY`) 관리
|
||||
|
||||
### 2.2 권한 적용
|
||||
- `runtime.env`: `640`
|
||||
- `secrets.env`: `600`
|
||||
- 디렉터리 `/home/admin/infra-config`: `750`
|
||||
|
||||
### 2.3 게이트웨이 참조 경로 변경
|
||||
- 대상: `/home/admin/robeing-gateway/docker-compose.yml`
|
||||
- `env_file` 순서:
|
||||
1. `/home/admin/infra-config/runtime.env`
|
||||
2. `/home/admin/infra-config/secrets.env`
|
||||
3. `.env` (임시 오버라이드 전용)
|
||||
|
||||
### 2.4 기존 게이트웨이 `.env` 정리
|
||||
- 대상: `/home/admin/robeing-gateway/.env`
|
||||
- 실값 제거 후, “로컬 오버라이드 전용” 안내만 유지
|
||||
|
||||
## 3. 검증 결과
|
||||
### 3.1 설정 파싱 검증
|
||||
- `docker compose -f /home/admin/robeing-gateway/docker-compose.yml config` 성공
|
||||
|
||||
### 3.2 재가동 검증
|
||||
- 실행: `docker compose down && docker compose up -d --build`
|
||||
- 결과: `robeing-gateway` `Up (healthy)` 확인
|
||||
|
||||
### 3.3 기능 검증
|
||||
- `GET http://127.0.0.1:8100/healthz` -> `200`
|
||||
- 도메인 경유 `/gateway/api/config` -> 미인증 요청 `401` (정상 인증 경계)
|
||||
- `gateway -> 192.168.0.100:8001/health` -> `200`
|
||||
- `gateway -> 192.168.0.100:9024/healthz` -> `200`
|
||||
|
||||
## 4. 결론
|
||||
- 기존 무응답 핵심 원인이었던 연결 단절 상태는 해소됨.
|
||||
- 현재 `/api/message` 응답 경계는 연결 실패가 아니라 인증(`401`) 단계로 정상 전환됨.
|
||||
- SSOT 분리는 `robeing-gateway`에 1차 적용 완료, 나머지 서비스는 동일 패턴으로 순차 이전 필요.
|
||||
|
||||
## 5. 후속 적용: robeing-monitor SSOT 분리 및 9024 복구
|
||||
### 5.1 변경 사항
|
||||
- 대상: `/home/admin/robeing/robeing-monitor`
|
||||
- `docker-compose.yml`이 `/home/admin/infra-config/runtime.env`, `/home/admin/infra-config/secrets.env`를 우선 참조하도록 변경
|
||||
- 기존 `.env`는 로컬 오버라이드 전용 안내만 유지
|
||||
- `app/core/config.py` 기본 DB 호스트를 현재 운영 기준 `192.168.0.100`으로 교정
|
||||
- `infra-config`에 아래 값을 추가
|
||||
- `ROBEING_MONITOR_PORT`
|
||||
- `ROBEING_MONITOR_LOG_LEVEL`
|
||||
- `ROBEING_MONITOR_DATABASE_URL`
|
||||
- `ROBEING_URLS`
|
||||
- `SKILL_URLS`
|
||||
|
||||
### 5.2 증상
|
||||
- 적용 전 `robeing_monitor` 컨테이너는 `unhealthy`
|
||||
- `curl http://127.0.0.1:9024/healthz` 타임아웃
|
||||
- Docker healthcheck도 동일하게 `Health check exceeded timeout (10s)` 반복
|
||||
|
||||
### 5.3 검증 결과
|
||||
- `docker compose -f /home/admin/robeing/robeing-monitor/docker-compose.yml config` 성공
|
||||
- 실행: `docker compose down && docker compose up -d --build`
|
||||
- 결과: `robeing_monitor` `Up (healthy)` 확인
|
||||
- `GET http://127.0.0.1:9024/healthz` -> `200`
|
||||
|
||||
### 5.4 결론
|
||||
- `robeing-monitor`도 SSOT 기반으로 1차 이전 완료
|
||||
- 9024 응답 정지 상태는 해소됐고, 현재 헬스체크 정상
|
||||
- 51123 임시 운용 핵심 경로는 `gateway`, `rb8001`, `robeing-monitor`까지 정상 응답 기준으로 복구됨
|
||||
Loading…
x
Reference in New Issue
Block a user