# VPN 서버 vpnid_list 암호 암호화 배포 안내

> **[2026-07-04 실사 결과: 현 IKEv2 서버(hp-server, 183.108.10.158)에는 이 킷의 배포가 불필요합니다.]**
> SSH 실사 결과 IKEv2SellerOffice4U/mylib4ikev2svr 코드에는 `vpn_user_pwd`/`member_pwd` DB 참조가 전혀 없고,
> 로컬 DB에 vpnid 계열 테이블도 없습니다. VPN 자격증명은 `/etc/ipsec.secrets`(600, strongSwan 요구상 평문)와
> `user_billing.json`(600) 파일로만 관리되며, vpnid_list는 샵 DB 하나뿐입니다(샵 측 암호화 완료).
> 이 킷은 **향후 vpnid/vpnid_list DB를 로컬 보유한 레거시(CentOS IKEv2SellerOffice) 서버를 발견/재가동할 경우**를 위한 참고용으로 보존합니다.

샵 서버(2026-07-04 적용 완료)와 동일한 `VLSEC1:` 암호화 정책을 VPN 서버(183.108.10.158)의
`vpnid_list.vpn_user_pwd`에 적용하기 위한 배포 킷입니다.

## 정책 요약

- 저장 포맷: `VLSEC1:` + base64(iv) + `:` + base64(AES-256-CBC 암호문)
- 키: 공유 시크릿(sha256) — **DB 외부**(.env / ikev2_secret.php / 환경변수)에만 보관
- 접두어 없는 레거시 평문은 복호화 함수가 그대로 통과(하위호환) → 코드 先배포, 데이터 後암호화 순서로 무중단 전환
- ipsec.secrets 파일은 strongSwan 요구사항상 평문 유지(이번 위협모델은 "DB 단독 유출" 대응)

## 배포 순서 (반드시 이 순서로)

1. **헬퍼 업로드**: `vpnlink_pwd_vault.lib.php` → `/var/www/html/mylib4ikev2svr/` 에 복사
2. **시크릿 확인**: VPN 서버에서 `php -r "require '/var/www/html/mylib4ikev2svr/vpnlink_pwd_vault.lib.php'; var_dump(vpnlink_vault_secret() !== '');"` → `true` 확인
3. **읽기 코드 패치 (先배포)** — vpnid_list 에서 `vpn_user_pwd` 를 읽는 모든 지점에
   `require_once '/var/www/html/mylib4ikev2svr/vpnlink_pwd_vault.lib.php';` 후
   `$pwd = vpnlink_vpn_pwd_reveal($row['vpn_user_pwd']);` 적용.
   실제 파일은 서버에서 `grep -rn "vpn_user_pwd" /var/www/html/IKEv2SellerOffice4U /var/www/html/mylib4ikev2svr --include="*.php"` 로 확정할 것. 예상 지점:
   - `IKEv2SellerOffice4U/vpn_users.php` (VPNUserManager — 목록/상세 표시, ipsec.secrets 기록 시)
   - `IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php` (샵↔VPN 비교 — 해시/비교 전 reveal)
   - `IKEv2SellerOffice4U/Crons/cron_expire_enforce.php` (계정 재기록 시)
   - 샵의 서버사용자 조회 API(`vpnlink_ikev2_fetch_server_users` 가 호출하는 엔드포인트) — `password_sha256` 산출 전 reveal
4. **쓰기 코드 패치** — vpnid_list 에 `vpn_user_pwd` 를 INSERT/UPDATE 하는 지점에
   `vpnlink_vpn_pwd_protect($plain)` 적용. 예상 지점:
   - `mylib4ikev2svr/ikev2_ipsec.secrets_update.php` (샵 프로비저닝 수신 → vpnid_list 기록)
   - `mylib/ikev2_shop_sync_event_receiver.php` (백엔드 액션 수신: add_user/update_user 등)
5. **마이그레이션**: `migrate_encrypt_vpnid_pwd_cli.php` 업로드 후 상단 DB 상수 수정 →
   `php migrate_encrypt_vpnid_pwd_cli.php` (dry-run) → 건수 확인 → `--apply`
6. **검증**:
   - 관리패널에서 VPN 사용자 목록/상세의 암호 표시 정상 확인
   - `php IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php --json` 에서 password 불일치 오탐 없는지 확인
   - 샵 관리자 `adm/shop_admin/ikev2_server_compare.php` 비교 결과 정상 확인
   - 신규 구매 1건 프로비저닝 → VPN 접속 테스트

## 주의

- 3(읽기 reveal)보다 5(데이터 암호화)를 먼저 실행하면 패널·크론이 암호문을 그대로 표시/비교하게 됨.
  반드시 **코드 先배포 → 데이터 後암호화**.
- 마이그레이션 전 `mysqldump vpnid_list` 백업 권장. 백업 파일은 평문 암호를 포함하므로 작업 후 즉시 삭제.
- 샵 서버 측 대응 코드는 이미 배포됨: `mylib/ikev2_provision.lib.php` 의
  `vpnlink_vpn_pwd_protect/reveal` (동일 포맷·동일 시크릿).
