공급망 보안 (Supply Chain Security)
리눅스 커널 공급망의 무결성(Integrity)을 보장하는 기술과 프로세스(Process)를 종합합니다. 커밋 서명, 태그 검증, SLSA 프레임워크, 재현 가능 빌드, 커널 모듈(Kernel Module) 서명, 펌웨어(Firmware) 서명 검증(Signature Verification), SBOM, 취약점(Vulnerability) 공개 프로세스까지 다룹니다.
선행 지식: 이 문서는 커널 빌드 과정과 기본적인 보안 개념을 이해하고 있다고 가정합니다. 커널 보안 개요와 빌드 시스템(Build System) 문서를 먼저 읽으면 도움이 됩니다.
일상 비유: 공급망 보안은 식품 유통 과정의 추적 시스템과 비슷합니다. 농장에서 식탁까지 모든 단계에 원산지 표시(서명), 유통기한 확인(검증), 이력 관리(투명성 로그)가 있어야 안전한 것처럼, 소스 코드에서 실행 바이너리까지 매 단계의 무결성을 보장해야 합니다.
핵심 요약
| 보안 계층 | 대표 기술 | 검증 대상 | 도입 난이도 |
|---|---|---|---|
| 소스 코드 | GPG/SSH 커밋 서명, 태그 서명 | 개발자 신원, 코드 무결성 | 낮음 |
| 빌드 프로세스 | 재현 가능 빌드, SLSA, 빌드 격리(Isolation) | 빌드 산출물의 결정론성 | 중간 |
| 바이너리 배포 | MODULE_SIG, 펌웨어 서명, Secure Boot | 커널/모듈/펌웨어 무결성 | 중간 |
| 메타데이터 | SBOM (SPDX, CycloneDX), SLSA Provenance | 구성 요소 목록, 출처 증명 | 중간 |
| 투명성 | Sigstore, Rekor, in-toto, TUF | 서명 이력, 배포 무결성 | 높음 |
| 취약점 관리 | security@kernel.org, CVE, linux-distros@ | 보안 결함 대응 프로세스 | 프로세스 |
| 컴플라이언스 | EO 14028, EU CRA, NIST SSDF | 규제 준수 | 프로세스 |
- 공급망 공격은 소스 코드, 빌드 시스템, 배포 채널, 의존성 등 소프트웨어 생명주기 전반을 대상으로 합니다.
- 리눅스 커널은 GPG 태그 서명, 모듈 서명, Secure Boot 체인 등 다층 방어를 채택합니다.
- SLSA 프레임워크는 공급망 무결성을 4단계 성숙도 모델로 체계화합니다.
- 재현 가능 빌드(Reproducible Builds)는 동일 소스에서 동일 바이너리를 생성함을 보장합니다.
- SBOM은 소프트웨어 구성 요소 목록을 표준 포맷으로 제공하여 취약점 추적을 가능케 합니다.
커널 공급망 개요
리눅스 커널 공급망은 개발자의 로컬 커밋에서 시작하여, 서브시스템 메인테이너의 리뷰, Linus Torvalds의 최종 병합, kernel.org 배포, 배포판 패키징, 최종 사용자의 설치까지 이어지는 긴 체인입니다. 각 단계에서 무결성이 훼손되면 전체 생태계에 영향을 미칩니다.
공급망 단계별 위험도
소프트웨어 공급망은 단순한 선형 프로세스가 아니라, 각 단계가 서로 의존하는 복잡한 그래프(Graph) 구조입니다. 하나의 단계가 침해되면 하류(downstream) 전체에 영향을 미치므로, 각 단계의 위험도를 이해하고 적절한 방어를 배치해야 합니다.
| 공급망 단계 | 위험도 | 공격 성공 시 영향 | 탐지 난이도 | 방어 메커니즘 |
|---|---|---|---|---|
| 개발자 계정 | 높음 | 악성 코드 직접 커밋 | 중간 | 2FA, 하드웨어 키, 커밋 서명 |
| 코드 리뷰 | 중간 | 취약한 코드 승인 | 높음 | 다수 리뷰어, 자동화 분석 |
| 빌드 시스템 | 매우 높음 | 바이너리에 악성코드 삽입 | 매우 높음 | 밀폐 빌드, 재현성 검증 |
| 의존성 | 높음 | 간접적 악성코드 도입 | 높음 | 의존성 핀닝, 해시 검증, SBOM |
| 배포 채널 | 높음 | 변조된 패키지 배포 | 낮음 | 패키지 서명, TUF, 미러 검증 |
| 하드웨어 | 매우 높음 | 물리적 수준 백도어 | 매우 높음 | 공급업체 감사, 물리적 검증 |
공급망 공격 유형 분류
공급망 공격(Supply Chain Attack)은 소프트웨어의 개발, 빌드, 배포 과정에서 악의적인 코드나 변조를 삽입하는 공격 기법입니다. 리눅스 커널 생태계에서 발생할 수 있는 공격 유형을 체계적으로 분류합니다.
소스코드 수준 공격
소스코드 공격은 공급망의 최초 단계를 대상으로 합니다. 공격자가 악성 코드를 정상적인 기여처럼 위장하여 프로젝트에 삽입합니다.
| 공격 기법 | 설명 | 실제 사례 | 방어 수단 |
|---|---|---|---|
| 계정 탈취 | 메인테이너의 자격 증명을 도용하여 악성 커밋 푸시 | PHP 저장소 침해 (2021) | 2FA, 하드웨어 보안 키, GPG 커밋 서명 |
| 사회공학 패치 | 장기간 신뢰를 쌓은 후 악성 코드를 포함한 패치 제출 | XZ Utils 백도어 (2024) | 다수 리뷰어, 빌드 스크립트 감사 |
| 의도적 취약 코드 | 의도적으로 취약한 코드를 "수정"으로 위장하여 제출 | University of Minnesota (2021) | 엄격한 코드 리뷰, 기여자 이력 확인 |
| 유니코드 트릭 | Bidi 오버라이드(Override) 문자로 코드 흐름을 시각적으로 위장 | Trojan Source (2021) | 컴파일러 경고 활성화, 코드 스캐닝 |
| 타이포스쿼팅(Typosquatting) | 유사한 이름의 악성 패키지로 의존성 오류 유도 | npm/PyPI 다수 사례 | 의존성 잠금, 해시 검증 |
빌드 시스템 수준 공격
빌드 시스템 공격은 소스 코드는 정상이지만 빌드 과정에서 악성 코드를 삽입합니다. 이른바 "Thompson 공격"(Ken Thompson의 1984년 "Reflections on Trusting Trust" 연설)의 현대적 변형입니다.
| 공격 기법 | 설명 | 실제 사례 | 탐지 방법 |
|---|---|---|---|
| 빌드 환경 오염 | 빌드 서버에 침투하여 컴파일 과정에서 코드 삽입 | SolarWinds (2020) | 재현 가능 빌드, 빌드 로그 감사 |
| CI/CD 파이프라인 변조 | CI 스크립트를 수정하여 시크릿 유출 또는 바이너리 변조 | Codecov (2021) | 파이프라인 서명, 러너 격리 |
| 빌드 스크립트 조작 | Makefile/configure/m4 매크로에 악성 로직 숨김 | XZ Utils 빌드 스크립트 | 빌드 스크립트 diff 리뷰, 밀폐 빌드 |
| 컴파일러 백도어 | 컴파일러 자체에 특정 패턴 감지 시 악성 코드 삽입 | Thompson 공격 (이론) | 다중 컴파일러 교차 검증, 부트스트래핑 |
배포 채널 공격
배포 채널 공격은 정상적으로 빌드된 소프트웨어가 사용자에게 전달되는 과정을 대상으로 합니다.
- 미러 변조: 비공식 미러의 바이너리를 변조하여 악성 패키지 배포. PGP 서명 검증을 하지 않는 사용자가 피해 대상
- DNS 하이재킹(Hijacking): 패키지 저장소 도메인(Domain)을 탈취하여 악성 서버로 리다이렉트
- 업데이트 서버 침해: 공식 업데이트 인프라에 침투하여 악성 업데이트 배포 (예: NotPetya의 M.E.Doc 서버 침해)
- 롤백 공격: 이전 버전의 취약한 패키지를 최신인 것처럼 배포. TUF의 Timestamp 역할이 이를 방어
- 키 탈취: 패키지 서명 키를 도용하여 악성 패키지에 유효한 서명 부여
실제 사건 상세 분석
주요 공급망 공격 사건을 심층 분석하여 공격 기법, 탐지 과정, 교훈을 상세히 살펴봅니다.
실제 공급망 사고 사례
| 사건 | 연도 | 공격 벡터 | 영향 | 교훈 |
|---|---|---|---|---|
| kernel.org 침해 | 2011 | 서버 SSH 키 탈취 | git 인프라 일시 오프라인 | GPG 서명 덕분에 소스 무결성 확인 가능 |
| SolarWinds | 2020 | 빌드 시스템 침투 | 18,000+ 조직 영향 | 빌드 환경 격리, 출처 증명 필요 |
| Codecov | 2021 | CI 스크립트 변조 | 환경변수/시크릿 유출 | CI/CD 파이프라인(Pipeline) 무결성 검증 |
| University of Minnesota | 2021 | 의도적 취약 패치(Patch) 제출 | 해당 대학 전면 출입 금지 | 코드 리뷰 프로세스 강화, 기여자 신뢰 검증 |
| event-stream | 2018 | 메인테이너 권한 양도 후 악성 코드 삽입 | npm 패키지 200만+ 다운로드 감염 | 메인테이너 전환 시 감사, 의존성 모니터링 |
| XZ Utils 백도어 | 2024 | 장기간 사회공학 + 악성 빌드 스크립트 | sshd 인증 우회 시도 | 빌드 스크립트 검증, 메인테이너 번아웃 문제 |
| NotPetya (M.E.Doc) | 2017 | 업데이트 서버 침해 | 전 세계 100억+ 달러 피해 | 업데이트 채널 무결성, 코드 서명 검증 |
XZ Utils 백도어 (CVE-2024-3094) 상세 분석
XZ Utils 백도어는 2024년 3월 발견된, 오픈소스 공급망 공격의 가장 정교한 사례 중 하나입니다. 약 2년간의 사회공학(Social Engineering)을 통해 프로젝트의 공동 메인테이너 지위를 획득한 공격자가, 빌드 시스템을 통해 sshd에 인증 우회 백도어를 삽입했습니다.
공격 타임라인
2022.01 : "Jia Tan" 계정으로 XZ 프로젝트에 첫 기여 시작
2022.05 : 지속적인 유용한 패치 제출로 신뢰 구축
2022.09 : 소셜 압력 캠페인 시작 - 가짜 계정들이 원래 메인테이너에게
"새 메인테이너가 필요하다"고 압박
2023.01 : 공동 메인테이너 권한 획득 (커밋/릴리스 권한)
2023.06 : ifunc 관련 변경 시작 - 향후 백도어의 기반 코드
2024.02 : v5.6.0/5.6.1 릴리스에 백도어 삽입
- 바이너리 테스트 파일(bad-3-corrupt_lzma2.xz)에 암호화된 페이로드
- build-to-host.m4 매크로에 디코딩 로직 숨김
- ifunc resolver를 통해 sshd의 RSA_public_decrypt 후킹
2024.03.28: Andres Freund가 sshd 성능 이상으로 조사 중 발견
2024.03.29: oss-security 메일링 리스트에 공개
2024.03.30: CVE-2024-3094 할당, CVSS 10.0
기술적 메커니즘
# 백도어 삽입 경로 (재현 금지 - 분석 목적만)
# 1. tests/files/bad-3-corrupt_lzma2.xz 에 암호화된 셸코드 포함
# 2. build-to-host.m4 (autotools 매크로)에서 빌드 시 디코딩
# 3. liblzma에 악성 코드 링크
# 4. systemd를 통해 sshd가 liblzma 로드 → 후킹 활성화
# 영향받는 조건:
# - x86_64 Linux (glibc)
# - systemd로 sshd 관리 (sd_notify 링크로 liblzma 로드)
# - xz-utils 5.6.0 또는 5.6.1
# 탐지 방법
xz --version
# xz (XZ Utils) 5.6.0 또는 5.6.1 이면 위험
# liblzma 백도어 시그니처 확인
hexdump -C /usr/lib/x86_64-linux-gnu/liblzma.so.5 | \
grep -c "f3 0f 1e fa" # ifunc resolver 패턴
# 안전한 버전으로 다운그레이드
apt install xz-utils=5.4.1-0.2 # Debian 예시
교훈과 방어
- 메인테이너 번아웃: 단일 메인테이너가 장기간 프로젝트를 관리하면 사회공학에 취약. 공동 메인테이너 정책과 지원 체계 필요
- 빌드 스크립트 투명성: autotools/m4 매크로는 리뷰하기 어렵고 난독화 가능. 빌드 프로세스의 투명성 확보 필요
- 바이너리 테스트 파일: 테스트 데이터로 위장한 바이너리 blob은 코드 리뷰를 우회. 바이너리 파일에 대한 추가 감사 필요
- ifunc 메커니즘: GNU indirect function은 런타임에 함수를 교체할 수 있어 후킹에 악용 가능. 불필요한 ifunc 사용 제한 검토
- 성능 이상 탐지: Andres Freund가 sshd 로그인 지연(500ms)을 조사하다 발견. 성능 모니터링도 보안 탐지 수단이 될 수 있음
- 바이너리 분석: 릴리스 타르볼에 포함된 바이너리 파일(테스트 데이터 포함)은 자동화된 분석 파이프라인으로 정기 스캔 필요
- autotools 대안: 빌드 시스템을 meson, CMake 등 감사 용이한 도구로 전환하는 것도 장기적 대책
- 다중 리뷰어: 빌드 인프라 변경은 최소 2인 이상의 독립적 리뷰를 거쳐야 함
rpminspect으로 빌드 스크립트 변경을 추적하며, Debian은 빌드 로그에서 의심스러운 명령 패턴을 자동 검출하는 시스템을 개발 중입니다.
SolarWinds 사건 상세 분석
SolarWinds 공격(SUNBURST)은 2020년 12월 공개된, 역사상 가장 영향력 있는 공급망 공격 중 하나입니다. 공격자(APT29/Cozy Bear로 추정)가 SolarWinds의 빌드 시스템에 침투하여, Orion 소프트웨어의 업데이트에 백도어를 삽입했습니다.
공격 기법
| 단계 | 기법 | 상세 |
|---|---|---|
| 1. 초기 침투 | 자격 증명 탈취 | SolarWinds 직원의 Microsoft 365 계정 침해 |
| 2. 내부 이동 | 빌드 서버 접근 | Orion 빌드 파이프라인(TeamCity) 침투 |
| 3. 코드 삽입 | 빌드 프로세스 조작 | SolarWinds.Orion.Core.BusinessLayer.dll에 SUNBURST 삽입 |
| 4. 서명 | 정상 서명 | 변조된 DLL이 SolarWinds의 정식 코드 서명 인증서로 서명됨 |
| 5. 배포 | 정상 업데이트 채널 | 18,000+ 조직이 악성 업데이트를 자동 설치 |
| 6. C2 통신 | DNS 터널링 | avsvmcloud.com 도메인으로 DNS 기반 C2 통신 |
리눅스 커널 관점의 교훈
- 빌드 환경 격리: 리눅스 커널 빌드는 네트워크 차단된 밀폐(hermetic) 환경에서 수행해야 합니다
- 재현 가능 빌드: SolarWinds 공격은 재현 가능 빌드가 있었다면 탐지 가능. 동일 소스에서 다른 바이너리가 생성되는 것은 변조의 증거
- 코드 서명 ≠ 무결성: 코드 서명은 빌드 시스템이 신뢰할 수 있을 때만 의미 있음. 빌드 시스템 자체의 보호가 선행되어야 함
- SLSA 프레임워크: SLSA Level 3 이상의 Provenance가 있었다면 빌드 변조를 탐지할 수 있었음
Codecov 사건 분석
Codecov 사건(2021년 4월)은 CI/CD 파이프라인의 취약성을 보여줍니다. 공격자가 Codecov의 Docker 이미지 생성 과정의 취약점을 악용하여 Bash Uploader 스크립트를 변조했습니다.
# Codecov의 원래 Bash Uploader 사용 방식 (변조 전)
bash <(curl -s https://codecov.io/bash)
# 변조된 스크립트가 수행한 악의적 행위:
# 1. CI 환경의 모든 환경변수 수집 (API 토큰, 서명 키 등)
# 2. git remote URL 수집 (소스 저장소 정보)
# 3. 수집된 정보를 공격자 서버로 전송
# 교훈: CI 스크립트를 URL에서 직접 실행하지 말 것
# 대안 1: 핀닝된 버전 사용
curl -s https://codecov.io/bash -o codecov.sh
sha256sum codecov.sh # 해시 검증 후 사용
# 대안 2: 공식 GitHub Action 사용 (커밋 해시로 핀닝)
# uses: codecov/codecov-action@v3.1.4 # 태그 대신 해시 사용
event-stream 사건 분석
event-stream 사건(2018년)은 오픈소스 메인테이너 전환(succession)의 위험을 보여줍니다. 공격자 "right9ctrl"이 원래 메인테이너(Dominic Tarr)에게 접근하여 npm 패키지 퍼블리시 권한을 양도받았습니다.
| 단계 | 내용 |
|---|---|
| 1. 접근 | 원래 메인테이너에게 유지보수 인계를 제안. 메인테이너는 더 이상 사용하지 않는 패키지라 흔쾌히 수락 |
| 2. 신뢰 구축 | 몇 주간 정상적인 유지보수 커밋 수행 |
| 3. 악성 의존성 | flatmap-stream이라는 악성 패키지를 의존성으로 추가 |
| 4. 대상 지정 | Copay 비트코인 지갑 앱만 대상으로 하는 조건부 악성 코드 (특정 package.json 감지) |
| 5. 실행 | Copay 앱에서만 비트코인 개인키 탈취 시도 |
SLSA 프레임워크
SLSA(Supply-chain Levels for Software Artifacts, 발음: "salsa")는 Google이 주도하고 OpenSSF가 관리하는 공급망 보안 프레임워크입니다. 소프트웨어 산출물의 무결성을 4단계 성숙도 레벨로 정의합니다.
| SLSA 레벨 | 요구사항 | 리눅스 커널 적용 현황 |
|---|---|---|
| Level 1 | 빌드 프로세스 문서화, Provenance 메타데이터 존재 | kernel.org 타르볼 + PGP 서명으로 부분 충족 |
| Level 2 | 버전 관리된 소스 + 호스팅 빌드 서비스에서 Provenance 생성 | git 저장소 + 배포판 빌드 시스템 |
| Level 3 | 밀폐 빌드 + 비위조(non-forgeable) Provenance + 소스 검증 | 일부 배포판(Fedora, Debian) 진행 중 |
| Level 4 | 2인 리뷰 + 밀폐/재현 가능 빌드 + 의존성 전체 검증 | 목표 상태, 완전 달성 사례 아직 없음 |
SLSA Provenance 스키마
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [{
"name": "linux-6.8.tar.xz",
"digest": { "sha256": "abcdef1234..." }
}],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://kernel.org/build/v1",
"externalParameters": {
"source": "https://git.kernel.org/torvalds/linux.git",
"ref": "refs/tags/v6.8"
}
},
"runDetails": {
"builder": { "id": "https://kernel.org/builders/official" },
"metadata": {
"invocationId": "build-20240310-001",
"startedOn": "2024-03-10T08:00:00Z",
"finishedOn": "2024-03-10T09:30:00Z"
}
}
}
}
NIST SSDF (Secure Software Development Framework)
NIST SSDF(SP 800-218)는 미국 국립표준기술연구소(NIST)가 제정한 보안 소프트웨어 개발 프레임워크입니다. EO 14028에 의해 미국 연방 정부 조달 소프트웨어에 적용이 의무화되었습니다.
| SSDF 그룹 | 약어 | 핵심 활동 | 커널 프로젝트 현황 |
|---|---|---|---|
| 조직 준비 | PO | 보안 정책, 역할 정의, 도구 선정 | kernel.org 보안 정책 문서화, 메인테이너 역할 명시 |
| 소프트웨어 보호 | PS | 소스/빌드/배포 보호, 접근 통제 | GPG 서명, SSH 접근 통제, 코드 리뷰 의무 |
| 안전한 소프트웨어 생산 | PW | 보안 설계, 코드 리뷰, 테스트 | Coverity 스캔, 퍼저(syzkaller), 정적 분석 |
| 취약점 대응 | RV | 취약점 식별, 분석, 패치, 공개 | security@kernel.org, CNA 운영, stable 백포트 |
SLSA와 SSDF 비교
| 비교 항목 | SLSA | NIST SSDF |
|---|---|---|
| 초점 | 공급망 무결성 (빌드/배포) | 전체 소프트웨어 개발 생명주기 |
| 성숙도 모델 | 4단계 레벨 (L1-L4) | 관행(Practice) 기반 (레벨 없음) |
| 인증 | 자체 증명 / 제3자 감사 | 자체 증명 (연방 조달 시) |
| 기술적 깊이 | 빌드 Provenance 중심, 상세 기술 스펙 | 프로세스 중심, 기술 비특정 |
| 관할 | OpenSSF (자발적) | 미국 연방 (조달 시 의무) |
| 커널 적용성 | 빌드 파이프라인에 직접 적용 가능 | 개발 프로세스 전반에 가이드라인 역할 |
SLSA 빌드 검증 실습
# SLSA Provenance 검증 (slsa-verifier 사용)
# 1. slsa-verifier 설치
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest
# 2. GitHub Actions에서 생성된 Provenance 검증
slsa-verifier verify-artifact linux-6.8.tar.xz \
--provenance-path linux-6.8.tar.xz.intoto.jsonl \
--source-uri github.com/torvalds/linux \
--source-tag v6.8
# 3. Provenance 내용 확인
cat linux-6.8.tar.xz.intoto.jsonl | jq '.payload' | \
base64 -d | jq '.predicate.buildDefinition'
# 4. 커스텀 Provenance 생성 (커널 빌드용)
slsa-github-generator generate-provenance \
--artifact linux-6.8.tar.xz \
--source-uri https://git.kernel.org/torvalds/linux.git \
--builder-id https://kernel.org/builders/official \
--output linux-6.8.provenance.json
커밋 서명
커밋 서명은 공급망 최초 지점인 개발자의 기여를 암호학적으로 인증합니다. Git은 GPG와 SSH 두 가지 서명 백엔드를 지원합니다.
GPG 커밋 서명 설정
# GPG 키 생성 (ed25519 권장, RSA 4096도 가능)
gpg --full-generate-key
# 키 목록 확인
gpg --list-secret-keys --keyid-format=long
# Git에 서명 키 설정
git config --global user.signingkey ABCDEF1234567890
git config --global commit.gpgsign true
git config --global tag.gpgsign true
# 커밋 시 서명 확인
git log --show-signature -1
# GPG 공개키를 kernel.org에 등록
gpg --armor --export ABCDEF1234567890 | \
xclip -selection clipboard
SSH 서명 설정 (Git 2.34+)
# SSH 서명 포맷 활성화
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# 허용된 서명자 파일 생성
echo "maintainer@kernel.org $(cat ~/.ssh/id_ed25519.pub)" > ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
# SSH 서명 검증
git verify-commit HEAD
GPG vs SSH 서명 비교
| 항목 | GPG | SSH |
|---|---|---|
| 키 관리 | Web of Trust, 키서버 | ~/.ssh/ 디렉터리 |
| 하드웨어 토큰 | YubiKey, Nitrokey 지원 | FIDO2/U2F 지원 (Git 2.34+) |
| 만료/폐기 | 내장 지원 | allowed_signers 파일 수동 관리 |
| 설정 복잡도 | 높음 (gpg-agent, pinentry) | 낮음 (기존 SSH 키 재사용) |
| 커널 커뮤니티 | 표준 (메인테이너 GPG 키) | 점진적 채택 중 |
Signed-off-by와 DCO
리눅스 커널은 Developer Certificate of Origin(DCO)을 사용합니다. 모든 패치에 Signed-off-by: 태그를 추가하여, 해당 코드가 오픈소스 라이선스(GPLv2)에 부합함을 기여자가 선언합니다.
# DCO 서명 추가
git commit -s -m "subsystem: Fix null pointer dereference in foo_handler"
# 결과:
# Signed-off-by: Developer Name <developer@example.com>
Signed-off-by는 법적 선언(DCO)이며, GPG/SSH 커밋 서명은 암호학적 인증입니다. 두 가지는 목적이 다르므로 혼동하지 마세요. 커널 패치에는 둘 다 포함하는 것이 모범 사례입니다.
커밋 서명 자동 검증 스크립트
#!/bin/bash
# verify-commit-signatures.sh
# 특정 브랜치의 모든 커밋 서명을 일괄 검증
set -euo pipefail
BRANCH="${1:-HEAD}"
RANGE="${2:-HEAD~10..HEAD}"
echo "=== 커밋 서명 검증: $RANGE ==="
echo ""
total=0
signed=0
unsigned=0
bad=0
while IFS= read -r commit_hash; do
total=$((total + 1))
subject=$(git log -1 --format="%s" "$commit_hash")
# GPG 서명 검증
result=$(git verify-commit "$commit_hash" 2>&1 || true)
if echo "$result" | grep -q "Good signature"; then
signed=$((signed + 1))
signer=$(echo "$result" | grep "Good signature" | \
sed 's/.*Good signature from "\(.*\)"/\1/')
echo "[OK] $commit_hash $subject"
echo " 서명자: $signer"
elif echo "$result" | grep -q "BAD signature"; then
bad=$((bad + 1))
echo "[BAD] $commit_hash $subject"
echo " 경고: 서명이 유효하지 않습니다!"
else
unsigned=$((unsigned + 1))
echo "[---] $commit_hash $subject"
echo " 서명 없음"
fi
done < <(git log --format="%H" "$RANGE")
echo ""
echo "=== 결과 ==="
echo "전체: $total, 서명: $signed, 미서명: $unsigned, 불량: $bad"
if [ "$bad" -gt 0 ]; then
echo "경고: 유효하지 않은 서명이 발견되었습니다!"
exit 1
fi
GPG 키 관리 고급 설정
# GPG 키 베스트 프랙티스
# 1. 마스터 키와 서브키 분리
gpg --full-generate-key
# 마스터 키: Certify only
# 서브키: Sign, Encrypt, Authenticate 각각 분리
# 2. 마스터 키를 오프라인으로 이동
# 마스터 키 백업
gpg --armor --export-secret-keys KEYID > master-key-backup.asc
# 서브키만 남기기
gpg --armor --export-secret-subkeys KEYID > subkeys.asc
gpg --delete-secret-keys KEYID
gpg --import subkeys.asc
shred -u subkeys.asc
# 3. YubiKey에 서브키 이동
gpg --card-edit
# admin
# key 1
# keytocard # Signature key
# key 2
# keytocard # Encryption key
# key 3
# keytocard # Authentication key
# 4. YubiKey 터치 정책 설정 (매 서명 시 물리적 터치 필요)
ykman openpgp keys set-touch sig on
ykman openpgp keys set-touch enc on
# 5. 키 만료 설정 (2년)
gpg --edit-key KEYID
# expire
# 2y
# save
# 6. 키 폐기 인증서 미리 생성 (보관)
gpg --gen-revoke KEYID > revocation-cert.asc
# 안전한 오프라인 저장소에 보관
Git 서명 검증 정책 자동화
# pre-receive 훅: 서명되지 않은 커밋 거부 (서버 측)
cat > hooks/pre-receive << 'HOOK'
#!/bin/bash
while read oldrev newrev refname; do
# 새 브랜치 생성은 건너뛰기
if [ "$oldrev" = "0000000000000000000000000000000000000000" ]; then
continue
fi
# 모든 새 커밋의 서명 검증
for commit in $(git rev-list $oldrev..$newrev); do
if ! git verify-commit "$commit" &>/dev/null; then
echo "ERROR: 커밋 $commit에 유효한 GPG 서명이 없습니다."
echo "모든 커밋은 GPG 서명이 필요합니다."
exit 1
fi
done
done
HOOK
chmod +x hooks/pre-receive
# pre-push 훅: 로컬에서 푸시 전 서명 확인 (클라이언트 측)
cat > .git/hooks/pre-push << 'HOOK'
#!/bin/bash
remote="$1"
while read local_ref local_sha remote_ref remote_sha; do
if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
continue # 삭제는 건너뛰기
fi
range="$remote_sha..$local_sha"
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
range="$local_sha"
fi
unsigned=$(git log --format="%H" --no-merges "$range" | while read hash; do
git verify-commit "$hash" 2>/dev/null || echo "$hash"
done)
if [ -n "$unsigned" ]; then
echo "경고: 서명되지 않은 커밋이 있습니다:"
echo "$unsigned"
read -p "계속 진행하시겠습니까? (y/N) " answer
[ "$answer" = "y" ] || exit 1
fi
done
HOOK
chmod +x .git/hooks/pre-push
태그 검증
커널 릴리스 태그는 Linus Torvalds(mainline)와 Greg KH(stable)가 GPG 서명합니다. 이 서명을 검증하면 해당 릴리스가 공식 메인테이너로부터 나왔음을 확인할 수 있습니다.
GPG 키 가져오기 및 태그 검증
# Linus Torvalds의 GPG 키 (ABAF 11C6 5A29 70B1 30AB ...)
gpg --locate-keys torvalds@kernel.org
# Greg Kroah-Hartman의 GPG 키
gpg --locate-keys gregkh@kernel.org
# 또는 kernel.org에서 직접 가져오기
gpg --keyserver hkps://keys.openpgp.org --recv-keys \
ABAF11C65A2970B130ABE3C479BE3E4300411886
# 태그 검증
cd linux
git tag -v v6.8
# gpg: Signature made ... using RSA key ID ...
# gpg: Good signature from "Linus Torvalds <torvalds@kernel.org>"
# 특정 커밋이 서명된 태그에 포함되는지 확인
git merge-base --is-ancestor <commit-hash> v6.8 && echo "포함됨"
kernel.org 키 인프라
| 키 소유자 | 용도 | 키 유형 | 키 ID (마지막 16자리) |
|---|---|---|---|
| Linus Torvalds | mainline 태그 서명 | RSA 2048 | 79BE3E4300411886 |
| Greg Kroah-Hartman | stable 태그 서명 | RSA 4096 | 38DBBDC86092693E |
| kernel.org TAR | 타르볼 자동 서명 | RSA 4096 | 6092693E |
Sigstore & Rekor
Sigstore는 소프트웨어 서명의 진입 장벽을 낮추기 위한 프로젝트입니다. 장기 키 관리 없이 OIDC 인증으로 단기(ephemeral) 키를 생성하여 서명하고, 투명성 로그(Rekor)에 기록합니다.
cosign 사용 예시
# cosign 설치
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
# Keyless 서명 (OIDC 브라우저 인증)
cosign sign-blob --output-signature sig.txt \
--output-certificate cert.pem \
linux-6.8.tar.xz
# 검증
cosign verify-blob --signature sig.txt \
--certificate cert.pem \
--certificate-identity maintainer@kernel.org \
--certificate-oidc-issuer https://accounts.google.com \
linux-6.8.tar.xz
# Rekor 투명성 로그 조회
rekor-cli search --sha sha256:<hash-of-artifact>
rekor-cli get --uuid <entry-uuid>
Sigstore 컴포넌트
| 컴포넌트 | 역할 | 비유 |
|---|---|---|
| Fulcio | OIDC 토큰 기반 단기 인증서 발급 CA | 임시 신분증 발급기 |
| Rekor | 변조 불가능한 투명성 로그 (Merkle Tree) | 공증 기록부 |
| cosign | 컨테이너(Container) 이미지/blob 서명 CLI | 도장(인감) 도구 |
| Gitsign | Git 커밋의 Keyless 서명 | GPG 대체제 |
Gitsign: Git 커밋의 Keyless 서명
Gitsign은 Sigstore를 Git 커밋 서명에 적용합니다. GPG 키 관리 없이 OIDC 인증만으로 커밋을 서명할 수 있습니다.
# Gitsign 설치
go install github.com/sigstore/gitsign@latest
# Git에 Gitsign 설정
git config --local gpg.x509.program gitsign
git config --local gpg.format x509
git config --local commit.gpgsign true
# 커밋 시 자동으로 OIDC 인증 → Keyless 서명
git commit -m "feat: add new scheduler policy"
# 브라우저가 열리고 Google/GitHub/Microsoft 계정으로 인증
# Fulcio에서 단기 인증서 발급 → 커밋 서명 → Rekor에 기록
# 서명 검증
git verify-commit HEAD
# tlog index: 12345678
# gitsign: Signature made using certificate ID: ...
# gitsign: Good signature from [...@gmail.com]
# Rekor에서 서명 이력 조회
rekor-cli search --email developer@example.com
rekor-cli get --uuid <entry-uuid> --format json | jq '.body'
GPG vs Sigstore 비교
| 비교 항목 | 전통적 GPG | Sigstore (Keyless) |
|---|---|---|
| 키 관리 | 사용자가 직접 관리 (수년간) | 키 관리 불필요 (단기 키 자동 생성/폐기) |
| 신원 확인 | Web of Trust / 키서버 | OIDC IdP (Google, GitHub 등) |
| 폐기 처리 | 복잡 (폐기 인증서 배포) | 불필요 (키가 자동 만료) |
| 투명성 | 키서버 조회 가능 | Rekor 투명성 로그 (불변 기록) |
| 오프라인 검증 | 가능 (공개키만 필요) | Rekor 접근 필요 (오프라인 번들 가능) |
| 커널 커뮤니티 | 표준 (수십 년 사용) | 실험적 채택 단계 |
| 규제 준수 | 잘 알려진 표준 | 신규, 규제 인정 확대 중 |
재현 가능 빌드
재현 가능 빌드(Reproducible Builds)는 동일한 소스 코드, 동일한 빌드 환경에서 비트 단위로 동일한 바이너리를 생성할 수 있음을 보장합니다. 이를 통해 빌드 시스템이 변조되지 않았음을 독립적으로 검증할 수 있습니다.
커널 재현 빌드의 주요 장애물
| 비결정성 소스 | 원인 | 해결 방법 |
|---|---|---|
| 타임스탬프 | __DATE__, __TIME__ 매크로(Macro) | KBUILD_BUILD_TIMESTAMP 고정 |
| 빌드 경로 | 절대 경로 포함 (__FILE__) | KBUILD_BUILD_HOST, -ffile-prefix-map |
| 빌드 사용자/호스트 | KBUILD_BUILD_USER, KBUILD_BUILD_HOST | 환경변수 고정 |
| 모듈 순서 | 병렬 빌드 시 링크 순서 비결정적 | -j1 또는 결정론적 링크 스크립트 |
| CONFIG_MODULE_SIG_ALL | 랜덤 키로 모듈 서명 | 고정 서명 키 사용 |
재현 빌드 실행 예시
# SOURCE_DATE_EPOCH으로 모든 타임스탬프 고정
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
export KBUILD_BUILD_TIMESTAMP="$(date -d @$SOURCE_DATE_EPOCH -u)"
export KBUILD_BUILD_USER="reproducible"
export KBUILD_BUILD_HOST="reproducible"
# 빌드
make -j$(nproc) KCFLAGS="-ffile-prefix-map=$(pwd)=."
# 두 번째 독립 빌드 후 비교
diffoscope --html report.html vmlinux-build1 vmlinux-build2
# 차이 없으면: "No differences found"
# 차이 있으면: 어떤 섹션이 다른지 상세 리포트 생성
reprotest를 이용한 자동 재현성 검증
# reprotest 설치
apt install reprotest
# 커널 패키지의 재현성 자동 테스트
reprotest --vary=+all,-build_path \
'make -j$(nproc) KCFLAGS="-ffile-prefix-map=$(pwd)=." bzImage' \
arch/x86/boot/bzImage
# 개별 변동 요소 테스트
# 타임스탬프 변동
reprotest --vary=+time 'make bzImage' arch/x86/boot/bzImage
# 빌드 경로 변동
reprotest --vary=+build_path 'make bzImage' arch/x86/boot/bzImage
# 호스트명 변동
reprotest --vary=+host 'make bzImage' arch/x86/boot/bzImage
# diffoscope로 상세 차이점 분석
diffoscope --html report.html \
--text report.txt \
--max-diff-block-lines 200 \
build1/arch/x86/boot/bzImage \
build2/arch/x86/boot/bzImage
커널 6.x에서의 재현 빌드 개선 사항
| 커널 버전 | 개선 사항 | 관련 커밋/설정 |
|---|---|---|
| 5.10+ | -ffile-prefix-map 지원 일반화 | Kbuild에서 자동 적용 |
| 5.19+ | initramfs 타임스탬프 결정론화 | KBUILD_BUILD_TIMESTAMP 존중 |
| 6.1+ | BTF(BPF Type Format) 데이터 결정론화 | pahole 정렬 옵션 |
| 6.4+ | 모듈 서명에 결정론적 키 사용 옵션 | CONFIG_MODULE_SIG_KEY 외부 키 지원 강화 |
| 6.6+ | DWARF 디버그 정보 결정론화 | -fdebug-prefix-map 자동 적용 |
| 6.8+ | Rust 코드의 재현 빌드 지원 | RUSTFLAGS 환경변수 전달 |
배포판별 재현 빌드 현황
| 배포판 | 재현율 (커널) | 도구 | 상태 |
|---|---|---|---|
| Debian | ~90% (amd64) | reprotest, diffoscope, strip-nondeterminism | 공식 추적 (tests.reproducible-builds.org) |
| Arch Linux | ~80% | Reproducible Arch project | 커뮤니티 주도 |
| Fedora | ~70% | Koji 빌드 비교 | 개선 진행 중 |
| NixOS/Guix | ~95% | nix-build --check / guix build --check | 설계상 재현 빌드 지향 |
| openSUSE | ~75% | OBS 재현 빌드 지원 | 자동 검증 구축 중 |
커널 모듈 서명
커널 모듈 서명은 로드되는 .ko 파일이 신뢰할 수 있는 키로 서명되었는지 커널이 직접 검증하는 메커니즘입니다. CONFIG_MODULE_SIG_FORCE를 활성화하면 서명되지 않은 모듈의 로드를 완전히 차단합니다.
관련 Kconfig 옵션
# .config에서 모듈 서명 관련 옵션
CONFIG_MODULE_SIG=y # 모듈 서명 지원 활성화
CONFIG_MODULE_SIG_FORCE=y # 서명 없는 모듈 로드 차단
CONFIG_MODULE_SIG_ALL=y # 빌드 시 모든 모듈 자동 서명
CONFIG_MODULE_SIG_SHA512=y # 서명 해시 알고리즘 (SHA-512)
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" # 서명 키 경로
CONFIG_SYSTEM_TRUSTED_KEYRING=y # 시스템 신뢰 키링
CONFIG_SECONDARY_TRUSTED_KEYRING=y # 보조 키링 (런타임 키 추가)
모듈 서명 과정
# 수동으로 모듈 서명
scripts/sign-file sha512 \
certs/signing_key.pem \
certs/signing_key.x509 \
drivers/net/wireless/iwlwifi/iwlwifi.ko
# 서명 확인
modinfo iwlwifi.ko | grep sig
# sig_id: PKCS#7
# signer: Build time autogenerated kernel key
# sig_key: AB:CD:EF:...
# sig_hashalgo: sha512
# 서명 무결성 검증 (커널 로그)
dmesg | grep "module verification"
# module: x] module verification failed ...
커널 키링(Keyring) 구조
/* include/keys/system_keyring.h */
/* .builtin_trusted_keys: 빌드 시 내장된 키
* - CONFIG_SYSTEM_TRUSTED_KEYS로 지정된 인증서
* - 빌드 자동생성 키 (CONFIG_MODULE_SIG_KEY)
*/
extern struct key *builtin_trusted_keys;
/* .secondary_trusted_keys: 런타임 추가 가능한 키
* - builtin_trusted_keys로 서명된 키만 추가 가능
* - UEFI db의 인증서, IMA 키 등
*/
extern struct key *secondary_trusted_keys;
/* .machine: UEFI Machine Owner Key (MOK)
* - shim/MokManager에서 등록한 키
* - DKMS/OOT 모듈 서명에 사용
*/
extern struct key *machine_keyring;
certs/signing_key.pem은 빌드가 끝나면 반드시 안전하게 보관하거나 삭제해야 합니다. 이 키가 유출되면 공격자가 모듈을 서명하여 MODULE_SIG_FORCE를 우회할 수 있습니다.
모듈 서명 커널 내부 구현
커널 모듈 서명 검증은 kernel/module/signing.c에서 수행됩니다. 모듈 파일의 끝에 PKCS#7 서명 데이터가 추가되며, 커널은 로드 시 이를 검증합니다.
/* kernel/module/signing.c - 모듈 서명 검증 핵심 로직 */
int mod_verify_sig(const void *mod, struct load_info *info)
{
struct module_signature ms;
size_t sig_len, modlen = info->len;
int ret;
/* 모듈 끝에서 서명 메타데이터 추출 */
memcpy(&ms, mod + modlen - sizeof(ms), sizeof(ms));
/* 매직 넘버 확인: "~Module signature appended~\n" */
if (memcmp(&ms, MODULE_SIG_STRING, sizeof(MODULE_SIG_STRING) - 1) != 0)
return -ENODATA; /* 서명 없음 */
sig_len = be32_to_cpu(ms.sig_len);
/* PKCS#7 서명 검증 */
ret = verify_pkcs7_signature(mod, modlen - sig_len,
mod + modlen - sig_len, sig_len,
VERIFY_USE_SECONDARY_KEYRING,
VERIFYING_MODULE_SIGNATURE,
NULL, NULL);
return ret;
}
/* 모듈 로드 시 서명 정책 적용 */
static int module_sig_check(struct load_info *info, int flags)
{
int err;
err = mod_verify_sig(info->mod, info);
switch (err) {
case 0: /* 서명 유효 */
info->sig_ok = true;
return 0;
case -ENODATA: /* 서명 없음 */
if (is_module_sig_enforced())
return -EKEYREJECTED; /* 강제 모드: 거부 */
/* 허용 모드: taint 표시 후 로드 */
add_taint(TAINT_UNSIGNED_MODULE, LOCKDEP_STILL_OK);
return 0;
case -ENOPKG: /* 알 수 없는 알고리즘 */
case -EKEYREJECTED: /* 키 거부 */
return err;
default:
return err;
}
}
모듈 서명 검증 단계별 흐름
모듈 로드 요청 (insmod / modprobe)
│
├─ 1. 모듈 파일 읽기 (.ko)
│
├─ 2. 서명 메타데이터 확인
│ └─ "~Module signature appended~\n" 매직 스트링 검색
│
├─ 3. PKCS#7 서명 추출
│ └─ 서명 길이, 해시 알고리즘, 키 ID 파싱
│
├─ 4. 키링에서 서명 키 검색
│ ├─ .builtin_trusted_keys (빌드 시 내장)
│ ├─ .secondary_trusted_keys (런타임 추가)
│ └─ .machine (MOK 키)
│
├─ 5. 서명 검증
│ ├─ 성공 → sig_ok = true, 로드 허용
│ ├─ 실패 → MODULE_SIG_FORCE 시 -EKEYREJECTED
│ └─ 미서명 → MODULE_SIG_FORCE 시 -EKEYREJECTED
│ → 비강제 모드: TAINT_UNSIGNED_MODULE + 로드
│
└─ 6. 모듈 초기화 (module_init 호출)
외부 모듈 서명 자동화
# 배포판에서 커스텀 모듈을 빌드/서명하는 전체 워크플로우
# 1. 서명 키 생성 (한 번만)
openssl req -new -x509 -newkey rsa:4096 \
-keyout /etc/pki/module-signing-key.pem \
-outform DER -out /etc/pki/module-signing-key.der \
-days 3650 -subj "/CN=Custom Module Signing Key/" \
-nodes
chmod 400 /etc/pki/module-signing-key.pem
# 2. MOK에 등록 (Secure Boot 환경)
mokutil --import /etc/pki/module-signing-key.der
# 비밀번호 설정 후 재부팅 → UEFI에서 등록 확인
# 3. 모듈 빌드
cd /usr/src/my-driver
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
# 4. 서명
/lib/modules/$(uname -r)/build/scripts/sign-file sha512 \
/etc/pki/module-signing-key.pem \
/etc/pki/module-signing-key.der \
my-driver.ko
# 5. 서명 확인
modinfo my-driver.ko | grep -E "sig|signer"
# sig_id: PKCS#7
# signer: Custom Module Signing Key
# sig_hashalgo: sha512
# 6. 모듈 설치 및 로드
install -m 644 my-driver.ko /lib/modules/$(uname -r)/extra/
depmod -a
modprobe my-driver
# 7. 검증
dmesg | tail -5
lsmod | grep my_driver
DKMS 보안
DKMS(Dynamic Kernel Module Support)는 커널 업그레이드 시 외부 모듈을 자동으로 재빌드합니다. Secure Boot 환경에서는 DKMS 모듈도 서명이 필요합니다.
DKMS + Secure Boot 연동
# MOK(Machine Owner Key) 생성
openssl req -new -x509 -newkey rsa:2048 \
-keyout /root/mok-signing-key.priv \
-outform DER -out /root/mok-signing-key.der \
-days 36500 -subj "/CN=My DKMS Signing Key/" \
-nodes
# MOK 등록 (재부팅 후 UEFI에서 확인)
mokutil --import /root/mok-signing-key.der
# /etc/dkms/framework.conf에 서명 설정
cat >> /etc/dkms/framework.conf << 'EOF'
sign_tool="/etc/dkms/sign_helper.sh"
mok_signing_key="/root/mok-signing-key.priv"
mok_certificate="/root/mok-signing-key.der"
EOF
# sign_helper.sh
cat > /etc/dkms/sign_helper.sh << 'SCRIPT'
#!/bin/bash
/lib/modules/"$1"/build/scripts/sign-file sha256 \
/root/mok-signing-key.priv \
/root/mok-signing-key.der "$2"
SCRIPT
chmod +x /etc/dkms/sign_helper.sh
# DKMS 모듈 빌드/설치 (자동 서명)
dkms install nvidia/535.129.03
# Signing module /var/lib/dkms/nvidia/535.129.03/.../nvidia.ko
MOK 키 관리 모범 사례
| 항목 | 권장사항 |
|---|---|
| 키 저장 | 개인키는 root만 읽기 가능 (chmod 400), 가능하면 HSM/TPM 사용 |
| 키 유효기간 | 조직 정책에 따라 1~10년, 갱신 프로세스 문서화 |
| 키 폐기 | mokutil --delete로 MOK에서 제거, 즉시 새 키로 교체 |
| 키 감사 | mokutil --list-enrolled로 등록된 키 주기적 점검 |
dkms autoinstall 과정에서 서명 스크립트가 자동 호출됩니다. 자세한 내용은 커널 모듈 문서를 참고하세요.
펌웨어 서명 검증
리눅스 커널은 firmware_class 서브시스템을 통해 디바이스 펌웨어를 로드합니다. 펌웨어 이미지의 무결성은 IMA(Integrity Measurement Architecture)와 dm-verity, 또는 드라이버 자체 검증으로 보장됩니다.
IMA 정책으로 펌웨어 보호
# IMA 정책: 펌웨어 파일에 대한 서명 검증 강제
echo "appraise func=FIRMWARE_CHECK appraise_type=imasig" \
>> /etc/ima/ima-policy
# 펌웨어 파일에 IMA 서명 추가
evmctl ima_sign --key /etc/keys/privkey_evm.pem \
/lib/firmware/iwlwifi-ty-a0-gf-a0-72.ucode
# 검증 (xattr에 IMA 서명 확인)
getfattr -m security.ima -d \
/lib/firmware/iwlwifi-ty-a0-gf-a0-72.ucode
CONFIG_FW_LOADER 관련 옵션
CONFIG_FW_LOADER=y # 펌웨어 로딩 기본 지원
CONFIG_FW_LOADER_USER_HELPER=n # 사용자 공간 헬퍼 비활성화 (보안 강화)
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n # 폴백도 비활성화
CONFIG_FW_LOADER_COMPRESS=y # 압축 펌웨어 지원 (xz/zstd)
CONFIG_EXTRA_FIRMWARE="" # 빌트인 펌웨어 경로 (initramfs 불필요)
CONFIG_EXTRA_FIRMWARE로 커널 이미지에 직접 포함할 수 있습니다. 이 경우 커널 이미지 자체의 Secure Boot 서명이 펌웨어 무결성도 보장합니다. 자세한 내용은 Secure Boot 문서를 참고하세요.
커널 타르볼 검증
kernel.org에서 배포하는 커널 소스 타르볼은 PGP 서명과 SHA-256 체크섬(Checksum)으로 무결성을 보장합니다.
타르볼 다운로드 및 검증
# 타르볼과 서명 파일 다운로드
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.sign
# xz 압축 해제 후 서명 검증 (서명은 .tar에 대해 생성됨)
unxz linux-6.8.tar.xz
gpg --verify linux-6.8.tar.sign linux-6.8.tar
# 출력 확인:
# gpg: Signature made ...
# gpg: Good signature from "Greg Kroah-Hartman <gregkh@kernel.org>"
# gpg: aka "Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# 키 지문(fingerprint) 수동 확인
gpg --fingerprint gregkh@kernel.org
# 647F 2865 4894 E3BD 4571 99BE 38DB BDC8 6092 693E
자동화 스크립트
#!/bin/bash
# verify-kernel-tarball.sh - 커널 타르볼 자동 검증
set -euo pipefail
VERSION="${1:?Usage: $0 <version> (e.g., 6.8)}"
MAJOR="${VERSION%%.*}"
BASE_URL="https://cdn.kernel.org/pub/linux/kernel/v${MAJOR}.x"
echo "[1/4] 다운로드..."
wget -q "${BASE_URL}/linux-${VERSION}.tar.xz"
wget -q "${BASE_URL}/linux-${VERSION}.tar.sign"
echo "[2/4] GPG 키 가져오기..."
gpg --keyserver hkps://keys.openpgp.org --recv-keys \
ABAF11C65A2970B130ABE3C479BE3E4300411886 \
647F28654894E3BD457199BE38DBBDC86092693E 2>/dev/null || true
echo "[3/4] 압축 해제..."
unxz "linux-${VERSION}.tar.xz"
echo "[4/4] 서명 검증..."
if gpg --verify "linux-${VERSION}.tar.sign" "linux-${VERSION}.tar" 2>&1 | grep -q "Good signature"; then
echo "검증 성공: linux-${VERSION}.tar"
else
echo "검증 실패! 타르볼이 변조되었을 수 있습니다."
exit 1
fi
배포판 커널 빌드 검증
주요 배포판은 upstream 커널을 기반으로 자체 패치를 적용하고, 자동화된 빌드 파이프라인에서 서명된 패키지를 생성합니다.
배포판별 빌드 파이프라인
| 배포판 | 빌드 시스템 | 패키지 서명 | 소스 공개 | 재현 빌드 |
|---|---|---|---|---|
| Debian | sbuild + buildd | GPG (archive key) | apt source linux | 진행 중 (reproducible-builds.org) |
| Ubuntu | Launchpad | GPG (archive key) | apt source linux | Debian 기반 노력 활용 |
| Fedora/RHEL | Koji | GPG (RPM signing key) | koji download-build / src.rpm | Fedora CI 검증 중 |
| SUSE/openSUSE | OBS (Open Build Service) | GPG (OBS key) | osc checkout | OBS 재현 빌드 지원 |
| Arch Linux | makepkg | GPG (packager key) | asp checkout linux | 부분 지원 |
Debian/Ubuntu 커널 패키지 검증
# APT 저장소 서명 검증 (자동)
apt-key list | grep -A 1 "Ubuntu Archive"
# 패키지 무결성 확인
dpkg --verify linux-image-$(uname -r)
# 소스 패키지 다운로드 후 빌드 재현 시도
apt source linux-image-$(uname -r)
cd linux-*/
dpkg-buildpackage -us -uc
# 설치된 커널과 비교
diffoscope /boot/vmlinuz-$(uname -r) debian/build/build-generic/vmlinux
RHEL/Fedora 커널 패키지 검증
# RPM GPG 서명 검증
rpm -K kernel-$(uname -r).rpm
# kernel-6.8.0-1.fc40.x86_64.rpm: digests signatures OK
# 빌드 출처 확인
rpm -qi kernel-$(uname -r) | grep -E "Build Host|Vendor|Signature"
# Koji에서 빌드 로그 확인
koji buildinfo kernel-6.8.0-1.fc40
# src.rpm으로 재빌드
rpmbuild --rebuild kernel-6.8.0-1.fc40.src.rpm
SBOM (Software Bill of Materials)
SBOM은 소프트웨어에 포함된 모든 구성 요소(라이브러리, 모듈, 펌웨어 등)의 목록을 표준 포맷으로 제공합니다. 취약점 발생 시 영향 범위를 신속하게 파악할 수 있습니다.
SPDX vs CycloneDX
| 항목 | SPDX | CycloneDX |
|---|---|---|
| 표준 | ISO/IEC 5962, Linux Foundation | OWASP |
| 초점 | 라이선스 + 구성 요소 | 보안 + 취약점 |
| 포맷 | Tag-Value, JSON, RDF, YAML | JSON, XML, Protobuf |
| 커널 친화도(Affinity) | 높음 (SPDX 태그 내장) | 중간 |
| VEX 지원 | SPDX 3.0+ | 네이티브 |
SBOM 생성 예시
# syft로 커널 빌드 디렉터리에서 SBOM 생성
syft dir:/usr/src/linux-6.8 -o spdx-json=kernel-sbom.spdx.json
# 특정 커널 패키지에서 SBOM 추출
syft packages:linux-image-6.8.0-generic -o cyclonedx-json=kernel-sbom.cdx.json
# SBOM으로 알려진 취약점 검색 (grype)
grype sbom:kernel-sbom.spdx.json
# SPDX 라이선스 태그 통계 (커널 소스)
grep -r "SPDX-License-Identifier" --include="*.c" --include="*.h" | \
awk -F: '{print $NF}' | sort | uniq -c | sort -rn | head -20
SPDX-License-Identifier 태그를 추가하고 있습니다. 이는 전 세계에서 가장 큰 규모의 SPDX 태깅 프로젝트입니다.
커널 SBOM 생성 상세
리눅스 커널의 SBOM 생성은 일반 소프트웨어와 다른 특수한 고려사항이 있습니다. 커널은 .config에 따라 포함되는 코드가 달라지므로, 특정 빌드 구성에 대한 SBOM을 생성해야 합니다.
# 방법 1: syft로 커널 소스 디렉터리 스캔
syft dir:/usr/src/linux-6.8 \
-o spdx-json=kernel-src-sbom.spdx.json \
--name "linux-kernel" \
--version "6.8.0"
# 방법 2: 빌드된 커널 패키지에서 SBOM 생성
syft packages:linux-image-6.8.0-generic \
-o cyclonedx-json=kernel-pkg-sbom.cdx.json
# 방법 3: 커널 .config 기반으로 활성 모듈만 포함하는 SBOM
# (커스텀 스크립트 예시)
cat .config | grep "=m$\|=y$" | \
sed 's/CONFIG_//; s/=.*//' | \
while read module; do
echo "{\"name\": \"$module\", \"type\": \"kernel-module\"}"
done | jq -s '{components: .}' > kernel-modules-sbom.json
# 방법 4: 펌웨어 의존성 포함 SBOM
# 부팅에 필요한 펌웨어 목록 추출
modprobe --show-depends $(lsmod | awk 'NR>1{print $1}') 2>/dev/null | \
grep firmware | sort -u
# SBOM에 펌웨어 정보 추가
syft dir:/lib/firmware \
-o spdx-json=firmware-sbom.spdx.json \
--name "linux-firmware"
# SBOM 품질 검증
# 1. NTIA 최소 요소 확인
# 공급자명, 컴포넌트명, 버전, 고유 식별자, 관계, 타임스탬프
ntia-checker -v kernel-src-sbom.spdx.json
# 2. SBOM으로 알려진 취약점 검색
grype sbom:kernel-src-sbom.spdx.json --only-fixed
trivy sbom kernel-src-sbom.spdx.json
SBOM 자동화 파이프라인
# 커널 SBOM 자동 생성 CI 파이프라인 예시
# (GitLab CI / GitHub Actions 형식)
stages:
- build
- sbom
- sign
- publish
build-kernel:
stage: build
script:
- make -j$(nproc) bzImage modules
- make modules_install INSTALL_MOD_PATH=$CI_PROJECT_DIR/output
artifacts:
paths: [output/]
generate-sbom:
stage: sbom
script:
# 소스 SBOM
- syft dir:. -o spdx-json=source-sbom.spdx.json
# 빌드 산출물 SBOM
- syft dir:output/ -o cyclonedx-json=build-sbom.cdx.json
# SBOM 머지
- sbom-tool merge source-sbom.spdx.json build-sbom.cdx.json \
-o merged-sbom.spdx.json
# NTIA 최소 요소 검증
- ntia-checker merged-sbom.spdx.json
artifacts:
paths: [merged-sbom.spdx.json, build-sbom.cdx.json]
sign-sbom:
stage: sign
script:
- cosign sign-blob --output-signature sbom.sig \
--output-certificate sbom.cert \
merged-sbom.spdx.json
artifacts:
paths: [sbom.sig, sbom.cert]
publish-sbom:
stage: publish
script:
# SBOM을 OCI 레지스트리에 첨부
- cosign attach sbom --sbom merged-sbom.spdx.json \
registry.example.com/kernel:6.8.0
# Dependency-Track에 SBOM 업로드
- curl -X POST "$DTRACK_URL/api/v1/bom" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-F "bom=@merged-sbom.spdx.json"
VEX (Vulnerability Exploitability eXchange)
VEX는 SBOM에 포함된 구성 요소의 취약점이 실제로 해당 제품에서 악용 가능한지 여부를 명시하는 문서입니다. 커널 빌드에서 특정 CONFIG 옵션이 비활성화되어 있으면, 관련 취약점은 "not affected"로 표시할 수 있습니다.
| VEX 상태 | 의미 | 커널 예시 |
|---|---|---|
| Not Affected | 취약한 코드가 포함되지 않음 | CONFIG_BT=n → Bluetooth 취약점 해당 없음 |
| Affected | 취약하며 패치 필요 | CVE가 활성화된 서브시스템에 해당 |
| Fixed | 패치가 적용됨 | stable 백포트가 적용된 버전 |
| Under Investigation | 분석 중 | 영향도 확인 중인 CVE |
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://kernel.org/vex/2024-001",
"author": "kernel-security@kernel.org",
"timestamp": "2024-03-15T12:00:00Z",
"statements": [
{
"vulnerability": {"name": "CVE-2024-1234"},
"products": [
{"@id": "pkg:generic/linux-kernel@6.8.0?config=minimal"}
],
"status": "not_affected",
"justification": "vulnerable_code_not_present",
"impact_statement": "CONFIG_SCSI=n: SCSI 서브시스템이 빌드에 포함되지 않음"
},
{
"vulnerability": {"name": "CVE-2024-5678"},
"products": [
{"@id": "pkg:generic/linux-kernel@6.8.0?config=server"}
],
"status": "fixed",
"impact_statement": "커밋 abc123def로 패치 적용됨 (stable 6.8.1+)"
}
]
}
출처 증명 (Provenance)
출처 증명(Provenance)은 소프트웨어 산출물이 어떤 소스에서, 어떤 빌드 과정을 거쳐, 누구에 의해 만들어졌는지를 암호학적으로 기록합니다.
in-toto 프레임워크
in-toto는 소프트웨어 공급망의 각 단계(step)를 정의하고, 각 단계의 수행자가 서명한 링크 메타데이터를 수집하여 전체 공급망을 검증합니다.
# in-toto 레이아웃 정의 (커널 빌드 공급망)
in-toto-run --step-name clone --products linux-6.8/ -- \
git clone --branch v6.8 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux-6.8
in-toto-run --step-name configure --materials linux-6.8/ --products linux-6.8/.config -- \
make -C linux-6.8 defconfig
in-toto-run --step-name build --materials linux-6.8/ --products linux-6.8/vmlinux -- \
make -C linux-6.8 -j$(nproc)
# 검증
in-toto-verify --layout kernel-layout.json --layout-key maintainer-pub.pem
TUF (The Update Framework)
TUF는 소프트웨어 업데이트 시스템의 보안을 위한 프레임워크로, 키 관리, 위임, 만료 정책을 체계적으로 다룹니다. 리눅스 배포판의 패키지 저장소 보안에 적용됩니다.
| TUF 역할 | 목적 | 커널 배포 적용 |
|---|---|---|
| Root | 최상위 신뢰 앵커, 다른 역할 키 지정 | 배포판 마스터 키 |
| Targets | 실제 파일 해시(Hash)/크기 메타데이터 | 커널 패키지 해시 |
| Snapshot | Targets 메타데이터의 현재 상태 | 저장소 상태 스냅샷 |
| Timestamp | 최신 Snapshot을 가리키는 타임스탬프 | 롤백(Rollback) 공격 방지 |
취약점 공개 프로세스
리눅스 커널은 체계적인 취약점 공개(coordinated disclosure) 프로세스를 운영합니다.
보고 채널
| 채널 | 대상 | 참여자 | 엠바고 기간 |
|---|---|---|---|
| security@kernel.org | 커널 보안 팀 | 소수 핵심 메인테이너 | 최대 7일 (패치 공개까지) |
| linux-distros@ | 배포판 보안 팀 | Debian, Red Hat, SUSE, Ubuntu 등 | 최대 14일 |
| oss-security@ | 공개 메일링 리스트 | 전체 공개 | 없음 (공개 후 논의) |
취약점 처리 타임라인
Day 0 : 보안 연구원이 security@kernel.org로 보고
Day 1-3 : 커널 보안 팀이 재현/확인, 패치 개발 시작
Day 3-5 : 패치 리뷰/테스트, stable 백포트 준비
Day 5-7 : linux-distros@에 사전 통보 (엠바고)
Day 7-14: 배포판 패키지 준비 기간
Day 14 : 패치 공개 + stable 릴리스 + CVE 할당
Day 14+ : oss-security@에 공개 논의
CVE 할당
2024년 2월부터 리눅스 커널 프로젝트는 자체 CNA(CVE Numbering Authority)로서 CVE를 직접 할당합니다. CVE-2024-* 형식으로 stable 커밋에 연결됩니다.
# 커널 CVE 목록 확인
git clone https://git.kernel.org/pub/scm/linux/security/vulns.git
ls vulns/cve/published/2024/
# 특정 CVE의 영향받는 버전 확인
cat vulns/cve/published/2024/CVE-2024-XXXX.json | jq '.affected[].versions'
# 현재 커널에 적용된 보안 패치 확인
grep -i "cve-" /usr/share/doc/linux-image-$(uname -r)/changelog.Debian.gz
커널 보안 취약점 추적 자동화
# 현재 시스템에 적용되지 않은 CVE 확인
# 방법 1: 커널 CVE 저장소 활용
git clone https://git.kernel.org/pub/scm/linux/security/vulns.git
cd vulns
# 현재 커널 버전에 영향받는 CVE 목록
KVER=$(uname -r | cut -d- -f1)
for cve in cve/published/2024/CVE-*.json; do
affected=$(jq -r ".affected[].versions[]" "$cve" 2>/dev/null | \
grep -c "$KVER" || true)
if [ "$affected" -gt 0 ]; then
cveid=$(basename "$cve" .json)
desc=$(jq -r '.containers.cna.descriptions[0].value' "$cve" | \
head -c 80)
echo "$cveid: $desc..."
fi
done
# 방법 2: livepatch 적용 가능 여부 확인 (Ubuntu)
canonical-livepatch status --verbose 2>/dev/null
# 방법 3: 배포판 보안 트래커 활용
# Debian: https://security-tracker.debian.org/tracker/
curl -s "https://security-tracker.debian.org/tracker/source-package/linux" | \
grep -oP 'CVE-[0-9]+-[0-9]+' | sort -u | tail -20
# 방법 4: OSV.dev API 활용
curl -s "https://api.osv.dev/v1/query" \
-d '{"package":{"name":"linux","ecosystem":"Linux"},"version":"6.8.0"}' | \
jq '.vulns[].id'
보안 메일링 리스트 운영 규칙
| 메일링 리스트 | 가입 조건 | 엠바고 규칙 | 위반 시 조치 |
|---|---|---|---|
| security@kernel.org | 초대 전용 (핵심 메인테이너) | 패치 공개까지 비공개 | 목록에서 영구 제거 |
| linux-distros@ | 배포판 보안 팀 (검증된 담당자) | 최대 14일, 단축 협상 가능 | 목록에서 제거, 공개 경고 |
| oss-security@ | 공개 (누구나 가입) | 없음 (공개 목록) | 해당 없음 |
- 엠바고 위반: linux-distros@ 엠바고 기간 중 패치를 사전 공개하면 해당 배포판 보안 팀이 목록에서 제거됩니다. 이는 전체 생태계의 신뢰를 보호하기 위한 엄격한 규칙입니다.
- 90일 규칙: 보안 연구자는 일반적으로 90일의 공개 기한(disclosure deadline)을 설정합니다. 커널 팀이 기한 내 패치를 공개하지 않으면 연구자가 독자적으로 공개할 수 있습니다.
- Zero-day 대응: 이미 악용 중인 취약점(zero-day)은 엠바고 없이 즉시 패치를 공개합니다. 이 경우 linux-distros@에 사전 통보 없이 oss-security@에 직접 공개됩니다.
빌드 시스템 무결성
SolarWinds 사건이 보여주듯, 빌드 시스템 자체가 공격 대상이 될 수 있습니다. 빌드 환경의 격리와 감사는 공급망 보안의 핵심입니다.
밀폐(Hermetic) 빌드 환경
# 밀폐 빌드 환경 예시 (podman + 네트워크 차단)
podman run --rm --network=none \
-v /path/to/linux-6.8:/src:ro \
-v /path/to/output:/out \
kernel-build-env:latest \
/bin/bash -c "
cd /src
cp /src/.config /out/.config
make O=/out -j\$(nproc) bzImage modules
"
# 빌드 환경 이미지 자체도 서명/검증
cosign verify --certificate-identity builder@kernel.org \
--certificate-oidc-issuer https://accounts.google.com \
registry.example.com/kernel-build-env:latest
빌드 환경 Dockerfile 예시
# 커널 밀폐 빌드 환경 Dockerfile
FROM debian:bookworm-slim AS kernel-build-env
# 빌드 의존성 설치 (버전 핀닝)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential=12.9 \
bc=1.07.1-3+b1 \
bison=2:3.8.2+dfsg-1+b1 \
flex=2.6.4-8.2 \
libelf-dev=0.189-4 \
libssl-dev=3.0.11-1~deb12u2 \
cpio=2.13+dfsg-7.1 \
kmod=30+20221128-1 \
&& rm -rf /var/lib/apt/lists/*
# 빌드 도구 해시 검증
RUN sha256sum /usr/bin/gcc /usr/bin/make /usr/bin/ld > /build-tools-hashes.txt
# 비특권 사용자로 빌드
RUN useradd -m builder
USER builder
WORKDIR /home/builder
# 빌드 스크립트
COPY --chown=builder:builder build-kernel.sh /home/builder/
RUN chmod +x /home/builder/build-kernel.sh
ENTRYPOINT ["/home/builder/build-kernel.sh"]
빌드 감사 로그
# 빌드 과정의 모든 단계를 감사 로그로 기록
build_kernel_audited() {
local LOGDIR="/var/log/kernel-build"
local TIMESTAMP=$(date -u +%Y%m%dT%H%M%SZ)
local LOGFILE="${LOGDIR}/build-${TIMESTAMP}.log"
mkdir -p "$LOGDIR"
echo "=== Kernel Build Audit Log ===" > "$LOGFILE"
echo "Timestamp: $TIMESTAMP" >> "$LOGFILE"
echo "Builder: $(whoami)@$(hostname)" >> "$LOGFILE"
echo "Kernel Version: $(make kernelversion)" >> "$LOGFILE"
# 소스 무결성 확인
echo "--- Source Verification ---" >> "$LOGFILE"
git tag -v "$(git describe --tags)" >> "$LOGFILE" 2>&1
# 빌드 도구 해시
echo "--- Build Tools ---" >> "$LOGFILE"
for tool in gcc cc1 as ld make; do
which $tool >> "$LOGFILE" 2>&1
sha256sum "$(which $tool)" >> "$LOGFILE" 2>&1
done
# .config 해시
echo "--- Config Hash ---" >> "$LOGFILE"
sha256sum .config >> "$LOGFILE"
# 환경변수 기록
echo "--- Environment ---" >> "$LOGFILE"
env | grep -E "^(SOURCE_DATE|KBUILD|CC|LD|AR|PATH)=" >> "$LOGFILE"
# 빌드 수행
echo "--- Build Start ---" >> "$LOGFILE"
make -j$(nproc) bzImage modules 2>&1 | tee -a "$LOGFILE"
local BUILD_RC=$?
# 산출물 해시
echo "--- Artifact Hashes ---" >> "$LOGFILE"
sha256sum arch/x86/boot/bzImage >> "$LOGFILE"
find . -name "*.ko" -exec sha256sum {} \; >> "$LOGFILE"
echo "--- Build Complete (rc=$BUILD_RC) ---" >> "$LOGFILE"
# 로그 서명
gpg --detach-sign --armor "$LOGFILE"
return $BUILD_RC
}
위협 모델: 빌드 시스템 공격
| 위협 | 공격 시나리오 | SLSA 레벨 방어 | 추가 방어 |
|---|---|---|---|
| 소스 변조 | 빌드 직전 소스 코드 수정 | L2: 소스가 버전 관리됨 | 빌드 전 git tag -v 검증 |
| 빌드 스크립트 변조 | Makefile/스크립트에 악성 명령 삽입 | L3: 빌드 프로세스가 빌더에 의해 정의 | 빌드 스크립트 해시 검증 |
| 컴파일러 변조 | 변조된 GCC/Clang으로 빌드 | L3: 밀폐 빌드 환경 | 다중 컴파일러 교차 빌드 |
| 빌드 캐시 오염 | ccache/sccache에 변조된 객체 삽입 | L3: 밀폐 빌드 (캐시 미사용) | 캐시 무결성 검증 |
| 산출물 교체 | 빌드 후 서명 전에 바이너리 교체 | L3: Provenance가 빌드 직후 생성 | 빌드-서명 원자적 수행 |
| Provenance 위조 | 가짜 빌드 출처 메타데이터 생성 | L3: Provenance 비위조 보장 | HSM 기반 서명 키 |
kernel.org 인프라
kernel.org는 리눅스 커널의 공식 배포 인프라입니다. 전 세계 미러 네트워크와 Git 호스팅을 제공합니다.
인프라 구성
| 서비스 | 기술 | 보안 조치 |
|---|---|---|
| git.kernel.org | gitolite + cgit | SSH 키 인증, 메인테이너별 ACL, 포스 푸시 금지 |
| cdn.kernel.org | Fastly CDN | HTTPS + PGP 서명 파일 병행 배포 |
| 미러 네트워크 | rsync + HTTP | 미러는 신뢰 불가 → PGP 검증 필수 |
| lore.kernel.org | public-inbox | 메일링 리스트 아카이브, DKIM 검증 |
| korg 관리자 | Linux Foundation IT | 2FA, 하드웨어 보안 키, 감사 로그 |
2011년 침해 사건과 이후 개선
2011년 kernel.org 서버가 해킹되었지만, GPG 서명 체계 덕분에 소스 코드 무결성에는 영향이 없었습니다. 이 사건 이후 다음과 같은 보안 강화가 이루어졌습니다.
- Git 객체 무결성: Git의 SHA-1 해시 체인이 모든 커밋의 변조를 감지합니다. SHA-256 전환도 진행 중입니다.
- 서버 접근 통제: SSH 키 + 2FA, 최소 권한 원칙, 관리자 접근 감사 로그
- 인프라 분리: Git 서버와 웹 서버 분리, 빌드 인프라 독립 운영
- 투명성: 모든 GPG 키와 서명 정책이 공개 문서화
Git SHA-1에서 SHA-256으로의 전환
Git은 기본적으로 SHA-1 해시를 사용하여 객체를 식별합니다. SHA-1의 충돌(collision) 공격이 실증된 이후(SHAttered, 2017), Git과 커널 커뮤니티는 SHA-256 전환을 추진하고 있습니다.
| 항목 | SHA-1 (현재) | SHA-256 (목표) |
|---|---|---|
| 해시 길이 | 160비트 (40자 hex) | 256비트 (64자 hex) |
| 충돌 저항성 | 이론적 약화, 실증된 충돌 | 충분한 안전 마진 |
| Git 지원 | 기본값 | Git 2.42+ 실험적 지원 |
| 커널 저장소 | 현재 사용 중 | 전환 계획 진행 중 |
| 호환성 | 모든 도구 지원 | 점진적 도구 지원 확대 |
# SHA-256 저장소 생성 (Git 2.42+)
git init --object-format=sha256 my-repo
# 기존 저장소의 해시 포맷 확인
git rev-parse --show-object-format
# sha1
# SHA-1 충돌 감지 (Git의 내장 방어)
# Git 2.13+는 SHA-1 충돌 공격을 감지하는 코드가 내장됨
# 충돌이 감지되면 push/fetch를 거부
# kernel.org의 해시 무결성 검증
# git fsck가 전체 저장소의 해시 체인을 검증
git fsck --full --strict
kernel.org 미러 보안
kernel.org의 미러 네트워크는 전 세계에 분산되어 있습니다. 미러는 신뢰할 수 없는 제3자이므로, PGP 서명 검증이 필수입니다.
# 미러 목록 확인
curl -s https://www.kernel.org/mirrors.html | \
grep -oP 'href="(https?://[^"]+)"' | head -20
# 미러에서 다운로드 시 보안 절차
# 1. HTTPS 사용 (가능한 경우)
# 2. PGP 서명 검증 (필수)
# 3. 해시 검증 (보조)
# 자동화된 미러 검증 스크립트
verify_mirror() {
local mirror_url="$1"
local version="$2"
local official_url="https://cdn.kernel.org"
# 미러에서 다운로드
wget -q "${mirror_url}/pub/linux/kernel/v6.x/linux-${version}.tar.sign"
wget -q "${mirror_url}/pub/linux/kernel/v6.x/linux-${version}.tar.xz"
# 서명 파일은 공식 서버에서도 받아서 비교
wget -q "${official_url}/pub/linux/kernel/v6.x/linux-${version}.tar.sign" \
-O official.tar.sign
# 서명 파일 비교
if ! diff -q "linux-${version}.tar.sign" official.tar.sign &>/dev/null; then
echo "경고: 서명 파일이 공식 서버와 다릅니다!"
return 1
fi
# PGP 검증
unxz "linux-${version}.tar.xz"
gpg --verify "linux-${version}.tar.sign" "linux-${version}.tar"
}
컨테이너 이미지 서명
컨테이너 환경에서 커널과 관련 컴포넌트를 배포할 때, 이미지 서명으로 무결성을 보장합니다.
cosign을 이용한 이미지 서명
# 컨테이너 이미지 서명 (Keyless)
cosign sign registry.example.com/kernel-modules:6.8
# 검증
cosign verify \
--certificate-identity builder@kernel.org \
--certificate-oidc-issuer https://accounts.google.com \
registry.example.com/kernel-modules:6.8
# SBOM을 이미지에 첨부
cosign attach sbom --sbom kernel-sbom.spdx.json \
registry.example.com/kernel-modules:6.8
# 서명 + SBOM + Provenance 통합 검증
cosign verify-attestation \
--type spdxjson \
--certificate-identity builder@kernel.org \
--certificate-oidc-issuer https://accounts.google.com \
registry.example.com/kernel-modules:6.8
Notary v2 (notation)
# Notary v2 (CNCF notation) 서명
notation sign registry.example.com/kernel-modules:6.8
# 검증 정책 설정
cat > ~/.config/notation/trustpolicy.json << 'EOF'
{
"version": "1.0",
"trustPolicies": [{
"name": "kernel-policy",
"registryScopes": ["registry.example.com/kernel-*"],
"signatureVerification": { "level": "strict" },
"trustStores": ["ca:kernel-ca"],
"trustedIdentities": ["x509.subject: CN=kernel.org"]
}]
}
EOF
notation verify registry.example.com/kernel-modules:6.8
Kubernetes 정책 적용
# Kyverno 정책: 서명된 이미지만 허용
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-kernel-images
spec:
validationFailureAction: Enforce
rules:
- name: check-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences: ["registry.example.com/kernel-*"]
attestors:
- entries:
- keyless:
subject: "builder@kernel.org"
issuer: "https://accounts.google.com"
rekor:
url: "https://rekor.sigstore.dev"
컴플라이언스
전 세계 정부와 규제 기관이 소프트웨어 공급망 보안에 대한 법적 요구사항을 강화하고 있습니다.
주요 규제 요약
| 규제 | 관할 | 핵심 요구사항 | 커널 프로젝트 영향 |
|---|---|---|---|
| EO 14028 | 미국 | SBOM 의무화, 빌드 환경 보호, 취약점 공개 | 연방 조달 시 SBOM 필수 |
| EU CRA | EU | 디지털 제품의 사이버보안 의무, 취약점 24시간 보고 | 오픈소스 메인테이너 면책 규정 포함 |
| NIST SSDF | 미국 | 보안 소프트웨어 개발 프레임워크 | 개발 프로세스 표준화 가이드 |
| NTIA SBOM | 미국 | SBOM 최소 요소 정의 | 공급자명, 컴포넌트명, 버전, 해시, 관계, 타임스탬프 |
EU CRA와 오픈소스
EU CRA(Cyber Resilience Act)는 오픈소스 소프트웨어의 "상업적 활동" 범위를 중요하게 정의합니다.
- 면책 대상: 비영리 오픈소스 프로젝트 (리눅스 커널 자체의 개발)
- 규제 대상: 커널을 상업 제품에 통합하여 판매하는 기업
- 오픈소스 Steward: Linux Foundation 같은 재단은 "due diligence" 의무 부담
- 취약점 보고: 적극적으로 악용되는 취약점은 24시간 내 ENISA에 보고 의무
기업 컴플라이언스 체크리스트
| 규제 | 필수 요구사항 | 구현 방법 | 증거 자료 |
|---|---|---|---|
| EO 14028 | SBOM 제공 | syft/tern으로 SPDX/CycloneDX 생성 | SBOM JSON 파일 |
| 빌드 환경 보호 | 밀폐 빌드, SLSA L2+ Provenance | 빌드 로그, Provenance 문서 | |
| 취약점 공개 프로세스 | coordinated disclosure 프로세스 문서화 | 보안 정책 문서 | |
| EU CRA | 보안 업데이트 제공 | 최소 5년간 보안 패치 제공 체계 | 업데이트 이력, SLA 문서 |
| 취약점 24시간 보고 | 적극 악용 취약점 발견 시 ENISA 보고 | 사고 대응 프로세스 문서 | |
| 위험 평가 | 제품의 사이버보안 위험 평가 수행 | 위험 평가 보고서 | |
| 기술 문서 | 보안 기능 및 구성에 대한 기술 문서 | 보안 아키텍처 문서 | |
| NIST SSDF | 보안 개발 프로세스 | PO/PS/PW/RV 그룹별 관행 구현 | 자체 증명 양식 |
| 제3자 컴포넌트 관리 | 오픈소스 라이선스/취약점 추적 | SBOM + 취약점 스캔 결과 |
OpenSSF Scorecard
OpenSSF Scorecard는 오픈소스 프로젝트의 보안 관행을 자동으로 평가하는 도구입니다. 커널 관련 프로젝트의 공급망 보안 수준을 객관적으로 측정할 수 있습니다.
# OpenSSF Scorecard 실행
# GitHub 프로젝트의 보안 점수 확인
scorecard --repo=github.com/torvalds/linux
# 주요 체크 항목:
# - Binary-Artifacts: 바이너리 파일 포함 여부
# - Branch-Protection: 브랜치 보호 규칙
# - Code-Review: 코드 리뷰 프로세스
# - Dangerous-Workflow: 위험한 CI 패턴
# - Dependency-Update-Tool: 의존성 업데이트 자동화
# - License: 라이선스 파일 존재
# - Maintained: 프로젝트 유지보수 활성도
# - Pinned-Dependencies: 의존성 해시 핀닝
# - SAST: 정적 분석 도구 사용
# - Security-Policy: SECURITY.md 존재
# - Signed-Releases: 릴리스 서명
# - Token-Permissions: 워크플로우 토큰 최소 권한
# - Vulnerabilities: 알려진 취약점
# 결과 예시:
# Score: 7.5/10
# Branch-Protection: 10/10
# Code-Review: 10/10
# Signed-Releases: 10/10
# Pinned-Dependencies: 5/10
# Vulnerabilities: 8/10
CI/CD 파이프라인 보안
CI/CD(Continuous Integration/Continuous Delivery) 파이프라인은 현대 소프트웨어 공급망의 핵심 구성 요소입니다. 파이프라인이 침해되면 서명 키 유출, 바이너리 변조, 시크릿 탈취 등 치명적인 결과를 초래합니다.
KernelCI 보안
KernelCI는 리눅스 커널의 공식 지속적 통합 테스트 프로젝트입니다. 커널 빌드와 부팅 테스트를 자동화하여 회귀(regression)를 조기에 탐지합니다.
| 보안 영역 | KernelCI 현황 | 위험 | 완화 조치 |
|---|---|---|---|
| 빌드 환경 | Docker 컨테이너 기반 빌드 | 컨테이너 이미지 변조 | 이미지 서명, 레지스트리(Registry) 접근 통제 |
| 테스트 인프라 | 다양한 하드웨어 랩 연동 | 테스트 환경에서의 측면 이동 | 랩별 네트워크 격리, 최소 권한 |
| 결과 리포팅 | 공개 대시보드 | 결과 변조로 잘못된 판단 유도 | 결과 서명, 감사 로그 |
| 소스 페치 | git.kernel.org에서 직접 클론 | 중간자 공격, 미러 변조 | GPG 태그 검증 후 빌드 |
GitHub Actions 위험과 완화
많은 커널 관련 프로젝트(out-of-tree 모듈, 도구 등)가 GitHub Actions를 사용합니다. GitHub Actions의 주요 보안 위험을 이해해야 합니다.
# 위험한 패턴: 태그로 액션 참조 (변조 가능)
# BAD:
# uses: actions/checkout@v4
# 안전한 패턴: 커밋 해시로 핀닝
# GOOD:
# uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# 위험한 패턴: pull_request_target에서 체크아웃 후 빌드
# BAD: PR 작성자의 코드가 시크릿 접근 가능한 환경에서 실행
# on: pull_request_target
# steps:
# - uses: actions/checkout@v4
# with:
# ref: ${{ github.event.pull_request.head.sha }}
# - run: make # 악성 Makefile 실행 위험!
# 안전한 패턴: pull_request 이벤트 사용 (시크릿 접근 불가)
# GOOD:
# on: pull_request
# steps:
# - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# - run: make
CI/CD 하드닝 체크리스트
| 영역 | 권장사항 | 구현 방법 |
|---|---|---|
| 시크릿 관리 | 시크릿을 환경변수로 노출 최소화 | OIDC 토큰, Vault, KMS 사용 |
| 러너 격리 | 일회성 러너(ephemeral runner) 사용 | 각 빌드마다 새 VM/컨테이너 생성 |
| 의존성 핀닝 | 모든 액션/이미지를 해시로 핀닝 | Dependabot/Renovate으로 해시 업데이트 |
| 빌드 로그 | 변조 불가능한 로그 보관 | WORM 스토리지, Rekor 로그 |
| SLSA Provenance | 빌드마다 Provenance 자동 생성 | slsa-github-generator |
| 코드 리뷰 | 워크플로우 파일 변경에 CODEOWNERS 지정 | .github/CODEOWNERS 설정 |
| 네트워크 제한 | 빌드 단계에서 불필요한 네트워크 접근 차단 | 방화벽 규칙, 프록시 사용 |
| 권한 최소화 | 워크플로우 토큰 권한을 read-only 기본값으로 | permissions: read-all |
# 안전한 GitHub Actions 워크플로우 템플릿
name: Kernel Module Build
on:
push:
branches: [main]
pull_request:
branches: [main]
# 기본 권한을 최소화
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
# 커밋 해시로 핀닝
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# 빌드 환경 해시 검증
- name: Verify build tools
run: |
gcc --version
sha256sum $(which gcc) | tee gcc-hash.txt
# 밀폐 빌드 (네트워크 차단은 self-hosted runner에서)
- name: Build module
run: |
make -j$(nproc) M=drivers/my_module
# 서명
- name: Sign module
run: |
scripts/sign-file sha512 \
${{ secrets.MODULE_SIGNING_KEY }} \
certs/signing_key.x509 \
drivers/my_module/my_module.ko
# SLSA Provenance 생성
- uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0
with:
base64-subjects: |
$(sha256sum drivers/my_module/my_module.ko | base64 -w0)
의존성 관리
리눅스 커널은 일반적인 소프트웨어와 달리 외부 라이브러리에 대한 런타임 의존성이 거의 없습니다. 그러나 빌드 도구 체인(Build Toolchain), 펌웨어 blob, DKMS 모듈, 유저스페이스 도구 등에서 공급망 위험이 존재합니다.
커널 의존성 유형
| 의존성 유형 | 예시 | 공급망 위험 | 관리 방법 |
|---|---|---|---|
| 빌드 도구 | GCC, Clang/LLVM, binutils, make | 컴파일러 백도어, 도구 체인 변조 | 배포판 패키지 서명 검증, 버전 핀닝 |
| 빌드 의존성 | flex, bison, libelf, openssl, kmod | 개발 라이브러리 변조 | 패키지 매니저 서명 검증 |
| 펌웨어 blob | linux-firmware 패키지 (WiFi, GPU 등) | 바이너리 감사 불가, 공급업체 의존 | 해시 고정, IMA 서명, 벤더 서명 검증 |
| DKMS 모듈 | NVIDIA, VirtualBox, ZFS | out-of-tree 코드, 제한된 리뷰 | MOK 서명, 소스 감사 |
| initramfs 도구 | dracut, mkinitramfs, systemd | 부팅 환경 변조 | dm-verity, IMA, Secure Boot |
펌웨어 blob 보안
리눅스 커널은 수천 개의 바이너리 펌웨어 파일에 의존합니다. linux-firmware 패키지는 3,000개 이상의 펌웨어 파일을 포함하며, 대부분 소스 코드 없이 바이너리만 제공됩니다.
# linux-firmware 패키지 크기와 파일 수 확인
dpkg -L linux-firmware | wc -l
# 약 3,500+ 파일
# 특정 장치에 필요한 펌웨어 확인
modinfo iwlwifi | grep firmware
# firmware: iwlwifi-ty-a0-gf-a0-86.ucode
# firmware: iwlwifi-ty-a0-gf-a0-72.ucode
# ...
# 펌웨어 파일 해시 기록 (변조 탐지용)
find /lib/firmware -name "*.bin" -o -name "*.fw" -o -name "*.ucode" | \
xargs sha256sum > /etc/firmware-hashes.txt
# IMA로 펌웨어 무결성 감시
# /etc/ima/ima-policy에 추가:
# appraise func=FIRMWARE_CHECK appraise_type=imasig
# 펌웨어 로딩 이벤트 모니터링
dmesg | grep -i firmware
# [ 2.456] iwlwifi: loaded firmware version 72.daa05125.0
DKMS 보안 강화
# DKMS 모듈 소스 감사
# 1. 설치 전 소스 코드 확인
ls /usr/src/nvidia-535.129.03/
cat /usr/src/nvidia-535.129.03/dkms.conf
# 2. 빌드 스크립트에 의심스러운 명령 검색
grep -rn "curl\|wget\|nc \|/dev/tcp\|eval\|base64" \
/usr/src/nvidia-535.129.03/
# 3. DKMS 상태 및 서명 확인
dkms status
# nvidia/535.129.03, 6.8.0-generic, x86_64: installed
# 4. 설치된 모듈의 서명 검증
modinfo /lib/modules/$(uname -r)/updates/dkms/nvidia.ko | \
grep -E "sig|signer|sig_key"
# 5. DKMS 모듈을 빌드할 때 네트워크 접근 차단
# /etc/dkms/framework.conf에 추가:
# PRE_BUILD="unshare --net" # 네트워크 네임스페이스 격리
빌드 도구 체인 검증
# 커널 빌드에 사용된 도구 체인 버전 기록
cat /proc/version
# Linux version 6.8.0 (gcc (GCC) 13.2.0, GNU ld (GNU Binutils) 2.41) ...
# 빌드 도구 해시 기록 (재현 빌드용)
for tool in gcc cc1 as ld make; do
path=$(which $tool 2>/dev/null)
if [ -n "$path" ]; then
echo "$tool: $(sha256sum $path)"
fi
done > toolchain-hashes.txt
# 도구 체인 패키지 서명 검증 (Debian/Ubuntu)
dpkg --verify gcc-13
dpkg --verify binutils
# 도구 체인 패키지 서명 검증 (RHEL/Fedora)
rpm -V gcc
rpm -V binutils
하드웨어 공급망 보안
하드웨어 공급망(Hardware Supply Chain) 보안은 소프트웨어 수준의 방어로는 대응할 수 없는 물리적 위협을 다룹니다. 칩 설계에서 제조, 조립, 배송까지의 과정에서 발생할 수 있는 위변조를 탐지하고 방어합니다.
하드웨어 공급망 위협 분류
| 위협 유형 | 설명 | 공격 단계 | 탐지 난이도 |
|---|---|---|---|
| 칩 트로이 목마(Hardware Trojan) | IC 설계/제조 과정에서 악성 회로 삽입 | 설계 또는 제조 | 매우 높음 |
| 펌웨어 위변조 | BIOS/UEFI, BMC, NIC, SSD 펌웨어 변조 | 제조 또는 운송 | 높음 |
| 위조 부품(Counterfeit) | 비인증 부품이 정품으로 유통 | 유통/조립 | 중간 |
| 물리적 개입 | 운송 중 하드웨어 물리적 변조 | 운송/물류 | 중간 |
| 사이드 채널 임플란트(Implant) | 전력/전자파(EM) 분석용 추가 회로 삽입 | 설계/제조 | 매우 높음 |
리눅스 커널의 하드웨어 보안 기능
# TPM(Trusted Platform Module) 상태 확인
cat /sys/class/tpm/tpm0/tpm_version_major
# 2 (TPM 2.0)
# TPM PCR(Platform Configuration Register) 값 읽기
# PCR에는 부팅 과정의 측정값이 기록됨
tpm2_pcrread sha256:0,1,2,3,4,5,6,7
# Intel TXT(Trusted Execution Technology) 상태
dmesg | grep -i txt
# [ 0.000000] Intel TXT measured launch: TRUE
# AMD SEV(Secure Encrypted Virtualization) 상태
dmesg | grep -i sev
# [ 1.234] SEV: API=1.51 build=4
# ARM TrustZone 상태 (OP-TEE)
ls /dev/tee*
# /dev/tee0 /dev/teepriv0
# 하드웨어 인벤토리 수집 (공급망 감사용)
lspci -vvv | grep -E "Subsystem|Serial Number"
dmidecode -t system | grep -E "Serial|Manufacturer|Product"
dmidecode -t baseboard | grep -E "Serial|Manufacturer"
하드웨어 검증 기법
| 기법 | 설명 | 적용 대상 | 한계 |
|---|---|---|---|
| 물리적 검사 | X-ray, 현미경, 전자 현미경으로 칩 구조 확인 | 의심스러운 IC | 비용 높음, 비파괴 검사 어려움 |
| 사이드 채널 분석 | 전력 소비, 전자파 패턴으로 이상 탐지 | 동작 중인 칩 | 베이스라인 필요, 위양성 가능 |
| 기능 테스트 | 예상 동작과 실제 동작의 전수(exhaustive) 비교 | 복잡하지 않은 IC | 현대 칩의 상태 공간이 너무 방대 |
| RTL 비교 | 설계 파일(RTL)과 실제 칩의 레이아웃 비교 | 자체 설계 ASIC | 파운드리 접근 필요 |
| Measured Boot | TPM PCR에 부팅 체인의 각 단계를 측정 기록 | 서버, IoT | TPM 자체의 신뢰 필요 |
| 원격 증명(Remote Attestation) | TPM 기반으로 원격 시스템의 상태를 검증 | 클라우드, 분산 시스템 | 인프라 구축 필요 |
Measured Boot와 원격 증명
# Measured Boot: 부팅 과정의 각 단계를 TPM PCR에 기록
# PCR 0: BIOS/UEFI 코드
# PCR 1: BIOS/UEFI 설정
# PCR 2: 옵션 ROM
# PCR 4: MBR/부트로더
# PCR 5: 부트로더 설정
# PCR 7: Secure Boot 상태
# PCR 8-9: GRUB, 커널, initramfs
# IMA를 통한 커널 수준 측정
cat /sys/kernel/security/ima/ascii_runtime_measurements | head -5
# 10 sha256:abc123... ima-ng sha256:def456... /sbin/init
# 10 sha256:abc789... ima-ng sha256:ghi012... /lib/modules/6.8/kernel/...
# 원격 증명 (keylime 사용)
# 1. keylime-agent 설치 (대상 시스템)
keylime_agent --uuid d432fbb3-d2f1-4a97-9ef7-75bd81c00000
# 2. keylime-verifier에 에이전트 등록 (검증 서버)
keylime_tenant -c add --uuid d432fbb3-d2f1-4a97-9ef7-75bd81c00000 \
--tpm_policy '{"mask": "0x408000", "22": ["sha256:..."]}'
# 3. IMA 정책과 연동하여 파일 변조 탐지
keylime_tenant -c update --uuid d432fbb3-d2f1-4a97-9ef7-75bd81c00000 \
--ima_sign_verification_keys /etc/keys/ima-pub.pem
배포판 보안 프로세스 상세
주요 리눅스 배포판은 커널 패키지의 빌드, 서명, 배포에 각기 다른 보안 프로세스를 적용합니다. 이 프로세스를 이해하면 배포판 수준의 공급망 신뢰 체인을 평가할 수 있습니다.
Debian 커널 보안 프로세스
| 단계 | 프로세스 | 보안 조치 |
|---|---|---|
| 소스 확보 | upstream tarball + Debian 패치 시리즈 | GPG 서명 검증, orig.tar.xz 해시 확인 |
| 패치 관리 | debian/patches/ quilt 시리즈 | 보안 팀 리뷰, DSA(Debian Security Advisory) 프로세스 |
| 빌드 | sbuild + buildd 네트워크 | chroot 격리, 빌드 로그 공개, 재현 빌드 추적 |
| 서명 | Debian Archive 자동 서명 | 오프라인 마스터 키, 연간 갱신 서브키 |
| 배포 | deb.debian.org + 미러 네트워크 | Release 파일 GPG 서명, Packages 해시 체인 |
| Secure Boot | shim → GRUB → 커널 | Debian signing key로 커널/모듈 서명 |
# Debian 커널 패키지 보안 검증 체크리스트
# 1. APT 저장소 서명 검증 (InRelease 파일)
apt-key list 2>/dev/null | grep -A2 "Debian"
# 또는 새로운 방식:
ls /etc/apt/trusted.gpg.d/
# 2. 패키지 해시 체인 확인
# Release → Packages.xz → .deb 파일
cat /var/lib/apt/lists/*Release | grep -A5 SHA256
# 3. 설치된 패키지 무결성 검증
dpkg --verify linux-image-$(uname -r) 2>&1
# 출력이 없으면 정상 (변조된 파일이 없음)
# 4. Debian 보안 업데이트 소스 확인
grep security /etc/apt/sources.list
# deb http://security.debian.org/debian-security bookworm-security main
# 5. 커널 패키지의 출처(provenance) 확인
apt-cache policy linux-image-$(uname -r)
# Installed: 6.1.76-1
# Candidate: 6.1.76-1
# 500 http://security.debian.org/... bookworm-security/main
Fedora/RHEL 커널 보안 프로세스
| 단계 | 프로세스 | 보안 조치 |
|---|---|---|
| 소스 확보 | upstream + Fedora/RHEL 패치 셋 | src.rpm GPG 서명, dist-git 접근 통제 |
| 빌드 | Koji 빌드 시스템 | mock chroot 격리, 빌드 로그 공개 |
| 테스트 | Bodhi 업데이트 시스템 | gating 테스트, 커뮤니티 카르마 시스템 |
| 서명 | Fedora/Red Hat GPG 키 | 오프라인 HSM(Hardware Security Module) 서명 |
| 배포 | Fedora 미러 / RHEL CDN | repomd.xml GPG 서명, metalink HTTPS |
| Secure Boot | shim → GRUB → 커널 | Red Hat signing key (Microsoft 교차 서명) |
# Fedora/RHEL 커널 보안 검증
# 1. RPM GPG 서명 검증
rpm -K kernel-core-$(uname -r).rpm
# kernel-core-6.8.0-1.fc40.x86_64.rpm: digests signatures OK
# 2. 패키지 변조 검증
rpm -V kernel-core-$(uname -r)
# 출력이 없으면 정상
# 3. Koji 빌드 정보 확인
koji buildinfo kernel-6.8.0-1.fc40
# Build: kernel-6.8.0-1.fc40
# Built by: bodhi
# State: complete
# Build Host: buildvm-x86-01.iad2.fedoraproject.org
# 4. Bodhi 업데이트 상태 확인
bodhi updates query --packages kernel --status stable --releases f40
# 5. dnf/yum 저장소 서명 확인
rpm -qa gpg-pubkey* --qf "%{NAME}-%{VERSION}-%{RELEASE} %{SUMMARY}\n"
Ubuntu 커널 보안 프로세스
| 단계 | 프로세스 | 보안 조치 |
|---|---|---|
| 소스 확보 | upstream stable + Canonical 패치 | kernel.org GPG 검증, git 기반 관리 |
| 빌드 | Launchpad 빌드 팜 | 격리된 빌드 환경, 자동화된 파이프라인 |
| 테스트 | Canonical QA, SRU(Stable Release Update) 프로세스 | 회귀 테스트, 7일 대기 기간 |
| 서명 | Ubuntu Archive 키 | 오프라인 마스터 키, Launchpad PPA 서명 분리 |
| Livepatch | 커널 라이브패치 서비스 | Canonical 서명된 패치, HTTPS 전송 |
| Secure Boot | shim → GRUB → 커널 | Canonical signing key (Microsoft 교차 서명) |
대응 체계
공급망 보안 사고가 발생했을 때의 대응 체계는 피해를 최소화하는 핵심입니다. 사고 탐지, 분석, 격리, 복구, 사후 분석의 체계적인 프로세스가 필요합니다.
공급망 사고 대응 프로세스
침해 지표 (IoC: Indicators of Compromise)
공급망 공격의 침해 지표는 전통적인 보안 사고와 다른 특성을 가집니다. 변조된 코드가 정상 배포 채널을 통해 전달되므로, 네트워크 수준의 탐지가 어렵습니다.
| IoC 유형 | 예시 | 탐지 방법 |
|---|---|---|
| 파일 해시 불일치 | 바이너리의 SHA-256이 공식 해시와 다름 | SBOM 기반 해시 검증, IMA 측정 |
| 서명 이상 | 예상과 다른 서명자, 만료된 서명 | gpg --verify, cosign verify |
| 빌드 비결정성 | 재현 빌드 시 다른 바이너리 생성 | diffoscope, reprotest |
| 이상 네트워크 활동 | 커널 모듈이 예상 외 네트워크 연결 시도 | netfilter 로그, eBPF 모니터링 |
| 비정상 시스콜 | 커널 코드 경로에서 예상 외 시스콜 패턴 | seccomp-bpf, audit 로그 |
| 파일 시스템 변조 | /lib/modules/ 또는 /lib/firmware/ 파일 변경 | dm-verity, IMA appraise |
| Provenance 부재 | SLSA Provenance 없는 빌드 산출물 | slsa-verifier 정책 적용 |
포렌식(Forensics) 절차
# 커널 공급망 침해 포렌식 체크리스트
# 1. 현재 커널 무결성 확인
uname -a
cat /proc/version
sha256sum /boot/vmlinuz-$(uname -r)
# 2. 로드된 모듈의 서명 상태 확인
for mod in $(lsmod | awk 'NR>1 {print $1}'); do
sig=$(modinfo $mod 2>/dev/null | grep "sig_id" | awk '{print $2}')
if [ -z "$sig" ]; then
echo "UNSIGNED: $mod"
else
echo "SIGNED: $mod ($sig)"
fi
done
# 3. IMA 측정 로그 분석 (변조된 파일 탐지)
cat /sys/kernel/security/ima/violations
# 0이 아니면 무결성 위반 발생
cat /sys/kernel/security/ima/ascii_runtime_measurements | \
grep -v "sha256:0000" | tail -20
# 4. 커널 모듈 파일 변조 확인
rpm -V kernel-modules-$(uname -r) 2>/dev/null # RHEL/Fedora
dpkg --verify linux-modules-$(uname -r) 2>/dev/null # Debian/Ubuntu
# 5. 비정상 커널 스레드 확인
ps aux | awk '$11 ~ /^\[/ {print}'
# 예상 외 커널 스레드가 있으면 조사
# 6. dmesg에서 보안 관련 이벤트 검색
dmesg | grep -iE "taint|lockdown|integrity|ima|seccomp|module.sig"
# 7. Secure Boot 체인 확인
mokutil --sb-state
mokutil --list-enrolled # 등록된 MOK 키 확인
# 예상 외 키가 있으면 침해 의심
# 8. 메모리 덤프(Memory Dump) 수집 (고급)
# LiME(Linux Memory Extractor)로 물리 메모리 덤프
insmod lime.ko "path=/tmp/mem.dump format=lime"
# Volatility3로 분석
vol -f /tmp/mem.dump linux.bash
vol -f /tmp/mem.dump linux.lsmod
사고 대응 커뮤니케이션
| 대상 | 채널 | 내용 | 시점 |
|---|---|---|---|
| 커널 보안 팀 | security@kernel.org | 기술적 상세, 침해 증거 | 즉시 |
| 배포판 보안 팀 | linux-distros@ (엠바고) | 영향 범위, 패치 계획 | 패치 준비 후 |
| 공개 커뮤니티 | oss-security@ | 사고 보고서, CVE | 엠바고 해제 후 |
| 규제 기관 | ENISA (EU CRA), CISA (미국) | 사고 보고서 | 24시간 내 (EU CRA) |
| 사용자 | 배포판 공지, 보안 권고문(Advisory) | 업데이트 안내, 완화 조치 | 패치 공개 즉시 |
코드 서명과 검증
코드 서명(Code Signing)은 소프트웨어 공급망 보안의 가장 기본적인 메커니즘입니다. 리눅스 커널 생태계에서는 GPG 서명, 모듈 서명, kexec 서명, Secure Boot 등 다층적인 서명 체계가 존재합니다.
Secure Boot 서명 체인
UEFI Secure Boot는 부팅 과정의 각 단계를 암호학적으로 검증하는 체인입니다. 리눅스 커널은 이 체인의 핵심 구성 요소입니다.
UEFI 펌웨어 (PK: Platform Key)
└── Microsoft UEFI CA (KEK → db)
└── shim (Microsoft 교차 서명 + 배포판 키)
└── GRUB2 (배포판 Secure Boot 키로 서명)
└── 커널 (vmlinuz, 배포판 키로 서명)
└── 커널 모듈 (.ko, 빌드 키 또는 MOK로 서명)
└── 펌웨어 (IMA 또는 드라이버 자체 검증)
# Secure Boot 서명 체인 검증
# 1. UEFI Secure Boot 상태
mokutil --sb-state
# SecureBoot enabled
# 2. 등록된 키 확인
# PK (Platform Key)
mokutil --pk
# KEK (Key Exchange Key)
mokutil --kek
# db (Signature Database)
mokutil --db
# 3. shim 서명 확인
sbverify --cert /usr/share/secureboot/keys/canonical.pem \
/boot/efi/EFI/ubuntu/shimx64.efi
# 4. GRUB 서명 확인
sbverify --cert /usr/share/secureboot/keys/canonical.pem \
/boot/efi/EFI/ubuntu/grubx64.efi
# 5. 커널 서명 확인
sbverify --cert /usr/share/secureboot/keys/canonical.pem \
/boot/vmlinuz-$(uname -r)
# 6. sbsign으로 커스텀 커널 서명
sbsign --key MOK.priv --cert MOK.pem --output vmlinuz-signed vmlinuz
kexec 서명 검증
kexec는 실행 중인 커널에서 새 커널로 직접 전환하는 메커니즘입니다. Secure Boot 환경에서는 kexec로 로드하는 커널도 서명 검증이 필요합니다.
# kexec 관련 Kconfig 옵션
# CONFIG_KEXEC=y # kexec 시스콜 활성화
# CONFIG_KEXEC_SIG=y # kexec 이미지 서명 검증
# CONFIG_KEXEC_SIG_FORCE=y # 서명 없는 kexec 차단
# CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y # bzImage 서명 검증
# kexec 서명된 커널 로드
kexec -l /boot/vmlinuz-6.8.0-generic \
--initrd=/boot/initrd.img-6.8.0-generic \
--command-line="$(cat /proc/cmdline)"
# 서명 검증 실패 시:
# kexec: Signature verification failed
# kexec_load: Operation not permitted
# Lockdown LSM과 kexec
cat /sys/kernel/security/lockdown
# [integrity] confidentiality none
# integrity 모드: 서명되지 않은 kexec 차단
# confidentiality 모드: 모든 kexec 차단
서명 키 관리 모범 사례
| 키 유형 | 저장 위치 | 접근 통제 | 갱신 주기 | 폐기 절차 |
|---|---|---|---|---|
| GPG 마스터 키 | 오프라인 에어갭 시스템 | 물리적 접근 제한 | 5-10년 | 폐기 인증서 배포 |
| GPG 서브키 | YubiKey / Nitrokey | PIN + 터치 요구 | 1-2년 | 마스터 키로 새 서브키 생성 |
| 모듈 서명 키 | 빌드 서버 (빌드 후 삭제) | root 전용, 600 권한 | 매 빌드 | 커널 이미지에 공개키만 내장 |
| MOK | UEFI NVRAM | MOK 비밀번호 | 1-10년 | mokutil --delete |
| Secure Boot 키 | UEFI 펌웨어 db | PK 소유자만 수정 | 배포판 키 갱신 시 | dbx에 해시 추가 |
| IMA 서명 키 | HSM 또는 보호된 파일 | 보안 관리자 전용 | 조직 정책 따름 | 키 폐기 후 재서명 |
실전 체크리스트
개발자/메인테이너 체크리스트
| 항목 | 설명 | 도구 | |
|---|---|---|---|
| 1 | GPG/SSH 키 설정 | 커밋/태그 서명 활성화 | git config commit.gpgsign true |
| 2 | 하드웨어 보안 키 | GPG 키를 YubiKey/Nitrokey에 저장 | gpg --card-edit |
| 3 | 2FA 활성화 | kernel.org, GitHub 등 모든 계정 | TOTP 또는 FIDO2 |
| 4 | DCO 서명 | 모든 패치에 Signed-off-by 추가 | git commit -s |
| 5 | 패치 리뷰 | 최소 1인 이상 리뷰 후 병합 | 메일링 리스트 / PR 리뷰 |
빌드/배포 체크리스트
| 항목 | 설명 | 도구 | |
|---|---|---|---|
| 1 | 소스 검증 | 빌드 전 태그/타르볼 GPG 서명 검증 | git tag -v, gpg --verify |
| 2 | 밀폐 빌드 | 격리된 환경에서 네트워크 차단 빌드 | podman/docker --network=none |
| 3 | 재현 빌드 | SOURCE_DATE_EPOCH 등 비결정성 제거 | diffoscope, reprotest |
| 4 | 모듈 서명 | MODULE_SIG_FORCE 활성화 | sign-file, MOK |
| 5 | SBOM 생성 | SPDX/CycloneDX 형식으로 생성 | syft, tern |
| 6 | Provenance | SLSA Provenance 메타데이터 생성 | slsa-verifier, in-toto |
| 7 | 패키지 서명 | 배포 패키지에 GPG 서명 | dpkg-sig, rpm --sign |
| 8 | 이미지 서명 | 컨테이너 이미지에 cosign 서명 | cosign, notation |
운영 체크리스트
| 항목 | 설명 | 도구 | |
|---|---|---|---|
| 1 | Secure Boot | UEFI Secure Boot 활성화 + MOK 관리 | mokutil, sbsign |
| 2 | IMA/EVM | 런타임 파일 무결성 검증 | evmctl, ima-policy |
| 3 | dm-verity | 블록 레벨 무결성 (읽기전용 파티션) | veritysetup |
| 4 | 취약점 모니터링 | SBOM 기반 CVE 추적 | grype, trivy, OSV |
| 5 | 자동 업데이트 | 보안 패치 자동 적용 체계 | unattended-upgrades, dnf-automatic |
트러블슈팅
일반 문제
| 증상 | 원인 | 해결 방법 |
|---|---|---|
gpg: BAD signature | 타르볼 손상 또는 변조 | 다시 다운로드 후 재검증, 다른 미러 사용 |
gpg: Can't check signature: No public key | 서명자 GPG 키 미등록 | gpg --recv-keys <KEY_ID> |
모듈 로드 실패: module verification failed | MODULE_SIG_FORCE + 미서명 모듈 | sign-file로 서명하거나 MOK 등록 |
| DKMS 모듈 Secure Boot 거부 | MOK 미등록 | mokutil --import 후 재부팅 시 비밀번호 입력 |
펌웨어 로드 실패: firmware: failed to load | IMA 정책 위반 또는 파일 누락 | IMA 서명 추가하거나, /lib/firmware/에 파일 확인 |
cosign verify 실패 | 인증서 만료 또는 OIDC issuer 불일치 | --certificate-oidc-issuer 정확히 지정 |
GPG 에이전트 문제
# gpg-agent 상태 확인
gpg-connect-agent 'getinfo version' /bye
# 에이전트 재시작
gpgconf --kill gpg-agent
gpg-agent --daemon
# SSH를 통한 원격 서명 시 GPG_TTY 설정 필수
export GPG_TTY=$(tty)
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
# pinentry 프로그램 확인/변경
echo "pinentry-program /usr/bin/pinentry-curses" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
모듈 서명 디버깅(Debugging)
# 모듈 서명 정보 상세 확인
modinfo -F sig_id,signer,sig_key,sig_hashalgo nvidia.ko
# 커널 키링에 등록된 키 확인
keyctl list %:.builtin_trusted_keys
keyctl list %:.secondary_trusted_keys
keyctl list %:.machine
# IMA 감사 로그로 펌웨어/모듈 검증 실패 추적
dmesg | grep -E "integrity|ima|module"
# Secure Boot 상태 확인
mokutil --sb-state
# SecureBoot enabled
재현 빌드 디버깅
# diffoscope로 차이점 상세 분석
diffoscope --html-dir report/ vmlinux-build1 vmlinux-build2
# 일반적인 비결정성 확인
readelf -p .comment vmlinux # 컴파일러 버전
strings vmlinux | grep -E "Linux version|Build" # 빌드 문자열
objdump -s -j .note.gnu.build-id vmlinux # Build ID
# 환경변수 누락 확인
echo "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH"
echo "KBUILD_BUILD_TIMESTAMP=$KBUILD_BUILD_TIMESTAMP"
echo "KBUILD_BUILD_USER=$KBUILD_BUILD_USER"
echo "KBUILD_BUILD_HOST=$KBUILD_BUILD_HOST"
서명 관련 고급 트러블슈팅
| 증상 | 원인 | 진단 명령 | 해결 방법 |
|---|---|---|---|
gpg: decryption failed: No secret key | 서명 키가 GPG 키링에 없음 (YubiKey 미삽입 등) | gpg --card-status | YubiKey 삽입 또는 키 가져오기 |
error: gpg failed to sign the data | gpg-agent 미실행 또는 TTY 불일치 | gpg-connect-agent /bye | export GPG_TTY=$(tty) 후 재시도 |
Secure Boot 시 Verification failed | 커널/모듈이 db/MOK에 등록된 키로 서명되지 않음 | mokutil --list-enrolled | 올바른 키로 재서명 또는 MOK 등록 |
PKCS#7 signature not signed with a trusted key | 모듈 서명 키가 커널 키링에 없음 | keyctl list %:.builtin_trusted_keys | 서명 키의 공개키를 커널에 내장 후 재빌드 |
IMA: BAD SIGNATURE | 파일의 IMA 서명이 유효하지 않음 (파일 변경됨) | getfattr -m security.ima -d <file> | evmctl ima_sign으로 재서명 |
cosign: no matching signatures | 인증서 ID/OIDC issuer 불일치 | cosign triangulate <image> | --certificate-identity와 --certificate-oidc-issuer 정확히 지정 |
slsa-verifier: FAILED | Provenance의 빌더 ID 또는 소스 URI 불일치 | Provenance JSON 수동 검사 | --source-uri, --builder-id 옵션 확인 |
Secure Boot 문제 해결
# Secure Boot 상태 확인
mokutil --sb-state
# Secure Boot이 활성화되어 있는데 커널 부팅 실패 시
# 1. shim이 올바르게 설치되어 있는지 확인
ls -la /boot/efi/EFI/*/shimx64.efi
# 2. GRUB이 shim에 의해 서명되었는지 확인
sbverify --list /boot/efi/EFI/*/grubx64.efi
# 3. 커널이 서명되었는지 확인
sbverify --list /boot/vmlinuz-$(uname -r)
# 4. dbx (폐기 목록)에 키가 포함되어 있는지 확인
mokutil --list-delete 2>/dev/null
# 5. 로그에서 Secure Boot 관련 오류 확인
journalctl -b | grep -iE "secureboot|secure boot|lockdown|shim"
# 6. UEFI 변수 직접 확인 (고급)
efivar -l | grep -i secure
efivar -p -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-SecureBoot
# 7. 임시 해결: MOK에 키 등록
# (커스텀 커널 사용 시)
mokutil --import /path/to/my-signing-key.der
# 재부팅 후 MokManager에서 등록 확인
SBOM 및 Provenance 트러블슈팅
# SBOM 검증 문제 해결
# 1. SBOM 형식 유효성 검증
# SPDX
java -jar tools-java-*.jar Verify kernel-sbom.spdx.json
# 또는 Python 도구:
pyspdxtools parse kernel-sbom.spdx.json
# CycloneDX
cyclonedx-cli validate --input-file kernel-sbom.cdx.json \
--fail-on-errors
# 2. NTIA 최소 요소 누락 확인
ntia-checker -v kernel-sbom.spdx.json 2>&1 | grep FAIL
# FAIL: 공급자 이름 누락
# FAIL: 타임스탬프 누락
# 3. grype 스캔 시 오탐(false positive) 처리
# .grype.yaml 설정 파일로 무시 규칙 추가
cat > .grype.yaml << 'EOF'
ignore:
- vulnerability: CVE-2024-XXXX
reason: "CONFIG_SCSI=n: 해당 서브시스템 미포함"
EOF
grype sbom:kernel-sbom.spdx.json -c .grype.yaml
# 4. Provenance 검증 실패 시 디버깅
slsa-verifier verify-artifact linux-6.8.tar.xz \
--provenance-path prov.jsonl \
--source-uri github.com/torvalds/linux \
--print-provenance 2>&1 | head -50
# Provenance 내용을 수동으로 확인하여 불일치 필드 파악
미래 전망
리눅스 커널 공급망 보안은 빠르게 진화하고 있습니다. 규제 강화, 새로운 암호화 기술, 자동화 도구의 발전이 향후 변화를 주도할 것입니다.
주요 동향
| 영역 | 현재 (2024-2026) | 단기 전망 (2027-2028) | 장기 전망 (2029+) |
|---|---|---|---|
| 서명 방식 | GPG 중심, Sigstore 실험 | GPG + Sigstore 하이브리드 | 포스트 양자 암호로 전환 |
| 빌드 검증 | 부분적 재현 빌드 | 주요 배포판 재현 빌드 의무화 | SLSA L4 달성 추구 |
| SBOM | 자발적 생성 | EU CRA/EO 14028 의무화 | 실시간 SBOM + VEX 자동 업데이트 |
| 해시 알고리즘 | SHA-1 (Git), SHA-256/512 (서명) | Git SHA-256 전환 가속 | SHA-3 또는 포스트 양자 해시 |
| 하드웨어 검증 | TPM 2.0, Secure Boot | 원격 증명 표준화 | RISC-V 오픈 하드웨어 검증 |
| AI 보안 | 정적 분석 보조 | AI 기반 코드 리뷰 보조 | 자동화된 취약점 탐지/패치 |
포스트 양자 암호화 대비
양자 컴퓨터(Quantum Computer)가 실용화되면 현재의 RSA/ECDSA 기반 서명이 무력화될 수 있습니다. 커널 공급망에서 사용하는 암호화 알고리즘의 양자 내성(Quantum Resistance) 전환이 필요합니다.
| 현재 알고리즘 | 용도 | 양자 위협 | 대체 후보 (NIST PQC) |
|---|---|---|---|
| RSA-2048/4096 | GPG 서명, 모듈 서명 | Shor 알고리즘으로 해독 가능 | ML-DSA (CRYSTALS-Dilithium) |
| ECDSA (P-256) | SSH 서명, TLS | Shor 알고리즘으로 해독 가능 | SLH-DSA (SPHINCS+) |
| Ed25519 | SSH/GPG 서명 | Shor 알고리즘으로 해독 가능 | ML-DSA / FALCON |
| SHA-256 | 해시, SBOM 다이제스트 | Grover 알고리즘으로 약화 (128비트 수준) | SHA-3-256 (충분한 보안 마진) |
# 리눅스 커널의 포스트 양자 암호 지원 현황
# 커널 6.x에서의 PQC 관련 CONFIG 옵션
# 커널 내 지원 알고리즘 확인
cat /proc/crypto | grep -E "name|driver" | head -40
# ML-KEM (CRYSTALS-Kyber) 지원 확인 (TLS 키 교환용)
grep -r "KYBER\|ML_KEM" /usr/src/linux/crypto/ 2>/dev/null
# 향후 커널 모듈 서명에 PQC 알고리즘 사용 시나리오
# 1. 하이브리드 서명: 기존 RSA + ML-DSA 이중 서명
# 2. 전환기: 두 알고리즘 모두 검증, 하나라도 성공하면 통과
# 3. 완전 전환: PQC 알고리즘만 사용
RISC-V와 오픈 하드웨어 공급망
RISC-V는 오픈 ISA(Instruction Set Architecture)로서 하드웨어 설계의 투명성을 높일 수 있습니다. 오픈 하드웨어 기반의 공급망은 전통적인 블랙박스(Black Box) 하드웨어보다 감사와 검증이 용이합니다.
- 설계 감사 가능: RTL 소스 코드가 공개되어 백도어 삽입 여부를 독립적으로 검증 가능
- 재현 가능 칩 제조: 동일 설계에서 동일 FPGA 비트스트림 생성 가능 (시뮬레이션 수준)
- 커뮤니티 감사: 다수의 독립적인 리뷰어가 하드웨어 설계를 검증
- 리눅스 커널 지원: RISC-V 아키텍처는 커널 6.x에서 완전 지원, 부팅부터 보안 기능까지
공급망 보안 성숙도 평가 모델
조직의 커널 공급망 보안 수준을 평가하는 성숙도 모델을 다음과 같이 정의할 수 있습니다.
| 성숙도 단계 | 설명 | 주요 활동 | 필요 도구 |
|---|---|---|---|
| Level 0: 기초 | 공급망 보안 인식 없음 | 배포판 패키지 사용, 기본 업데이트 | apt/dnf |
| Level 1: 기본 검증 | 패키지 서명 검증, GPG 키 관리 | 커밋 서명, 타르볼 GPG 검증 | GPG, git verify-tag |
| Level 2: 빌드 보호 | 빌드 환경 격리, 모듈 서명 | 밀폐 빌드, MODULE_SIG_FORCE, MOK | podman, sign-file, mokutil |
| Level 3: 전체 추적 | SBOM 생성, 취약점 자동 추적 | SBOM 파이프라인, VEX, 재현 빌드 | syft, grype, diffoscope |
| Level 4: 지속 검증 | SLSA L3+, 자동 원격 증명 | Provenance 서명, IMA, TPM 원격 증명 | Sigstore, keylime, slsa-verifier |
| Level 5: 완전 검증 | SLSA L4 + PQC + 하드웨어 검증 | 포스트 양자 서명, 오픈 하드웨어 | ML-DSA, RISC-V 검증 도구 |
조직별 권장 수준
| 조직 유형 | 권장 성숙도 | 핵심 요구사항 |
|---|---|---|
| 개인 개발자 | Level 1 | GPG 커밋 서명, 태그 검증 |
| 스타트업/소기업 | Level 2 | 밀폐 빌드, Secure Boot |
| 일반 기업 | Level 3 | SBOM, 취약점 추적, EU CRA 준수 |
| 금융/의료 | Level 4 | SLSA L3, 원격 증명, 감사 로그 |
| 정부/군사/인프라 | Level 4-5 | 완전 검증, 하드웨어 감사, PQC 대비 |
참고 자료
| 자료 | 설명 | URL |
|---|---|---|
| SLSA 공식 사이트 | SLSA 프레임워크 스펙과 가이드 | slsa.dev |
| Sigstore | Keyless 서명 인프라 | sigstore.dev |
| Reproducible Builds | 재현 가능 빌드 프로젝트 | reproducible-builds.org |
| OpenSSF | 오픈소스 보안 재단 | openssf.org |
| kernel.org 보안 | 커널 보안 정책 및 키 목록 | kernel.org/category/signatures |
| NIST SSDF | 보안 소프트웨어 개발 프레임워크 | NIST SP 800-218 |
| EU CRA | 사이버 회복력 법안 전문 | EUR-Lex 32024R2847 |
| in-toto | 공급망 레이아웃 검증 프레임워크 | in-toto.io |
| TUF | 안전한 업데이트 프레임워크 | theupdateframework.io |
| OSV.dev | 오픈소스 취약점 데이터베이스 | osv.dev |
관련 문서
외부 참고 자료
- SLSA (Supply-chain Levels for Software Artifacts) — 소프트웨어 공급망 보안 프레임워크 공식 사이트입니다
- Sigstore — 소프트웨어 아티팩트 서명 및 검증 프로젝트입니다
- in-toto — 소프트웨어 공급망 무결성 보호 프레임워크입니다
- Kernel Module Signing — Admin Guide — 커널 모듈 서명 검증 공식 문서입니다
- Reproducible Builds — 재현 가능한 빌드 프로젝트 공식 사이트입니다
- SPDX (Software Package Data Exchange) — SBOM 표준 포맷 공식 사이트입니다
- CycloneDX — OWASP의 SBOM 표준 프로젝트입니다
- OpenSSF (Open Source Security Foundation) — 오픈소스 소프트웨어 보안 재단 공식 사이트입니다
- OpenSSF Scorecard — 오픈소스 프로젝트 보안 평가 도구입니다
- Linux 커널 sign-file.c — 커널 모듈 서명 도구 소스 코드입니다
- CISA SBOM Resources — 미국 CISA의 SBOM 관련 자료 및 가이드라인입니다
- deps.dev — Google의 오픈소스 의존성 보안 분석 서비스입니다
용어 사전
| 용어 | 영문 | 설명 |
|---|---|---|
| 공급망 공격 | Supply Chain Attack | 소프트웨어 개발/빌드/배포 과정에 악성 코드를 삽입하는 공격 |
| 출처 증명 | Provenance | 소프트웨어가 어디서, 어떻게, 누구에 의해 만들어졌는지의 메타데이터 |
| 재현 가능 빌드 | Reproducible Build | 동일 소스/환경에서 비트 단위로 동일한 바이너리를 생성하는 것 |
| 밀폐 빌드 | Hermetic Build | 외부 네트워크/자원 접근 없이 격리된 환경에서 수행하는 빌드 |
| 침해 지표 | IoC (Indicators of Compromise) | 보안 사고 발생을 나타내는 기술적 증거 |
| 엠바고 | Embargo | 보안 취약점 정보의 공개를 일정 기간 유예하는 약속 |
| SBOM | Software Bill of Materials | 소프트웨어에 포함된 모든 구성 요소의 목록 |
| VEX | Vulnerability Exploitability eXchange | 취약점의 실제 악용 가능성을 명시하는 문서 |
| MOK | Machine Owner Key | Secure Boot에서 사용자가 등록하는 키 |
| CNA | CVE Numbering Authority | CVE 번호를 할당할 권한이 있는 조직 |
| DCO | Developer Certificate of Origin | 기여자가 코드의 라이선스 적합성을 선언하는 서명 |
| SLSA | Supply-chain Levels for Software Artifacts | 공급망 보안 성숙도를 4단계로 정의하는 프레임워크 |
| HSM | Hardware Security Module | 암호화 키를 안전하게 저장/관리하는 하드웨어 장치 |
| TPM | Trusted Platform Module | 보안 측정/저장을 위한 하드웨어 칩 |
| PCR | Platform Configuration Register | TPM 내 부팅 측정값을 저장하는 레지스터 |
| PQC | Post-Quantum Cryptography | 양자 컴퓨터에 내성을 가지는 암호화 알고리즘 |
| 원격 증명 | Remote Attestation | 원격 시스템의 무결성 상태를 암호학적으로 검증하는 기법 |
| 타이포스쿼팅 | Typosquatting | 유사한 이름으로 악성 패키지를 배포하는 공격 기법 |
| 사회공학 | Social Engineering | 인간의 심리를 이용하여 보안을 우회하는 공격 기법 |
| SSDF | Secure Software Development Framework | NIST가 제정한 보안 소프트웨어 개발 프레임워크 (SP 800-218) |
| CRA | Cyber Resilience Act | EU의 디지털 제품 사이버보안 의무화 법안 |
| Web of Trust | Web of Trust | 분산형 PKI 모델로 사용자 간 상호 서명으로 신뢰 구축 |
| OIDC | OpenID Connect | OAuth 2.0 기반 인증 프로토콜, Sigstore에서 사용 |
| Merkle Tree | Merkle Tree | 해시 기반 이진 트리로 데이터 무결성을 효율적으로 검증하는 자료구조 |
| ifunc | GNU Indirect Function | 런타임에 함수 구현을 선택하는 GNU 확장 (XZ Utils 백도어에 악용) |
| Lockdown LSM | Lockdown Security Module | 커널의 무결성/기밀성을 보호하기 위해 특정 작업을 제한하는 LSM |
| taint 플래그 | Kernel Taint Flag | 커널 상태를 오염시킬 수 있는 사건을 표시하는 플래그 (예: 미서명 모듈) |