From 942981df54e51c921423d0510dce1238b47486ff Mon Sep 17 00:00:00 2001 From: happybell80 Date: Fri, 27 Feb 2026 03:41:47 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EC=A0=95=EB=A6=AC=20-=20slack=20events?= =?UTF-8?q?=20=EC=84=9C=EB=AA=85=20=EB=B6=88=EC=9D=BC=EC=B9=98=EC=99=80=20?= =?UTF-8?q?500=20=EB=A7=A4=ED=95=91=20=EC=9D=B4=EC=8A=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ents_signature_mismatch_and_500_mapping.md | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 journey/troubleshooting/260227_gateway_slack_events_signature_mismatch_and_500_mapping.md diff --git a/journey/troubleshooting/260227_gateway_slack_events_signature_mismatch_and_500_mapping.md b/journey/troubleshooting/260227_gateway_slack_events_signature_mismatch_and_500_mapping.md new file mode 100644 index 0000000..db2fc1e --- /dev/null +++ b/journey/troubleshooting/260227_gateway_slack_events_signature_mismatch_and_500_mapping.md @@ -0,0 +1,76 @@ +# Gateway Slack Events 서명 불일치 및 500 매핑 이슈 정리 + +**작성일**: 2026-02-27 +**작성자**: Codex +**상태**: 진행 중 (부분 해결) + +## 문제 요약 + +- `/gateway/slack/events` 요청이 반복적으로 `500` 반환 +- 초기 에러는 `rb8001`에서 `could not convert string to float: ''` +- 이후 `float('')` 가드 추가 후에도 `Invalid Slack signature` + `500` 지속 + +## 확인된 사실 (로그/코드 기준) + +1. **재현 시각/패턴** +- 최초 관측: `2026-02-13 14:39 (KST)` +- 반복 관측: `2026-02-19`, `2026-02-21`, `2026-02-27` +- 2026-02-27 기준 nginx `access.json`에서 `/gateway/slack/events`가 전부 `500`으로 관측 + +2. **게이트웨이(51123) 로그** +- 실유입 시 `X-Slack-Signature`, `X-Slack-Request-Timestamp` 헤더 키는 전달됨 +- 동시각 `rb8001` 호출 결과가 `500`으로 반환됨 + +3. **rb8001(51124) 로그** +- `Invalid Slack signature` 직후 `Error processing Slack event: 403: Invalid signature` +- 최종 응답이 `500 Internal Server Error`로 기록됨 + +## 잘못된 과정 (이번 장애에서의 오판/미흡) + +1. **헤더 키 전달 누락만 원인으로 먼저 고정한 점** +- 실제로는 헤더 키 전달 문제 + 본문 원문 보존 문제 + 403→500 매핑 문제가 함께 존재 + +2. **이벤트 본문 원문 보존 미처리** +- `robeing-gateway` `/slack/events` 경로에서 `request.json()` 후 `json=` 재전달 구조였음 +- Slack 서명 검증은 원문 바디 기준이므로 재직렬화 시 검증 불일치 가능 + +3. **rb8001 예외 처리 구조 미정리** +- `HTTPException(403)`를 광범위 `except Exception`에서 잡아 다시 `500`으로 변환 +- 인증 실패를 서버 장애처럼 보이게 만듦 + +## 원인 정리 (우선순위) + +1. **1순위**: `rb8001`의 `403 -> 500` 재매핑 구조 (`slack_endpoint.py`) +2. **2순위**: `gateway /slack/events` 본문 재직렬화(`json=`)로 인한 서명 불일치 가능성 +3. **보조 요인 아님**: DB/환경변수 변경은 이번 트리거 직접 증거가 약함 + +## 이번에 반영된 수정 (51123만) + +### A. 헤더 전달 보강 +- `X-Slack-Signature`, `X-Slack-Request-Timestamp` 전달 +- 커밋: `9097eee` (`fix: forward Slack signature headers on /slack/events`) + +### B. 원문 body 보존 전달 +- `/slack/events`: `raw_body = await request.body()` +- rb8001 전송: `client.post(..., content=raw_body, headers=...)` +- `Content-Type` 전달 추가 +- 커밋: `12c06ca` (`fix(slack): preserve raw event body for signature verification`) + +## 아직 남은 조치 (미해결 항목) + +1. **rb8001에서 403을 500으로 바꾸지 않도록 예외 분기 수정 필요** +- `except HTTPException as e: raise e` 또는 동등한 분기 필요 +- 현재는 이 미조치로 인증 실패가 계속 500으로 관측됨 + +2. **실유입 기준 최종 검증** +- 기대 결과: 인증 실패면 `403`, 정상 서명이면 `200` +- 더 이상 `/gateway/slack/events`에서 일괄 `500`이 나오지 않아야 함 + +## 관련 파일 + +- `robeing-gateway/app/routers/slack.py` +- `robeing-gateway/app/services/slack_proxy.py` +- `rb8001/app/router/slack_endpoint.py` +- `/var/log/nginx/access.json` +- `/mnt/hdd/logs/51124-server/rb8001/rb8001.log` +