오픈소스 도구를 활용한 SBOM 생성

범용 오픈소스 도구를 활용하여 환경별로 SBOM을 생성하는 방법을 안내합니다.

    Docker만 설치되어 있으면 BomLens 하나로 소스코드, 컨테이너 이미지, 서버 rootfs, 실행 파일, 펌웨어를 모두 스캔할 수 있습니다. 아래 오픈소스 도구를 개별적으로 설치하고 조합하는 대신 먼저 검토해 보시기 바랍니다.

    도구 선택 가이드

    graph TD
        A{{"공급 소프트웨어 분류"}}
    
        subgraph G1["소프트웨어 공급"]
          direction LR
          T1["소스코드·앱<br>(예: OSS/BSS, 관리 포털, 미들웨어)"]
          T2["실행 파일·라이브러리<br>(예: .jar, .dll, .so)"]
          T3["OS 없는 펌웨어<br>(예: 베어메탈·RTOS 단말)"]
        end
    
        subgraph G2["OS(예: Linux) 포함 공급"]
          direction LR
          T4["컨테이너 이미지<br>(예: CNF, 컨테이너형 네트워크 기능)"]
          T5["서버·VM 이미지<br>(예: VNF, 서버 어플라이언스)"]
          T6["OS 내장 펌웨어<br>(예: 기지국, 라우터, OLT/ONT, 셋톱박스)"]
        end
    
        %% 좌측: 소스코드 스캔 서브 박스 구조
        subgraph M1["소스코드 스캔"]
          M1_Sub["BomLens 또는 cdxgen"]
        end
    
        %% 우측: 소스코드 + OS 이미지 스캔 서브 박스 구조 (세로 배치)
        subgraph M2["소스코드 + OS 이미지 스캔"]
          direction TB
          M2_Top["OS (예: Linux) 스캔<br>(BomLens 또는 Syft·Trivy)"]
          M2_Bottom["소스코드 스캔<br>(BomLens 또는 cdxgen)"]
        end
    
        A --> G1
        A --> G2
        
        %% 그룹 박스 경계로만 연결 (박스당 화살표 1개)
        G1 --> M1
        G2 --> M2
        
        %% 그룹 박스에서 다음 단계로 연결
        M1 --> P(["SBOM 제출"])
        M2 --> P
    
        classDef start fill:#F2F2F2,stroke:#171717,color:#171717,stroke-width:1.5px
        classDef typebox fill:#ffffff,stroke:#c8c8c8,color:#171717,stroke-width:1px
        classDef submit fill:#F2F2F2,stroke:#171717,color:#171717,stroke-width:1.5px
        
        %% 내부 단일 박스용 흰색 스타일 정의 (좌/우 테두리 색상 구분)
        classDef subwhite_left fill:#ffffff,stroke:#00A651,color:#171717,stroke-width:1px
        classDef subwhite_right fill:#ffffff,stroke:#68127A,color:#171717,stroke-width:1px
    
        class A start
        class T1,T2,T3,T4,T5,T6 typebox
        class M1_Sub subwhite_left
        class M2_Top,M2_Bottom subwhite_right
        class P submit
    
        style G1 fill:#F1FAF5,stroke:#00A651,stroke-width:1px,color:#0A5A32
        style G2 fill:#FAF4FB,stroke:#68127A,stroke-width:1px,color:#4A0D57
        
        %% 외곽 박스 스타일 (배경색 및 테두리 유지)
        style M1 fill:#D9F0E4,stroke:#00A651,stroke-width:1px,color:#0A5A32
        style M2 fill:#EEDCF3,stroke:#68127A,stroke-width:1px,color:#4A0D57

    소스코드·앱, 실행 파일이나 라이브러리, OS 없는 펌웨어는 모두 자기가 개발한 소스코드를 BomLens 또는 cdxgen으로 스캔합니다. 완성된 바이너리를 그대로 스캔하면 패키지 매니저 메타데이터가 없어 purl이 누락되고 반려됩니다.

    OS나 베이스 이미지를 포함해 공급하는 경우(컨테이너 이미지, 서버, OS 내장 펌웨어)는 두 층으로 나눠 각각 스캔해 함께 제출합니다. OS 층은 납품되는 상태의 이미지나 rootfs를 BomLens 또는 Syft·Trivy로, 소스코드(앱 층)는 BomLens 또는 cdxgen으로 스캔합니다. 층별 명령과 파일 이름 규칙은 아래 서버 납품에 있습니다.

    타사가 제조한 상용 소프트웨어나 완제품을 공급해 소스코드에 접근할 수 없는 경우는 스캔 대신 제조사로부터 SBOM을 받아 제출합니다. 상용 소프트웨어 공급을 참고하세요.

    주요 도구 안내

    BomLens (SK텔레콤 제공)

    SK텔레콤이 만든 SBOM 생성 도구입니다. 소스코드, 컨테이너 이미지, 서버 rootfs, 실행 파일, 펌웨어를 아래 오픈소스 도구들을 개별적으로 설치하지 않고 하나의 Docker 컨테이너로 스캔합니다. 최상위 컴포넌트 이름 자동 기입, 제출 전 자체 검증(적합성 리포트) 등 SK텔레콤 제출 기준에 맞춘 기능이 포함되어 있습니다.

    제출 전에는 --conformance-profile skt-submission 옵션으로 SK텔레콤 심사 기준(PURL 포함률 100% 등)을 미리 확인하시기 바랍니다. 자세한 내용은 검증 체크리스트를 참고하세요. 스캔 중 오류가 나거나 결과가 이상하면 자주 발생하는 반려 사유에서 비슷한 사례를 먼저 확인하시기 바랍니다.

    BomLens로 처리되지 않는 경우이거나 오픈소스 도구를 직접 조합해서 쓰려면 아래를 참고하시기 바랍니다.

    cdxgen (소스코드 분석)

    Java, Python, Node.js, Go 등 다양한 언어 프로젝트를 자동 분석하여 CycloneDX 형식의 SBOM을 생성합니다.

    cdxgen은 lockfile이나 매니페스트를 정적으로 해석합니다. 정확한 결과를 얻으려면 의존성이 설치되거나 해결된 상태(lockfile이 있거나 빌드한 뒤)에서 실행하시기 바랍니다. 의존성이 해결되지 않은 순수 소스만 스캔하면 일부 컴포넌트나 purl이 누락될 수 있습니다.

    Syft (컨테이너 이미지 및 바이너리 분석)

    빌드된 컨테이너 이미지나 패키지 매니저 메타데이터가 포함된 빌드 산출물을 분석하여 OS 패키지와 애플리케이션 라이브러리를 모두 식별합니다. CycloneDX 및 SPDX 형식을 지원합니다.

    Trivy (컨테이너 이미지 분석)

    컨테이너 이미지 분석과 취약점 스캔을 함께 수행할 수 있는 올인원 도구입니다.

    언어별 전용 플러그인

    빌드 도구 플러그인을 사용하면 더 정확한 의존성 정보를 추출할 수 있습니다.

    언어/빌드 도구플러그인/도구공식 문서
    Java (Maven)cyclonedx-maven-plugin링크
    Java (Gradle)cyclonedx-gradle-plugin링크
    Pythoncyclonedx-bom링크
    Node.js@cyclonedx/cyclonedx-npm링크
    Gocyclonedx-gomod링크

    서버 납품

    OS나 베이스 이미지를 포함해 공급하는 경우(서버, 컨테이너 이미지, OS 내장 펌웨어)에 해당합니다. 두 층을 각각 만들어 함께 제출합니다.

    층대상누락 시 증상
    OS운영체제와 설치된 패키지 전체 (예: RHEL과 rpm 데이터베이스의 모든 패키지)OS 취약점 누락
    애플리케이션납품 애플리케이션과 패키지 매니저 의존성(직접·전이)앱 의존성 누락

    두 층으로 나눠 스캔

    OS 층은 서버의 rootfs(추출한 루트 파일시스템)나 그 컨테이너 이미지를 대상으로 합니다. 패키지 데이터베이스(rpm/dpkg/apk)를 읽어 설치된 패키지를 모두 실제 purl(pkg:rpm/...)로 식별합니다. 대상은 받아온 원본 베이스가 아니라 빌드가 끝나 납품되는 상태여야 합니다. 빌드 과정에서 설치한 OS 패키지까지 포함해야 하기 때문입니다. 설치 파일만 풀어 놓고 패키지 데이터베이스가 없는 폴더를 스캔하면 purl이 비어 반려됩니다.

    대상은 rootfs의 루트여야 합니다. 하위 디렉터리만 지정하면 패키지 데이터베이스는 읽혀도 배포판이 판정되지 않습니다. Syft는 대상 안의 /etc/os-release로 배포판을 정하고 그 값을 purl에 넣습니다. 정상이라면 pkg:rpm/rhel/bind@9.11.36-16.el8_10.6처럼 타입과 패키지 이름 사이에 배포판이 들어갑니다. 이 자리가 비면 형식 검증은 통과하지만 SK텔레콤 시스템이 패키지를 식별하지 못해 OS 패키지가 전량 미매칭으로 반려됩니다. 스캔 전에 대상 안에 이 파일이 있는지 확인하시기 바랍니다.

    # 대상 안에 배포판 정보가 있는지 먼저 확인
    cat /path/to/server-rootfs/etc/os-release
    
    # BomLens로 (rootfs 디렉터리를 그대로 대상으로 지정, 최상위 컴포넌트 이름도 자동 기입)
    ./scan-sbom.sh --project myserver-os --version 1.0.0 --target /path/to/server-rootfs --generate-only
    
    # 오픈소스 도구를 직접 쓰려면: rootfs 디렉터리를 대상으로
    syft dir:/path/to/server-rootfs -o cyclonedx-json=myserver-os_1.0.0_bom.json
    
    # 서버가 컨테이너 이미지로 패키징돼 있다면(BomLens는 이미지 이름을 그대로 대상으로 지정)
    ./scan-sbom.sh --project myserver-os --version 1.0.0 --target myserver:7 --generate-only
    syft myserver:7 -o cyclonedx-json=myserver-os_1.0.0_bom.json
    

    애플리케이션 층은 빌드를 마친 뒤 애플리케이션 소스를 스캔합니다. 패키지 매니저(Maven, npm, pip, Go modules, Conan 등)를 쓰면 전이 의존성까지 자동으로 해석됩니다.

    cd /path/to/app-source
    cdxgen -o myserver-app_1.0.0_bom.json
    
    # 또는 BomLens로
    ./scan-sbom.sh --project myserver-app --version 1.0.0 --target /path/to/app-source --generate-only
    

    OS 층 스캔에 파이썬이나 Node.js처럼 파일로 설치된 의존성이 함께 잡히기도 합니다. 그래도 애플리케이션 층은 따로 만드시기 바랍니다. C/C++처럼 소스에 라이브러리를 포함하는 방식은 OS 층 스캔으로 전혀 식별되지 않습니다.

    OS 내장 펌웨어(기지국, 라우터 등)

    기지국, 라우터, OLT/ONT, 셋톱박스처럼 OS를 내장한 펌웨어도 위와 같은 두 층 구조입니다. OS 층은 펌웨어 이미지 파일 전체를 대상으로 BomLens의 --firmware 옵션을 사용합니다.

    ./scan-sbom.sh --project mydevice-os --version 1.0.0 --target /path/to/firmware.bin --firmware --generate-only
    

    임베디드 리눅스 위에서 자체 애플리케이션이 별도로 동작한다면, 그 애플리케이션 소스는 위의 “애플리케이션 층” 스캔을 동일하게 적용합니다. 펌웨어 이미지 안에 애플리케이션까지 모두 포함되어 있다면 OS 층 스캔 하나로 끝날 수도 있습니다.

    층별로 제출

    층별 SBOM은 합치지 않고 그대로 제출합니다. SK텔레콤 시스템은 SBOM 문서 하나를 스캔 단위로 등록하고, 같은 제품 버전에 등록된 문서들을 합쳐 하나의 목록으로 봅니다. 층별로 포맷이 달라도 됩니다.

    파일마다 이름이 달라야 하고, 재제출할 때는 같은 이름을 그대로 써야 합니다. SBOM 문서 이름이 스캔의 정체성이라, 이름이 바뀌면 이전 제출분이 지워지지 않고 남아 이미 조치한 취약점이 계속 집계됩니다. 층을 나타내는 접미어는 재제출해도 바뀌지 않으므로 안전하지만, 제출 회차를 나타내는 순번은 붙이지 마시기 바랍니다.

    층파일 이름 예
    OSmyserver-os_1.0.0_bom.json
    애플리케이션myserver-app_1.0.0_bom.json

    층 구분은 --project 값에 붙이는 접미어(-os, -app)로 합니다. BomLens는 {프로젝트 이름}_{버전}_bom.json을 자동으로 만들므로, 두 층을 모두 만들 때는 --project를 층마다 다르게 주십시오(예: myserver-os, myserver-app). 같은 이름으로 두 번 실행하면 파일 이름이 같아져 나중에 실행한 쪽이 앞선 산출물을 덮어씁니다. cdxgen이나 Syft로 직접 만들 때도 출력 파일 이름을 같은 규칙(-o myserver-app_1.0.0_bom.json 등)으로 맞추시기 바랍니다.

    최상위 컴포넌트 이름(CycloneDX는 metadata.component.name, SPDX는 DocumentName)도 파일 이름 앞부분({이름}_{버전})과 같은 값으로 기재합니다. BomLens는 --project/--version 값을 이 필드에 자동으로 넣으므로 따로 손댈 필요가 없습니다. 이 값이 제출 건 전체에서 고유해야 하는 식별자입니다. 자세한 내용은 제출 요구사항의 메타데이터 절을 참고하세요.

    클러스터처럼 노드가 여럿인 제품을 어떤 단위로 묶어 내는지는 제출 절차의 제출 단위 절을 참고하세요.

    공통 주의사항

    도구를 사용하기 전 아래 사항을 확인하시기 바랍니다.

    • 전이적 의존성 포함 여부: 빌드(패키지 설치)가 완료된 상태에서 생성해야 전이적 의존성까지 포함됩니다. 의존성 누락은 반려 사유가 되며, 언어별 빌드 선행 명령은 제출 요구사항의 의존성 범위 절을 참고하세요.
    • PURL 포함 여부: 생성된 SBOM에 모든 컴포넌트의 purl 필드가 포함되어 있는지 확인합니다. SK텔레콤 시스템은 PURL을 기반으로 취약점을 매핑합니다. 확인 명령과 재생성 절차는 검증 체크리스트를 참고하세요.
    • 출력 포맷: CycloneDX JSON 형식을 권장합니다. (-o cyclonedx-json 또는 동등한 옵션 사용)
    • 프로젝트 정보: 메타데이터에 납품 프로젝트의 이름과 버전이 정확히 기입되었는지 확인합니다.

    관련 문서