76 lines
2.7 KiB
Markdown
76 lines
2.7 KiB
Markdown
# ADMIN_AUTH_PLAN (Laravel 12)
|
|
|
|
> 목적: **관리자(Admin) 영역**을 “허용된 IP + 이메일/비밀번호 + SMS OTP(필수) + (옵션) TOTP” 구조로 구축한다.
|
|
> 개발 환경: NAS nginx-proxy(HTTPS) → 내부 Docker(HTTP) → Laravel 12(PHP 8.3), Redis 사용
|
|
|
|
---
|
|
|
|
## 0) 현재 전제(프로젝트 컨텍스트)
|
|
|
|
- Web 도메인: `four.syye.net`
|
|
- Admin 도메인: `shot.syye.net`
|
|
- **Admin 도메인은 Laravel 라우트 그룹에서만** 접근 제어(개발용).
|
|
(Nginx allow/deny는 나중에 CloudFront/WAF에서 구현)
|
|
|
|
- Reverse proxy 구조:
|
|
- NAS `nginx-proxy`에서 HTTPS 종료
|
|
- 내부로 `gifticon-web:8091`, `gifticon-admin:8092`로 전달
|
|
- PHP는 `gifticon-app`(php-fpm)에서 처리
|
|
- Redis 사용: `gifticon-redis`
|
|
|
|
---
|
|
|
|
## 1) 보안 목표 & 정책
|
|
|
|
### 1.1 1차 방어: Admin IP Allowlist
|
|
- Admin 도메인 라우트 그룹에 `admin.ip` 미들웨어를 **반드시** 적용한다.
|
|
- `.env`의 `ADMIN_ALLOWED_IPS` 값을 사용한다.
|
|
- 실패 시 403.
|
|
|
|
> ⚠️ admin.ip 미들웨어를 login 라우트에 안 붙이면 “로그인 페이지가 열려 보안이 뚫린 것처럼 보이는” 문제가 생김.
|
|
> 해결: **도메인 그룹 단에서** `['web','admin.ip']` 적용.
|
|
|
|
### 1.2 2차 인증: 이메일/비밀번호 + SMS OTP(필수)
|
|
- 이메일/비밀번호가 맞으면 “임시 인증 상태”를 Redis에 저장하고, SMS로 OTP 코드를 발송한다.
|
|
- OTP 검증 성공 시에만 `auth:admin` 로그인 완료.
|
|
|
|
### 1.3 (옵션) TOTP(구글 OTP)
|
|
- 기본은 SMS OTP.
|
|
- “최고 관리자/특정 역할”에 한해 TOTP를 **옵션으로 활성화** 가능하도록 설계.
|
|
- 보안 우선순위: **TOTP > SMS** (SMS는 SIM 스와프 리스크 존재)
|
|
- 현실 운영 편의: **SMS만으로도 가능**, 대신 IP allowlist + rate limit + audit log를 강화.
|
|
|
|
### 1.4 비밀번호 해시(강력)
|
|
- Laravel `Hash::make()` 사용 (기본 bcrypt/argon 설정은 config로 통제)
|
|
- 권장: `argon2id` 고려(서버 자원 여유 있으면).
|
|
운영에서 튜닝(메모리/시간 비용) 필요.
|
|
|
|
### 1.5 전화번호 저장 정책 (B안 보안강화)
|
|
- DB에는 평문 전화번호를 저장하지 않는다.
|
|
- `phone_enc`(암호화 저장) + `phone_hash`(조회용) 조합 사용
|
|
- `phone_hash`: HMAC-SHA256(키 = `ADMIN_PHONE_HASH_KEY`)
|
|
- `phone_enc`: Laravel `Crypt::encryptString()` (키 = APP_KEY)
|
|
|
|
---
|
|
|
|
## 2) .env 표준화(도메인/URL)
|
|
|
|
권장 키:
|
|
|
|
```env
|
|
WEB_SCHEME=https
|
|
ADMIN_SCHEME=https
|
|
|
|
APP_DOMAIN=four.syye.net
|
|
ADMIN_DOMAIN=shot.syye.net
|
|
|
|
APP_URL=${WEB_SCHEME}://${APP_DOMAIN}
|
|
APP_ADMIN_URL=${ADMIN_SCHEME}://${ADMIN_DOMAIN}
|
|
|
|
ADMIN_ALLOWED_IPS=210.96.177.79
|
|
ADMIN_PHONE_HASH_KEY=change-me-long-random
|
|
ADMIN_OTP_TTL=300
|
|
ADMIN_OTP_MAX_ATTEMPTS=5
|
|
ADMIN_SMS_TTL=180
|
|
ADMIN_REDIS_PREFIX=admin:2fa:
|