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는 다양한 통합 옵션을 제공합니다.

4. 빠른 속도, 낮은 리소스 사용량

Trivy는 Go 언어로 작성되어 시작 속도가 빠르고 메모리 사용량이 낮아 CI/CD 파이프라인에서 자주 실행하기에 적합합니다.

Trivy 설치

Trivy는 다양한 설치 방식을 지원합니다. 가장 일반적인 방법들은 다음과 같습니다.

방법 1: Homebrew 사용 (macOS/Linux)

BASH
brew install trivy

방법 2: Docker 사용

BASH
docker run aquasec/trivy --version

방법 3: 바이너리 파일 다운로드

GitHub Releases에서 해당 플랫폼의 바이너리 파일을 다운로드합니다.

BASH
# 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 배포판)

BASH
# 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

설치 확인

BASH
trivy --version
# 출력 예시: Version: 0.50.0

빠르게 시작하기: 첫 번째 컨테이너 이미지 스캔

간단한 예제부터 시작해 보겠습니다. 공개 Docker 이미지를 스캔해서 Trivy가 무엇을 발견하는지 확인해 봅시다.

Python 공식 이미지 스캔

BASH
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 파라미터로 필터링할 수 있습니다.

BASH
trivy image --severity HIGH,CRITICAL python:3.9-slim

JSON 형식으로 출력 (자동화 처리에 편리)

BASH
trivy image --format json python:3.9-slim > results.json

핵심 기능 상세 설명

1. 파일 시스템 스캔

컨테이너 이미지 외에도 Trivy는 로컬 파일 시스템을 스캔하여 프로젝트 의존성의 취약점을 찾을 수 있습니다. 이는 개발 초기 단계에서 보안 문제를 발견하는 데 매우 유용합니다.

BASH
# 현재 디렉토리 스캔
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 저장소를 직접 스캔할 수 있어 로컬에 클론할 필요가 없습니다.

BASH
# 공개 GitHub 저장소 스캔
trivy repo https://github.com/aquasecurity/trivy

# 특정 브랜치 스캔
trivy repo https://github.com/aquasecurity/trivy@main

서드파티 오픈소스 프로젝트의 보안성을 감사할 때 매우 편리합니다.

3. Kubernetes 구성 스캔

Kubernetes 구성 오류는 보안 사고의 주요 원인 중 하나입니다. Trivy는 Kubernetes YAML 파일이 보안 모범 사례를 준수하는지 확인할 수 있습니다.

BASH
# 단일 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을 생성할 수 있습니다.

BASH
# 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 키, 비밀번호, 토큰 등)가 포함되어 있는지 스캔할 수 있습니다.

BASH
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을 생성합니다.

YAML
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에 다음을 추가합니다.

YAML
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

GROOVY
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 파라미터로 사용자 정의 무시 파일을 지정할 수 있습니다.

BASH
trivy image --ignorefile .trivyignore python:3.9-slim

2. 취약점 데이터베이스 캐싱

Trivy는 기본적으로 스캔할 때마다 취약점 데이터베이스를 업데이트합니다. CI/CD 환경에서는 추가 네트워크 오버헤드가 발생할 수 있으므로 캐시를 사용하여 속도를 높일 수 있습니다.

BASH
# 최초 스캔 시 데이터베이스만 다운로드
trivy image --download-db-only

# 이후 스캔은 로컬 캐시 사용
trivy image --skip-db-update python:3.9-slim

GitHub Actions에서는 actions/cache를 사용하여 데이터베이스를 영구 저장할 수 있습니다.

YAML
- 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 템플릿을 사용하여 출력 형식을 사용자 정의할 수 있습니다.

BASH
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를 배포하여 클러스터 내 보안 위험을 지속적으로 모니터링할 수 있습니다.

BASH
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로 데이터베이스 업데이트를 건너뛰거나, 사전에 데이터베이스를 다운로드합니다.

BASH
trivy image --download-db-only
trivy image --skip-db-update python:3.9-slim

문제 2: 오탐(False Positive)이 너무 많음

원인: Trivy의 취약점 데이터베이스에는 사용자 환경에서 악용될 수 없는 취약점이 포함될 수 있습니다.

해결 방법: .trivyignore 파일로 알려진 오탐을 무시하거나, --severity 파라미터를 조정하여 고위험 취약점만 집중합니다.

문제 3: 프라이빗 이미지 스캔 실패

원인: Trivy가 인증이 필요한 프라이빗 이미지 레지스트리에 접근할 수 없습니다.

해결 방법: 환경 변수를 설정하거나 --registry-token 파라미터를 사용합니다.

BASH
export TRIVY_USERNAME=myuser
export TRIVY_PASSWORD=mypassword
trivy image registry.example.com/my-private-image:latest

문제 4: 메모리 부족

원인: 대형 이미지나 파일 시스템을 스캔할 때 많은 메모리를 소비할 수 있습니다.

해결 방법: 컨테이너의 메모리 제한을 늘리거나, --light 모드를 사용하여 메모리 사용량을 줄입니다.

BASH
trivy image --light python:3.9-slim

요약

Trivy는 기능이 풍부하면서도 사용하기 쉬운 오픈소스 보안 스캔 도구입니다. 그 핵심 가치는 다음과 같습니다.

  1. 포괄성: 다양한 스캔 대상과 탐지 유형을 지원하여 코드부터 프로덕션까지 전체 보안 요구사항을 커버합니다.
  2. 사용 편의성: 간단한 CLI 인터페이스, 풍부한 문서 및 커뮤니티 지원
  3. 통합 친화성: 주요 CI/CD 플랫폼 및 Kubernetes를 기본 지원
  4. 뛰어난 성능: Go 언어 구현으로 빠른 시작과 낮은 리소스 사용량

보안을 중시하는 모든 개발 팀에게 Trivy를日常 개발 프로세스에 포함시키는 것은 현명한 선택입니다. 초기 단계에서 보안 문제를 발견하고 수정하여 프로덕션 환경의 보안 위험을 줄일 수 있습니다.

다음 단계 제안:

  1. 로컬 개발 환경에 Trivy를 설치하고 몇 가지 자주 사용하는 컨테이너 이미지를 스캔해 보세요.
  2. Trivy를 CI/CD 파이프라인에 통합하고 적절한 보안 임계값을 설정하세요.
  3. 스캔 결과를 정기적으로 검토하고 취약점 수정 워크플로우를 구축하세요.
  4. Trivy Operator를 탐색하여 Kubernetes 클러스터에 지속적인 보안 모니터링을 추가하세요.

Trivy의 공식 문서는 https://trivy.dev에서, GitHub 저장소는 https://github.com/aquasecurity/trivy에서 확인할 수 있습니다. 문제가 발생하면 이 두 곳에서 상세한 문서와 커뮤니티 지원을 찾을 수 있습니다.


관련 글: