Trivy (발음: /ˈtraɪvi/)는 Aqua Security에서 개발한 오픈소스 종합 보안 스캐너로, GitHub에서 35,000개 이상의 스타를 보유한 가장 인기 있는 오픈소스 보안 스캔 도구 중 하나입니다.
Trivy의 핵심 강점은 그 포괄성에 있습니다. 컨테이너 이미지, 파일 시스템, Git 저장소, 가상 머신 이미지, Kubernetes 클러스터 등 다양한 대상을 스캔할 수 있을 뿐만 아니라, 알려진 CVE 취약점, IaC 구성 오류, 민감 정보 노출, 소프트웨어 라이선스, SBOM 생성 등 다양한 보안 문제를 탐지합니다. 최신 DevSecOps 팀에게 Trivy는 코드 커밋부터 프로덕션 배포까지 전체 보안 스캔 파이프라인을 거의 모두 커버할 수 있습니다.
이 글에서는 설치부터 시작하여 Trivy의 핵심 기능, 실전 사용법, CI/CD 파이프라인에 Trivy를 통합하는 방법까지 단계별로 소개합니다. 개발자와 보안 엔지니어가 이 강력한 보안 도구를 빠르게 익힐 수 있도록 도와드리겠습니다.
왜 Trivy를 선택해야 할까?
Trivy가 등장하기 전에는 보안 스캔 분야가 대체로 파편화되어 있었습니다. 컨테이너 이미지를 스캔하려면 다른 도구를, IaC 구성을 확인하려면 또 다른 도구를, 코드 내 시크릿 노출을 찾으려면 또 다른 도구를 사용해야 했죠. Trivy는 이러한 기능을 하나의 통합 CLI 도구에 담아냈으며, 다음과 같은 뛰어난 특징을 제공합니다.
1. 다양한 대상 스캔 지원
Trivy는 다음 대상을 스캔할 수 있습니다.
- 컨테이너 이미지: Docker, OCI 호환 이미지 (로컬 또는 원격 레지스트리)
- 파일 시스템: 로컬 디렉토리, 프로젝트 소스 코드
- Git 저장소: 원격 Git 저장소 (클론 불필요)
- 가상 머신 이미지: AWS EC2 AMI, Azure VM 등
- Kubernetes 클러스터: 실행 중인 클러스터의 리소스 구성
2. 다차원 보안 탐지
Trivy는 다음과 같은 유형의 보안 문제를 발견할 수 있습니다.
- 알려진 취약점 (CVE): OS 패키지 및 소프트웨어 의존성 기반 취약점 데이터베이스
- IaC 구성 오류: Terraform, CloudFormation, Kubernetes YAML 등의 모범 사례 위반
- 민감 정보 노출: 하드코딩된 API 키, 비밀번호, 토큰
- 소프트웨어 라이선스 규정 준수: 프로젝트에서 사용된 오픈소스 라이선스 유형 식별
- SBOM 생성: 소프트웨어 자재 명세서(Software Bill of Materials) 생성
3. 쉬운 통합
Trivy는 다양한 통합 옵션을 제공합니다.
- GitHub Actions: trivy-action
- Kubernetes Operator: trivy-operator
- VS Code 플러그인: trivy-vscode-extension
- CI/CD 플랫폼: Jenkins, GitLab CI, CircleCI 등
4. 빠른 속도, 낮은 리소스 사용량
Trivy는 Go 언어로 작성되어 시작 속도가 빠르고 메모리 사용량이 낮아 CI/CD 파이프라인에서 자주 실행하기에 적합합니다.
Trivy 설치
Trivy는 다양한 설치 방식을 지원합니다. 가장 일반적인 방법들은 다음과 같습니다.
방법 1: Homebrew 사용 (macOS/Linux)
brew install trivy
방법 2: Docker 사용
docker run aquasec/trivy --version
방법 3: 바이너리 파일 다운로드
GitHub Releases에서 해당 플랫폼의 바이너리 파일을 다운로드합니다.
# Linux x86_64
wget https://github.com/aquasecurity/trivy/releases/download/v0.50.0/trivy_0.50.0_Linux-64bit.tar.gz
tar -xzf trivy_0.50.0_Linux-64bit.tar.gz
sudo mv trivy /usr/local/bin/
방법 4: apt/yum 사용 (Linux 배포판)
# Ubuntu/Debian
sudo apt-get install wget gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
# CentOS/RHEL
sudo yum install trivy
설치 확인
trivy --version
# 출력 예시: Version: 0.50.0
빠르게 시작하기: 첫 번째 컨테이너 이미지 스캔
간단한 예제부터 시작해 보겠습니다. 공개 Docker 이미지를 스캔해서 Trivy가 무엇을 발견하는지 확인해 봅시다.
Python 공식 이미지 스캔
trivy image python:3.9-slim
Trivy는 다음과 유사한 결과를 출력합니다.
python:3.9-slim (debian 11.7)
=====================================
Total: 123 (UNKNOWN: 0, LOW: 45, MEDIUM: 52, HIGH: 24, CRITICAL: 2)
+------------------+---------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+------------------+---------------------+----------+-------------------+---------------+---------------------------------------+
| libssl1.1 | CVE-2023-5678 | CRITICAL | 1.1.1w-0+deb11u1 | 1.1.1w-0+deb11u2 | OpenSSL: X.509 Email Address ... |
| openssl | CVE-2023-6129 | HIGH | 1.1.1w-0+deb11u1 | 1.1.1w-0+deb11u2 | OpenSSL: POLY1305 MAC implementation... |
+------------------+---------------------+----------+-------------------+---------------+---------------------------------------+
출력에는 다음과 같은 핵심 정보가 포함됩니다.
- 취약점 총계: 심각도별 분류 (UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL)
- 취약점 상세 표: 각 취약점의 라이브러리명, CVE ID, 심각도, 현재 버전, 수정 버전, 취약점 설명
고위험 및 심각 취약점만 출력
실무에서는 주로 고위험(High) 및 심각(Critical) 취약점에 더 관심을 가지게 됩니다. --severity 파라미터로 필터링할 수 있습니다.
trivy image --severity HIGH,CRITICAL python:3.9-slim
JSON 형식으로 출력 (자동화 처리에 편리)
trivy image --format json python:3.9-slim > results.json
핵심 기능 상세 설명
1. 파일 시스템 스캔
컨테이너 이미지 외에도 Trivy는 로컬 파일 시스템을 스캔하여 프로젝트 의존성의 취약점을 찾을 수 있습니다. 이는 개발 초기 단계에서 보안 문제를 발견하는 데 매우 유용합니다.
# 현재 디렉토리 스캔
trivy fs .
# 지정된 디렉토리 스캔
trivy fs /path/to/project
# 특정 언어의 의존성만 스캔
trivy fs --scanners vuln --language python /path/to/project
Trivy가 지원하는 언어: Python, Node.js, Java, Go, Ruby, PHP, .NET, Rust 등 주요 프로그래밍 언어.
2. Git 저장소 스캔
Trivy는 원격 Git 저장소를 직접 스캔할 수 있어 로컬에 클론할 필요가 없습니다.
# 공개 GitHub 저장소 스캔
trivy repo https://github.com/aquasecurity/trivy
# 특정 브랜치 스캔
trivy repo https://github.com/aquasecurity/trivy@main
서드파티 오픈소스 프로젝트의 보안성을 감사할 때 매우 편리합니다.
3. Kubernetes 구성 스캔
Kubernetes 구성 오류는 보안 사고의 주요 원인 중 하나입니다. Trivy는 Kubernetes YAML 파일이 보안 모범 사례를 준수하는지 확인할 수 있습니다.
# 단일 YAML 파일 스캔
trivy config deployment.yaml
# 디렉토리 내 모든 구성 파일 스캔
trivy config ./k8s-manifests/
Trivy는 다음과 같은 문제를 탐지합니다.
- 컨테이너가 root 사용자로 실행됨
- 리소스 제한(CPU/메모리) 미설정
latest태그 사용- 특권 모드 활성화
- 환경 변수에 하드코딩된 민감 정보
출력 예시:
k8s-manifests/deployment.yaml
=============================
Tests: 15 (SUCCESSES: 12, FAILURES: 3, EXCEPTIONS: 0)
Failures: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 1, CRITICAL: 0)
+-----------+------------+-----------------+----------+---------------------------------------+
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
+-----------+------------+-----------------+----------+---------------------------------------+
| Kubernetes| KSV012 | Image Tag | MEDIUM | Container 'app' uses 'latest' tag |
| Kubernetes| KSV001 | Privileged | HIGH | Container 'app' runs in privileged mode|
+-----------+------------+-----------------+----------+---------------------------------------+
4. SBOM (소프트웨어 자재 명세서) 생성
SBOM은 소프트웨어 공급망 보안의 중요한 구성 요소입니다. Trivy는 표준 형식의 SBOM을 생성할 수 있습니다.
# SPDX 형식의 SBOM 생성
trivy image --format spdx-json python:3.9-slim > sbom.spdx.json
# CycloneDX 형식의 SBOM 생성
trivy image --format cyclonedx python:3.9-slim > sbom.cyclonedx.xml
생성된 SBOM은 규정 준수 감사, 취약점 영향 분석 등에 활용할 수 있습니다.
5. 민감 정보 노출 탐지
Trivy는 코드에 하드코딩된 민감 정보(API 키, 비밀번호, 토큰 등)가 포함되어 있는지 스캔할 수 있습니다.
trivy fs --scanners secret ./my-project
Trivy에는 다양한 민감 정보 탐지 규칙이 내장되어 있습니다.
- AWS Access Key
- GitHub Token
- Slack Webhook URL
- Private Key
- Database Connection String
CI/CD 통합 실전
Trivy를 CI/CD 파이프라인에 통합하는 것은 '보안 좌측 이동(Shift Left)'을 실현하는 핵심 단계입니다. 다음은 주요 플랫폼별 통합 예시입니다.
GitHub Actions
프로젝트 루트에 .github/workflows/trivy.yml을 생성합니다.
name: Trivy Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'python:3.9-slim'
format: 'table'
severity: 'CRITICAL,HIGH'
exit-code: '1' # 고위험 취약점 발견 시 실패 처리
이 워크플로우는 푸시나 PR이 있을 때마다 지정된 컨테이너 이미지를 자동으로 스캔하며, 고위험 또는 심각 취약점이 발견되면 CI가 실패합니다.
GitLab CI
.gitlab-ci.yml에 다음을 추가합니다.
trivy-scan:
image:
name: aquasec/trivy:latest
entrypoint: [""]
script:
- trivy fs --exit-code 1 --severity HIGH,CRITICAL .
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
Jenkins Pipeline
pipeline {
agent any
stages {
stage('Security Scan') {
steps {
sh '''
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --exit-code 1 --severity HIGH,CRITICAL \
my-app:latest
'''
}
}
}
}
고급 사용법
1. 특정 취약점 무시
때로는 특정 취약점이 사용자의 환경에서 악용될 수 없는 경우가 있습니다. 이럴 때 .trivyignore 파일을 만들어 무시할 수 있습니다.
# .trivyignore
CVE-2023-1234
CVE-2023-5678
또는 --ignorefile 파라미터로 사용자 정의 무시 파일을 지정할 수 있습니다.
trivy image --ignorefile .trivyignore python:3.9-slim
2. 취약점 데이터베이스 캐싱
Trivy는 기본적으로 스캔할 때마다 취약점 데이터베이스를 업데이트합니다. CI/CD 환경에서는 추가 네트워크 오버헤드가 발생할 수 있으므로 캐시를 사용하여 속도를 높일 수 있습니다.
# 최초 스캔 시 데이터베이스만 다운로드
trivy image --download-db-only
# 이후 스캔은 로컬 캐시 사용
trivy image --skip-db-update python:3.9-slim
GitHub Actions에서는 actions/cache를 사용하여 데이터베이스를 영구 저장할 수 있습니다.
- name: Cache Trivy DB
uses: actions/cache@v3
with:
path: ~/.cache/trivy
key: trivy-db-${{ hashFiles('~/.cache/trivy/db/trivy.db') }}
restore-keys: trivy-db-
3. 사용자 정의 보고서 템플릿
Trivy는 Go 템플릿을 사용하여 출력 형식을 사용자 정의할 수 있습니다.
trivy image --format template --template "@contrib/html.tpl" python:3.9-slim > report.html
Trivy에 내장된 템플릿:
@contrib/html.tpl: HTML 보고서@contrib/junit.tpl: JUnit XML 형식 (CI/CD에 적합)@contrib/sarif.tpl: SARIF 형식 (GitHub Code Scanning에 적합)
4. Trivy Operator와 통합 (Kubernetes)
실행 중인 Kubernetes 클러스터의 경우 Trivy Operator를 배포하여 클러스터 내 보안 위험을 지속적으로 모니터링할 수 있습니다.
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm install trivy-operator aqua/trivy-operator --namespace trivy-system --create-namespace
Trivy Operator는 클러스터 내 워크로드를 자동으로 스캔하고 결과를 Kubernetes CRD로 저장합니다. Dashboard에서 확인하거나 API로 조회할 수 있습니다.
자주 묻는 문제 해결
문제 1: 스캔 속도가 느림
원인: 최초 스캔 시 취약점 데이터베이스(약 100-200MB)를 다운로드해야 하기 때문입니다.
해결 방법: --skip-db-update로 데이터베이스 업데이트를 건너뛰거나, 사전에 데이터베이스를 다운로드합니다.
trivy image --download-db-only
trivy image --skip-db-update python:3.9-slim
문제 2: 오탐(False Positive)이 너무 많음
원인: Trivy의 취약점 데이터베이스에는 사용자 환경에서 악용될 수 없는 취약점이 포함될 수 있습니다.
해결 방법: .trivyignore 파일로 알려진 오탐을 무시하거나, --severity 파라미터를 조정하여 고위험 취약점만 집중합니다.
문제 3: 프라이빗 이미지 스캔 실패
원인: Trivy가 인증이 필요한 프라이빗 이미지 레지스트리에 접근할 수 없습니다.
해결 방법: 환경 변수를 설정하거나 --registry-token 파라미터를 사용합니다.
export TRIVY_USERNAME=myuser
export TRIVY_PASSWORD=mypassword
trivy image registry.example.com/my-private-image:latest
문제 4: 메모리 부족
원인: 대형 이미지나 파일 시스템을 스캔할 때 많은 메모리를 소비할 수 있습니다.
해결 방법: 컨테이너의 메모리 제한을 늘리거나, --light 모드를 사용하여 메모리 사용량을 줄입니다.
trivy image --light python:3.9-slim
요약
Trivy는 기능이 풍부하면서도 사용하기 쉬운 오픈소스 보안 스캔 도구입니다. 그 핵심 가치는 다음과 같습니다.
- 포괄성: 다양한 스캔 대상과 탐지 유형을 지원하여 코드부터 프로덕션까지 전체 보안 요구사항을 커버합니다.
- 사용 편의성: 간단한 CLI 인터페이스, 풍부한 문서 및 커뮤니티 지원
- 통합 친화성: 주요 CI/CD 플랫폼 및 Kubernetes를 기본 지원
- 뛰어난 성능: Go 언어 구현으로 빠른 시작과 낮은 리소스 사용량
보안을 중시하는 모든 개발 팀에게 Trivy를日常 개발 프로세스에 포함시키는 것은 현명한 선택입니다. 초기 단계에서 보안 문제를 발견하고 수정하여 프로덕션 환경의 보안 위험을 줄일 수 있습니다.
다음 단계 제안:
- 로컬 개발 환경에 Trivy를 설치하고 몇 가지 자주 사용하는 컨테이너 이미지를 스캔해 보세요.
- Trivy를 CI/CD 파이프라인에 통합하고 적절한 보안 임계값을 설정하세요.
- 스캔 결과를 정기적으로 검토하고 취약점 수정 워크플로우를 구축하세요.
- Trivy Operator를 탐색하여 Kubernetes 클러스터에 지속적인 보안 모니터링을 추가하세요.
Trivy의 공식 문서는 https://trivy.dev에서, GitHub 저장소는 https://github.com/aquasecurity/trivy에서 확인할 수 있습니다. 문제가 발생하면 이 두 곳에서 상세한 문서와 커뮤니티 지원을 찾을 수 있습니다.
관련 글: