diff --git a/mail/README.md b/mail/README.md index 29ef43a..27c5c69 100644 --- a/mail/README.md +++ b/mail/README.md @@ -288,7 +288,7 @@ node --env-file=.env.development mail/scripts/setup.mjs - **계정 보안(12단계)** — `.env.production` 의 `MAIL_WEBHOOK_SECRET`(엔진 웹훅의 서명 키 — `openssl rand -hex 24` 로 만든 값, 사람이 지은 값은 쓰지 않는다). 운영 필수다 — 아래 2)의 `up` **전에** 넣는다(없으면 백엔드가 env 검사에서 멈춰 웹메일 전체가 서고, setup 도 멈춘다). 직원에게 미리 알린다 — 2단계 인증을 켜면 아웃룩 · 휴대폰 메일 앱은 앱 비밀번호로 다시 연결해야 한다 ([계정 보안](#계정-보안-12단계--인프라)) -- **전환 준비(13단계)** — 이미 떠 있는 서버는 [13단계 전부터 운영 중인 서버](#13단계-전부터-운영-중인-서버)의 차례대로(첫 setup 은 `--recovery`). 첫 직원을 옮기기 **전에** 백업과 15분 점검을 켠다: NCP Object Storage 비공개 버킷 · Object Storage 만 쓰는 하위 계정 키 · restic 비밀번호(비밀번호 관리자에 따로 보관), +- **전환 준비(13단계)** — 이미 떠 있는 서버는 [13단계 전부터 운영 중인 서버](#13단계-전부터-운영-중인-서버)의 차례대로(첫 setup 은 `--recovery`). 첫 직원을 옮기기 **전에** 백업과 15분 점검을 켠다: NCP Object Storage 비공개 버킷 · 백업 전용 API 인증키(아래 "백업 › 설치" — 메인 계정 키를 고른 까닭과 위험) · restic 비밀번호(비밀번호 관리자에 따로 보관), Healthchecks.io 점검 둘 · UptimeRobot 감시 셋 ([백업](#백업) · [감시](#감시-13단계)). `.env.production` 의 `DB_IMAGE` 를 예시와 같은 값(판 · digest 고정 — 옛 파일은 `postgres:15-alpine`)으로 바꾼다 — 다음 `up -d` 에서 db 가 다시 만들어진다(몇 초 · 데이터는 볼륨 그대로, 같은 메이저 15 라 덤프 · 복원은 필요 없다). frontend 는 `MAIL_DOMAIN` · `MAIL_HOSTNAME` 으로 [메일 프로그램 자동 설정](#메일-프로그램-자동-설정) 응답을 만든다 — 이미 있는 값이라 새로 넣을 것은 없다 @@ -1770,10 +1770,13 @@ systemctl list-timers 'arasystem-*' ``` - **NCP Object Storage** — 콘솔에서 한국 리전에 버킷을 만든다(공개 안 함 · 수명 주기 삭제 규칙 없음 — 지우기는 restic 이 한다). - **버킷에는 따로 키가 없다** — API 인증키(Access Key ID · Secret Key)는 Object Storage 만 쓰는 **서브 계정**의 것을 쓴다(메인 계정 키는 서버 · 결제까지 연다): - 콘솔 › Sub Account › Sub Accounts › 서브 계정 생성(접근 유형은 **API Gateway 접근만** — 콘솔 로그인 없음) → 그 계정의 **정책** 탭에 관리형 `NCP_OBJECT_STORAGE_MANAGER` 하나 - (`…_VIEWER` 는 읽기만이라 백업이 안 된다) → **Access Key** 탭에서 추가 — **Secret Key 는 만들 때만 보인다**, 그 자리에서 비밀번호 관리자(restic 비밀번호와 같은 항목)에 둔다 → ops.env 의 `AWS_ACCESS_KEY_ID` · `AWS_SECRET_ACCESS_KEY`. - NCP 문서에는 키를 버킷 하나로 좁히는 방법이 없다(2026-11-03 — 사용자 정의 정책도 버킷을 고르는 칸이 문서에 없다) — 이 키로 같은 계정의 버킷이 모두 열리므로 다른 버킷을 두지 않는다(시험 버킷은 쓸모가 끝나면 지운다). + **버킷에는 따로 키가 없다** — 계정의 API 인증키(Access Key ID · Secret Key)를 쓴다. **서버 B 는 메인 계정의 API 인증키를 백업 전용으로 새로 만들어 쓴다**(2026-11-03 사용자 결정 — 서브 계정은 만들지 않는다): + 콘솔 오른쪽 위 My Account › 계정 및 보안 관리(다시 로그인) › 보안 관리 › 접근 관리 › API 인증키 관리 › [신규 API 인증키 생성] — 계정마다 2개까지라, 처음부터 있던 기본 키는 쓰지 않는다 + (그 키를 쓰는 다른 곳과 섞이지 않게 — 문제가 생기면 이 키만 사용 중지할 수 있다) → 두 값을 비밀번호 관리자(restic 비밀번호와 같은 항목)에 → ops.env 의 `AWS_ACCESS_KEY_ID` · `AWS_SECRET_ACCESS_KEY`. + ⚠️ **메인 계정 키는 Object Storage 만이 아니라 그 NCP 계정의 모든 API 를 연다**(서버 A · B, 네트워크 · ACG, 스토리지 …) — 이 키가 놓이는 서버 B 의 root 가 뚫리면 계정 전체가 넘어간다. 받아들이고 고른 길이다. + 범위를 줄이려면 서브 계정으로 바꾼다 — Sub Account › Sub Accounts › 서브 계정 생성(접근 유형 **API Gateway 접근만**) → 정책 탭에 관리형 `NCP_OBJECT_STORAGE_MANAGER` 하나(`…_VIEWER` 는 읽기만이라 백업이 안 된다) + → Access Key 탭에서 추가(**Secret Key 는 만들 때만 보인다**). 그래도 버킷 하나로는 좁히지 못한다(NCP 문서에 그 방법이 없다 — 2026-11-03) — 같은 계정에 다른 버킷을 두지 않는다(시험 버킷은 쓸모가 끝나면 지운다). + 키를 바꿀 때는 새 키를 ops.env 에 넣고 백업이 한 번 된 것을 본 뒤 옛 키를 사용 중지 → 삭제(사용 중지한 키만 지울 수 있다). 만들 때의 다른 칸은 기본값 그대로 — **잠금 해제**(보존 기간을 걸면 restic 이 지난 백업을 지우지 못해 prune 이 실패한다) · **암호화(KMS) 해제**(restic 이 이미 암호화한다. 한 번 켜면 끌 수 없다) · 타 계정 권한 없음. "공개"는 버킷의 폴더 · 파일 목록을 누구에게나 연다 — restic 은 키로 서명해 들어가므로 필요 없다(NCP 가이드 "버킷 관리", 2026-11-03 확인). `RESTIC_REPOSITORY=s3:https://kr.object.ncloudstorage.com/<버킷>/arasystem`, `RESTIC_OPTIONS='-o s3.region=kr-standard -o s3.bucket-lookup=path'` — diff --git a/ops/ops.env.example b/ops/ops.env.example index 7713173..cf75381 100644 --- a/ops/ops.env.example +++ b/ops/ops.env.example @@ -31,8 +31,8 @@ RESTIC_REPOSITORY=s3:https://kr.object.ncloudstorage.com/change-me-bucket/arasys # NCP 의 S3 옵션 — 지역 kr-standard(서명 V4 에 쓴다) · 경로 방식(https://<엔드포인트>/<버킷> — NCP 는 경로 · 가상 호스트 방식 둘 다 받는다) # (근거: NCP API 가이드 Object Storage — https://api.ncloud-docs.com/docs/storage-objectstorage · …-listobjects) RESTIC_OPTIONS='-o s3.region=kr-standard -o s3.bucket-lookup=path' -# NCP 서브 계정의 API 인증키 — Object Storage 만 쓰는 서브 계정으로 (콘솔 › Sub Account — 접근 유형 API Gateway 만 · 정책 NCP_OBJECT_STORAGE_MANAGER 하나 · Access Key 탭). -# 버킷에는 따로 키가 없고, NCP 는 키를 버킷 하나로 좁히지 못한다 — 같은 계정에 다른 버킷을 두지 않는다. Secret Key 는 만들 때만 보인다(바로 비밀번호 관리자에) +# NCP API 인증키 — 버킷에는 따로 키가 없다. 서버 B 는 메인 계정의 백업 전용 키(My Account › 계정 및 보안 관리 › 보안 관리 › 접근 관리 › API 인증키 관리 — 2026-11-03 결정). +# ⚠️ 메인 계정 키는 그 계정의 모든 API 를 연다 — 범위를 줄이려면 Object Storage 만 쓰는 서브 계정의 키로(mail/README.md "백업 › 설치"). 어느 쪽이든 버킷 하나로는 좁히지 못한다 AWS_ACCESS_KEY_ID=change-me AWS_SECRET_ACCESS_KEY=change-me # 보존 — 매일 7 · 매주 4 · 매달 6 (그보다 오래된 백업은 지운다 — 지운 메일도 이 기간까지만 백업에 남는다)