Skip to content

prego-docker 이미지 검증 및 취약점 대응 기획

목적: (1) Frappe·ERPNext·HRMS·custom app이 이미지에 정상 포함되었는지 검증하는 방법을 정리하고, (2) Docker Hub 등에서 보고되는 취약점을 해결하는 방향을 기획한다. 코드 생성은 하지 않고 검증 절차·취약점 대응 전략만 문서화한다.

대상 이미지: iamfork/prego-repo (prego-docker build-and-push, tag 기반 pinning).


1. 이미지 내 앱 포함 여부 검증

1.1 기대 구조

bench init --apps_path=/opt/frappe/apps.json 은 apps.json에 정의된 앱을 설치한다.
현재 apps.json: erpnext (version-15), hrms (version-15), prego-saas-app (v1.0.0).
Frappe는 bench init 시 기본으로 설치되므로, 최종 이미지의 /home/frappe/frappe-bench/apps/ 아래에는 다음이 있어야 한다.

디렉터리검증 포인트
Frappefrappebench의 코어, sites·env 공유
ERPNexterpnexterpnext 앱 디렉터리·패키지
HRMShrmshrms 앱 디렉터리·패키지
Custom appprego_saas_appprego_saas_app 앱 디렉터리·setup.py 등

1.2 검증 방법 (수동·로컬)

이미지 pull 후 실행 중인 컨테이너 또는 일회 실행으로 디렉터리·버전 확인.

단계명령/확인 내용
1docker pull iamfork/prego-repo:latest (또는 특정 태그)
2docker run --rm iamfork/prego-repo:latest ls -la /home/frappe/frappe-bench/apps/frappe, erpnext, hrms, prego_saas_app 디렉터리 존재
3docker run --rm iamfork/prego-repo:latest cat /home/frappe/frappe-bench/apps/prego_saas_app/setup.py → prego_saas_app 패키지 내용 확인
4(선택) docker run --rm iamfork/prego-repo:latest /home/frappe/frappe-bench/env/bin/pip list | grep -i frappe 등으로 설치된 앱 패키지 확인

정상 기준: 위 디렉터리 4개가 존재하고, 각 앱 소스(최소 디렉터리·setup.py)가 비어 있지 않음.

1.3 검증 방법 (CI·자동화)

  • 시점: build-and-push 성공 후, 별도 검증 job 또는 동일 워크플로 내 후속 step.
  • 방식:
    • 방안 A: docker run --rm <이미지> ls /home/frappe/frappe-bench/apps/ 실행 후 stdout에서 frappe, erpnext, hrms, prego_saas_app 포함 여부 검사.
    • 방안 B: 동일 레포 또는 별도 레포에 “image verify” 워크플로를 두고, 특정 태그(예: latest 또는 빌드가 푸시한 태그)에 대해 위 명령을 실행하고 exit code·출력으로 pass/fail 판단.
  • 실패 시: 이미지에 앱이 누락된 빌드로 간주하고, bench init 또는 apps.json·태그 검증 단계를 점검.
  • 구현 상태: prego-docker build.ymlVerify image apps 단계 적용됨. 푸시 직후 해당 태그 이미지를 pull하여 4개 앱 디렉터리 존재 여부 검사, 누락 시 job 실패.

1.4 요약

  • 정상 여부: Frappe·ERPNext·HRMS·custom app 네 가지가 모두 /home/frappe/frappe-bench/apps/ 아래에 존재하면 “정상적으로 이미지 안에 들어간 것”으로 판단 가능.
  • 문서화: 위 1.2를 runbook docs/runbook/prego-docker-image-verify.md 로 정리했고, 1.3은 CI(build.yml Verify image apps)에 반영됨.

2. 취약점 해결 방향

2.1 현재 상황 (참고)

Docker Hub 스캔 결과 예: Critical 8, High 51, Medium 61, Low 76, Unknown 2 (이미지·스캔 시점에 따라 상이).
주요 발생 위치: 베이스 이미지(python:3.11-slim-bookworm), Node/프론트 빌드 의존성(npm), bench/pip 설치 패키지(pypi) 등.
예시 CVE: golang stdlib, npm loader-utils/form-data/@babel/traverse, pypi pillow 등.

2.2 대응 원칙

원칙설명
우선순위Critical → High → Medium 순으로 처리. Low/Unknown은 정책에 따라 수용 또는 주기 점검.
레이어 구분베이스 이미지 / 시스템 패키지(apt) / Node(npm) / Python(pip) 별로 출처를 구분하고, 각 레이어에서 패치 가능한지 판단.
호환성Frappe v15·ERPNext·HRMS 공식 요구사항과 충돌하지 않는 범위에서만 버전 상향.
재현성Dockerfile·apps.json·태그로 빌드가 재현 가능하므로, 베이스/의존성 변경 시 빌드·검증 후 배포.

2.3 대응 방안 (방향만)

구분대상해결 방향 (기획 수준)
베이스 이미지python:3.11-slim-bookworm주기적으로 최신 digest 또는 태그로 갱신. Debian 보안 업데이트 반영 여부 확인.
시스템 패키지Dockerfile 내 apt-get installapt-get update 및 고정된 패키지 버전 사용 시, 보안 업데이트가 포함된 베이스 또는 패키지 버전 상향 검토.
Node/npmNVM·yarn·프론트 빌드 의존성Node 버전 상향(현재 20 LTS 유지 시 보안 패치 버전으로), npm audit 가능 시 의존성 업데이트·교체 검토.
Python/pipfrappe-bench·Frappe·ERPNext·HRMS·prego_saas_appFrappe/ERPNext/HRMS는 upstream 버전 따름. custom app(prego_saas_app)의 install_requires·requirements.txt는 최소 유지·업데이트 가능 패키지만 포함.
스캔 도구Docker Hub / Trivy / Snyk 등CI에서 주기 스캔 도입 시, Critical/High만 fail로 두거나, 리포트만 수집 후 수동 대응 정책 선택.

2.4 단계별 접근 (제안)

단계내용산출물
1현황 정리Docker Hub(또는 Trivy) 스캔 결과에서 Critical/High 목록·영향 레이어(베이스/apt/npm/pip) 매핑.
2베이스·시스템python 이미지 최신 bookworm 태그/digest 반영, apt 패키지 필요 최소화·버전 명시.
3Node/npmNode 20.x 최신 패치, npm 패키지 중 알려진 CVE 있는 것만 선별 업데이트(호환성 테스트 후).
4Python 쪽Frappe/ERPNext/HRMS는 upstream 의존성 유지. custom app은 stripe 등 외부 라이브러리만 버전 상향 검토.
5정책“Critical 0, High N 이하” 등 수용 기준을 정하고, CI 또는 주기 빌드에서 스캔 결과로 통과/실패 또는 경고만 출력.

2.5 주의사항

  • False positive: 스캔 도구가 “이미지에 포함된 바이너리”를 특정 패키지로 잘못 매칭할 수 있음. CVE별로 “실제 사용 코드 경로에 영향이 있는지” 확인 후 조치하는 것이 안전함.
  • Upstream 의존성: Frappe/ERPNext/HRMS 내부 의존성은 우리가 직접 올리지 않으므로, 가능한 범위는 (1) 베이스·시스템·Node 버전 정리, (2) custom app 의존성 최소화·업데이트, (3) upstream 보안 릴리스 반영 시 이미지 재빌드.

3. 취약점 대응 — 어디서·어떻게 진행할지

아래는 (1)~(5) 단계를 실행 위치·도구·파일·명령 기준으로 구체화한 가이드다.

(1) Critical·High 목록·레이어 매핑

항목어디서어떻게
Docker Hubhttps://hub.docker.comiamfork/prego-repo → Tags → 해당 태그(예: latest) 클릭Vulnerabilities 탭에서 Critical/High 개수·목록·“Present in”(레이어)·“Affected package(s)” 확인. CVE ID·패키지명·레이어 번호를 스프레드시트나 문서에 정리.
Trivy (로컬)로컬 터미널 (Trivy 설치: brew install trivy)trivy image iamfork/prego-repo:latest 실행. CRITICAL/HIGH 행만 필터. trivy image --format table iamfork/prego-repo:latest 로 테이블 확인. 레이어는 Docker Hub Layers와 대응.
Trivy (CI)prego-docker 레포새 workflow: .github/workflows/trivy-scan.yml. on: workflow_dispatch 또는 schedule. Job에서 docker pull iamfork/prego-repo:latesttrivy image --exit-code 1 --severity CRITICAL,HIGH ... 로 스캔. 결과를 artifact 또는 job summary로 저장.
매핑 정리Prego 문서 또는 이슈CVE 목록 + 해당 레이어(베이스/apt/npm/pip) + Affected package 표를 만들어 docs/planning/ 또는 GitHub Issue에 정리. (2)~(4)에서 어떤 레이어를 수정할지 결정할 때 사용.

(2) 베이스·시스템 정리

항목어디서어떻게
베이스 이미지prego-docker/Dockerfile (1행 근처)FROM python:3.11-slim-bookworm. Docker Hub → python → Tags → 3.11-slim-bookworm → Digest 복사 후 FROM python:3.11-slim-bookworm@sha256:... 로 고정. 주기적으로 최신 digest로 갱신.
시스템 패키지prego-docker/Dockerfile (base·builder 스테이지)apt-get install 목록 검토. 불필요 패키지 제거. 보안 업데이트 반영은 베이스 이미지 갱신으로 충분한지 먼저 확인.
검증로컬 또는 CIdocker build 후 Trivy/Docker Hub로 재스캔해 Critical/High 감소 여부 확인.

(3) Node/npm

항목어디서어떻게
Node 버전prego-docker/Dockerfile (ARG NODE_VERSION=20)Node 20 LTS 최신 패치(예: 20.18.x)로 상향. nodejs.org 또는 nvm 문서에서 버전 확인 후 반영.
npm 의존성이미지 내부(Frappe/ERPNext 빌드 시)(1)에서 npm 패키지 CVE는 upstream(Frappe/ERPNext) 이슈·업데이트를 따르거나, Node 버전 상향으로 완화 가능한지 확인. custom app에 package.json이 있으면 해당 레포에서 npm audit / npm audit fix.

(4) Python (custom app)

항목어디서어떻게
custom appprego-saas-app/setup.pyinstall_requires(stripe 등) 버전을 PyPI 기준 안전 버전으로 상향.
Frappe/ERPNext/HRMSupstream직접 수정하지 않음. apps.json branch 유지, upstream 보안 릴리스 시 브랜치/태그 갱신 후 이미지 재빌드.

(5) 정책 + CI/주기 스캔

항목어디서어떻게
정책팀/문서”Critical 0, High N 이하” 등 수용 기준을 docs/planning/ 또는 runbook에 명시.
CI 스캔prego-docker.github/workflows/trivy-scan.yml 생성. trivy image --exit-code 1 --severity CRITICAL iamfork/prego-repo:$TAG 로 Critical 있으면 실패. High는 threshold 스크립트 또는 --severity CRITICAL,HIGH 로 정책에 맞게 설정.
주기 스캔prego-dockeron: schedule: - cron: '0 9 * * 1' (매주 월요일 09:00). Trivy 결과를 artifact 또는 이슈로 저장.

실행 순서: (1) → (2) → (3) → (4) → (5). prego-docker(Dockerfile·워크플로), prego-saas-app(setup.py), Prego 문서(정책·runbook)에 나눠 반영.


4. 정리

  • 이미지 검증: Frappe·ERPNext·HRMS·custom app이 /home/frappe/frappe-bench/apps/ 아래에 모두 존재하는지 로컬 명령(§1.2) 또는 **CI 검증(§1.3)**으로 확인하면 “정상 포함” 여부를 판단할 수 있다.
  • 취약점: 베이스 이미지·시스템 패키지·Node·Python(custom app) 순으로 우선순위를 두고, Critical/High 위주로 정리하며, Frappe/ERPNext/HRMS 호환성을 해치지 않는 범위에서 버전·이미지 갱신과 정책(스캔 기준·주기)을 정하는 것이 좋다.

다음 단계: 필요 시 §1.2를 runbook으로 작성하고, §2.3·2.4에 따라 “현황 정리” 단계에서 실제 CVE 목록·레이어 매핑을 한 뒤, 적용 가능한 Dockerfile·의존성 변경을 별도 작업으로 진행한다.


5. 취약점 수용 정책 (구현 반영)

항목기준
Critical0 — 1건이라도 있으면 CI(Trivy) 실패.
High보고만(CI는 통과). 필요 시 N 이하로 threshold 조정 가능.
실행prego-docker .github/workflows/trivy-scan.yml: workflow_dispatch(태그 지정 가능) + 매주 월요일 09:00 UTC schedule.
Runbook이미지 앱 검증 절차: docs/runbook/prego-docker-image-verify.md.
Help