IMA/EVM (무결성(Integrity) 검증)

IMA(Integrity Measurement Architecture)와 EVM(Extended Verification Module)은 리눅스 커널의 무결성 서브시스템(integrity subsystem)의 핵심 구성요소입니다. IMA는 파일을 측정(measure), 평가(appraise), 감사(audit)하고, EVM은 보안 확장 속성(xattr)의 변조를 감지합니다. TPM과 결합하면 부팅부터 런타임까지 이어지는 신뢰 체인(chain of trust)을 형성하여, 원격 증명(remote attestation)과 FIPS 140-3, Common Criteria 등 컴플라이언스 요구사항을 충족합니다.

전제 조건: 커널 보안 개요를 이해하고 있다고 가정합니다. TPM 기초는 TPM 2.0, 암호화(Encryption) 기반은 Crypto API 페이지(Page)를 참고하세요.
일상 비유: IMA/EVM은 공증된 봉인 택배와 비슷합니다. IMA는 택배 내용물의 해시(체크섬(Checksum))를 기록하고, EVM은 봉인 테이프(HMAC/서명)로 포장을 보호하며, TPM은 공증인 역할로 측정 기록을 변조 불가능하게 저장합니다. 수령자(원격 증명 서버)는 공증 기록을 확인하여 배송 중 변조가 없었는지 검증합니다.

핵심 요약

  • IMA Measure — 파일 해시를 측정 리스트에 기록하고 TPM PCR 10을 확장하여 원격 증명에 사용합니다.
  • IMA Appraisesecurity.ima xattr과 파일 해시를 비교하여 무결성을 검증하며, enforce 모드에서는 불일치 시 접근을 차단합니다.
  • IMA Audit — 파일 접근 이벤트를 audit 로그에 기록하여 감사 추적을 지원합니다.
  • EVM HMAC/서명 — 보안 xattr의 HMAC 또는 디지털 서명으로 메타데이터 변조를 방지합니다.
  • IMA 정책 — 어떤 파일을 언제 측정/평가/감사할지 결정하는 규칙을 /sys/kernel/security/ima/policy에서 관리합니다.
  • dm-verity / fs-verity — 블록 장치 또는 파일 단위 Merkle 트리로 읽기 전용 데이터의 무결성을 보장합니다.
구성요소역할저장 위치TPM 연동
IMA Measure파일 해시를 측정 리스트에 기록, TPM PCR 10 확장커널 메모리 (측정 리스트)PCR 10 extend
IMA Appraisesecurity.ima xattr과 파일 해시 비교 검증security.ima xattr선택적
IMA Audit파일 접근 이벤트를 audit 로그에 기록audit 로그불필요
EVM HMAC보안 xattr의 HMAC 보호 (대칭 키)security.evm xattrsealed key
EVM 디지털 서명보안 xattr의 비대칭 서명 검증(Signature Verification)security.evm xattr선택적
IMA 정책어떤 파일을 언제 측정/평가/감사할지 결정/sys/kernel/security/ima/policy불필요
dm-verity블록 장치(Block Device) 수준 Merkle 트리 검증별도 해시 파티션선택적
fs-verity파일 단위 Merkle 트리 (읽기 전용(Read-Only))파일 메타데이터선택적

단계별 이해

  1. IMA 활성화 확인/sys/kernel/security/ima/ 디렉터리로 IMA가 활성화되었는지 확인합니다.

    ascii_runtime_measurementsruntime_measurements_count로 현재 측정 상태를 파악합니다.

  2. 3가지 모드 이해 — Measure(측정), Appraise(평가), Audit(감사) 모드의 차이를 학습합니다.

    Measure는 TPM 기반 원격 증명, Appraise는 파일 무결성 보호, Audit는 감사 로그 기록에 사용됩니다.

  3. IMA 정책 작성 — 어떤 파일을 어떤 조건에서 측정/평가할지 정책을 구성합니다.

    기본 정책부터 시작하여 커스텀 정책으로 확장합니다.

  4. EVM 보호 설정 — HMAC 또는 디지털 서명으로 보안 xattr의 변조를 방지합니다.

    TPM sealed key로 HMAC 키를 보호하고, evmctl로 서명을 적용합니다.

  5. 원격 증명 연동 — TPM PCR 값과 측정 리스트를 원격 서버로 전송하여 시스템 무결성을 검증합니다.

    IMA 측정 리스트의 각 엔트리가 PCR extend 체인으로 연결되어 변조를 감지합니다.

ℹ️

커널 소스 위치: IMA/EVM 코드는 security/integrity/ 디렉터리에 위치합니다. IMA는 security/integrity/ima/, EVM은 security/integrity/evm/, 공통 코드는 security/integrity/ 루트에 있습니다.

IMA/EVM 기본 동작 확인 (빠른 시작)

# 1. IMA 활성화 여부 확인
ls /sys/kernel/security/ima/
# ascii_runtime_measurements  binary_runtime_measurements
# policy  runtime_measurements_count  violations

# 2. 현재 측정 상태
echo "측정 엔트리 수: $(cat /sys/kernel/security/ima/runtime_measurements_count)"
echo "위반 수: $(cat /sys/kernel/security/ima/violations)"

# 3. 최근 측정 엔트리 5개
tail -5 /sys/kernel/security/ima/ascii_runtime_measurements

# 4. EVM 상태
cat /sys/kernel/security/evm 2>/dev/null || echo "EVM 미활성"

# 5. ima-evm-utils 설치 확인
evmctl --version 2>/dev/null || echo "evmctl 미설치: dnf install ima-evm-utils"

# 6. 특정 파일의 IMA xattr 확인
getfattr -n security.ima -e hex /usr/bin/bash 2>/dev/null || \
    echo "security.ima xattr 없음"

IMA 3가지 동작 모드 비교

모드동작TPM 필요xattr 필요접근 차단주요 용도
Measure해시 기록 + PCR extend아니오아니오원격 증명
Appraise해시 vs xattr 비교아니오enforce 시 예무결성 보호
Auditaudit 로그 기록아니오아니오아니오감사 추적

IMA 아키텍처 개요

IMA는 LSM(Linux Security Module) 인프라의 무결성 후크(Hook)를 사용하여 파일 접근 시점에 개입합니다. security_inode_alloc(), security_file_open(), security_bprm_check() 등의 후크에서 IMA 콜백(Callback)이 호출되며, 정책에 따라 측정(measure), 평가(appraise), 감사(audit) 동작을 수행합니다.

사용자 공간 프로세스 (open/exec) evmctl ima_policy 로드 keylime (증명) 커널 공간 — security/integrity/ VFS → LSM Hook (file_open / bprm_check / mmap_file / kernel_read_file) IMA Core ima_main.c / ima_api.c 정책 엔진 ima_policy.c EVM evm_main.c / evm_crypto.c 측정 리스트 Appraise 판정 Audit 로그 security.ima security.evm 하드웨어 / 파일시스템 TPM (PCR 10) 파일시스템 xattr keyring (.ima/.evm) audit_log

IMA의 핵심 동작 흐름은 다음과 같습니다:

  1. VFS 계층에서 파일 접근(open, exec, mmap, kernel_read) 시 LSM 후크가 호출됩니다.
  2. IMA 정책 엔진(Policy Engine)이 해당 접근에 대한 규칙 매칭을 수행합니다.
  3. 매칭된 규칙에 따라 measure, appraise, audit 중 하나 이상의 동작이 실행됩니다.
  4. EVM이 활성화되어 있으면 security.ima xattr 자체의 무결성도 security.evm으로 검증합니다.
LSM 후크호출 시점IMA 함수
file_open파일 열기ima_file_check()
bprm_checkexec 실행ima_bprm_check()
mmap_file공유 라이브러리(Shared Library) mmapima_file_mmap()
kernel_read_file커널 모듈(Kernel Module), 펌웨어(Firmware) 로드ima_read_file()
kernel_load_datakexec 이미지, 정책 로드ima_load_data()

Measure 모드

IMA Measure는 파일의 해시 값을 측정 리스트(measurement list)에 추가하고, 해당 해시를 TPM의 PCR 10에 extend 하는 동작입니다. 한 번 extend된 PCR 값은 TPM 리셋(재부팅) 전까지 되돌릴 수 없으므로, 부팅 이후 실행된 모든 바이너리와 읽혀진 보안 관련 파일의 이력이 변조 불가능하게 기록됩니다.

1. 파일 접근 2. 정책 매칭 action=MEASURE? 3. 해시 계산 SHA-256(파일) 4. 측정 리스트 추가 ima_queue_entry() 5. TPM PCR 10 extend tpm_pcr_extend() securityfs 노출 /sys/kernel/security/ima/ascii_runtime_measurements 측정 리스트 레코드 형식 (ima-ng 템플릿) PCR template-hash template filedata-hash filename 10 sha256:3b5a...c2f1 ima-ng sha256:9d8e...1a3b /usr/bin/bash 10 sha256:7c2d...f8a0 ima-ng sha256:e1b4...5c7d /usr/lib64/libc.so.6 10 sha256:a1f3...d92e ima-ng sha256:4f6c...8b2a /etc/os-release PCR_new = SHA-1( PCR_old || SHA-1(template-hash) ) — TPM 1.2 PCR_new = SHA-256( PCR_old || SHA-256(template-hash) ) — TPM 2.0

측정 리스트는 /sys/kernel/security/ima/ascii_runtime_measurements에서 확인할 수 있습니다.

# 현재 측정 리스트 확인
cat /sys/kernel/security/ima/ascii_runtime_measurements | head -20

# 측정 리스트 엔트리 수
wc -l /sys/kernel/security/ima/ascii_runtime_measurements

# TPM PCR 10 현재 값 확인 (tpm2-tools)
tpm2_pcrread sha256:10

# 바이너리 측정 리스트 (원격 증명 시 사용)
xxd /sys/kernel/security/ima/binary_runtime_measurements | head
⚠️

PCR extend는 비가역: TPM PCR은 extend 전용 레지스터(Register)로, PCR_new = Hash(PCR_old || data) 연산만 가능합니다. 한 번 기록되면 재부팅 전까지 이전 값으로 되돌릴 수 없어, 공격자가 측정 기록을 삭제하거나 변조할 수 없습니다.

측정 리스트 세부 분석

측정 리스트의 각 레코드는 다음 필드로 구성됩니다:

필드크기설명
PCR2~3자extend 대상 PCR 번호 (기본 10)
template-hash알고리즘별 가변전체 레코드의 해시 (PCR extend 입력)
template-name가변사용된 템플릿 이름 (ima-ng, ima-sig 등)
filedata-hash알고리즘별 가변파일 내용의 해시
filename-hint가변파일 경로 (n-ng 필드)

template-hash는 레코드 전체의 해시로, TPM PCR extend에 사용됩니다. filedata-hash는 파일 내용의 해시로, 파일 무결성 검증에 사용됩니다. 이 두 해시는 다른 용도이므로 혼동하지 않아야 합니다.

boot_aggregate 상세

IMA 측정 리스트의 첫 번째 엔트리는 항상 boot_aggregate입니다. 이 값은 부팅 시점의 TPM PCR 0~9 값을 연결하여 해싱한 결과로, 부팅 환경의 무결성을 나타냅니다. 원격 증명 서버는 이 값을 확인하여 부팅 체인이 신뢰할 수 있는지 판단합니다.

/* security/integrity/ima/ima_init.c */
static int __init ima_calc_boot_aggregate(struct ima_digest_data *hash)
{
    struct tpm_digest d = { .alg_id = TPM_ALG_SHA256 };
    int rc, i;

    rc = crypto_shash_init(shash);
    if (rc)
        return rc;

    /* PCR 0~9의 값을 순서대로 해싱 */
    for (i = 0; i <= 9; i++) {
        rc = tpm_pcr_read(NULL, i, &d);
        if (rc)
            return rc;
        crypto_shash_update(shash, d.digest, d.digest_size);
    }

    crypto_shash_final(shash, hash->digest);
    return 0;
}

IMA 해시 알고리즘과 TPM 2.0 뱅크

TPM 2.0은 여러 해시 알고리즘 뱅크(SHA-1, SHA-256, SHA-384, SHA-512)를 동시에 지원합니다. IMA는 ima_hash= 부트 파라미터로 지정된 알고리즘을 사용하지만, TPM PCR extend 시에는 TPM이 지원하는 모든 뱅크에 동시 extend됩니다.

IMA 해시TPM 뱅크PCR extend 입력비고
sha256SHA-256SHA-256(template-hash)권장 (기본)
sha512SHA-256 + SHA-512각 뱅크별 해시높은 보안
sha1SHA-1SHA-1(template-hash)레거시, 비권장

IMA는 동일 파일의 중복 측정을 방지하기 위해 ima_iint_cache에 inode별 무결성 정보를 캐싱합니다. 파일이 변경되면(쓰기 후 닫기) 캐시(Cache)가 무효화(Invalidation)되어 다음 접근 시 재측정됩니다.

/* security/integrity/ima/ima.h */
struct ima_iint_cache {
    unsigned long      flags;
    unsigned long      measured_pcrs;
    enum integrity_status ima_file_status;
    enum integrity_status ima_mmap_status;
    enum integrity_status ima_bprm_status;
    enum integrity_status ima_read_status;
    struct ima_digest_data *ima_hash;
};

Appraise 모드

IMA Appraise는 파일의 실제 해시를 계산하고, 이를 security.ima 확장 속성(xattr)에 저장된 참조 값과 비교하여 파일 무결성을 검증합니다. 검증 실패 시 정책 모드에 따라 접근을 차단(enforce)하거나, 로그만 남기고 허용(log)하거나, xattr을 업데이트(fix)할 수 있습니다.

파일 접근 요청 APPRAISE 규칙 매칭? No → 허용 security.ima xattr 존재? No → MISSING fix: 생성 / enforce: 거부 파일 해시 계산 vs xattr 비교 일치 → PASS 접근 허용 불일치 → FAIL enforce: -EACCES / log: 허용 ima_appraise= enforce(기본) | fix(xattr 자동 생성) | log(로그만) | off(비활성)

security.ima xattr의 형식은 해시 알고리즘과 저장 방식에 따라 달라집니다:

타입xattr 구조설명
IMA_XATTR_DIGEST (0x01)type(1) + digest단순 해시 (레거시)
IMA_XATTR_DIGEST_NG (0x04)type(1) + algo(1) + digest알고리즘 지정 해시
EVM_IMA_XATTR_DIGSIG (0x03)type(1) + signature header + sig디지털 서명
# security.ima xattr 확인
getfattr -n security.ima -e hex /usr/bin/bash

# evmctl로 IMA 해시 확인
evmctl ima_hash /usr/bin/bash

# IMA 서명 검증
evmctl ima_verify /usr/bin/bash

# IMA appraise 모드 확인
cat /proc/cmdline | grep ima_appraise
/* security/integrity/ima/ima_appraise.c — 핵심 검증 로직 */
int ima_appraise_measurement(enum ima_hooks func,
                            struct integrity_iint_cache *iint,
                            struct file *file,
                            const unsigned char *filename,
                            struct evm_ima_xattr_data *xattr_value,
                            int xattr_len)
{
    enum integrity_status status = INTEGRITY_UNKNOWN;

    /* xattr 없음 */
    if (!xattr_value) {
        status = INTEGRITY_NOLABEL;
        goto out;
    }

    /* 해시 비교 */
    rc = ima_calc_file_hash(file, &hash);
    if (rc == 0 && xattr_verify(xattr_value, &hash))
        status = INTEGRITY_PASS;
    else
        status = INTEGRITY_FAIL;

out:
    /* enforce 모드면 FAIL/NOLABEL 시 -EACCES 반환 */
    if (ima_appraise & IMA_APPRAISE_ENFORCE)
        return (status == INTEGRITY_PASS) ? 0 : -EACCES;
    return 0;
}

Audit 모드

IMA Audit는 파일 접근 이벤트를 커널 audit 서브시스템에 기록합니다. 측정이나 평가와 달리 TPM이나 xattr을 사용하지 않으며, 순수하게 감사 추적(audit trail) 목적으로 동작합니다. IMA audit는 커널의 audit_log_start() / audit_log_format() API를 사용하여 INTEGRITY_RULE 타입의 audit 레코드를 생성합니다.

audit 모드는 단독으로 사용하거나, measure/appraise와 함께 사용할 수 있습니다. 파일 접근이 정책 규칙에 매칭되면 해당 이벤트의 해시, 파일 경로, SELinux 컨텍스트 등이 audit 로그에 기록됩니다.

audit 레코드 필드설명예시 값
INTEGRITY_RULE매칭된 IMA 정책 규칙func=FILE_CHECK mask=MAY_READ
cause감사 사유policy_rule
hash파일 해시sha256:3b5a...c2f1
subj주체 보안 컨텍스트 (SELinux)system_u:system_r:httpd_t:s0
obj객체 보안 컨텍스트system_u:object_r:httpd_exec_t:s0
# IMA audit 이벤트 검색
ausearch -m INTEGRITY_RULE -ts today

# 출력 예시:
# type=INTEGRITY_RULE msg=audit(1710000000.123:456):
#   file="/usr/bin/curl" hash="sha256:a1b2..." cause="policy_rule"
#   subj=unconfined_u:unconfined_r:unconfined_t:s0

# IMA 무결성 검증 실패 이벤트
ausearch -m INTEGRITY_DATA -m INTEGRITY_STATUS -ts today
💡

Measure vs Audit: Measure는 TPM PCR에 해시를 extend하여 원격 증명에 사용할 수 있지만, Audit는 커널 audit 로그에만 기록합니다. 일반적으로 둘을 함께 사용하여 측정(검증)과 감사(추적)를 동시에 수행합니다.

IMA audit 내부 구현

/* security/integrity/ima/ima_api.c */
void ima_audit_measurement(struct integrity_iint_cache *iint,
                           const unsigned char *filename)
{
    struct audit_buffer *ab;
    char *hash_str;
    int i;

    /* audit 버퍼 할당 */
    ab = audit_log_start(audit_context(), GFP_KERNEL,
                         AUDIT_INTEGRITY_RULE);
    if (!ab)
        return;

    /* 해시를 16진 문자열로 변환 */
    hash_str = iint->ima_hash->digest;
    audit_log_format(ab, "file=\"%s\" hash=\"%s:%s\"",
                     filename, hash_algo_name[iint->ima_hash->algo],
                     hash_str);

    /* 정책 규칙 정보 추가 */
    audit_log_format(ab, " cause=\"policy_rule\"");
    audit_log_end(ab);
}

IMA audit 이벤트는 AUDIT_INTEGRITY_RULE(1805), AUDIT_INTEGRITY_DATA(1800), AUDIT_INTEGRITY_STATUS(1802) 등의 메시지 타입으로 생성됩니다. 각 타입의 의미는 다음과 같습니다:

메시지 타입ID발생 조건
AUDIT_INTEGRITY_DATA1800파일 해시 불일치 (appraise FAIL)
AUDIT_INTEGRITY_METADATA1801메타데이터 검증 실패 (EVM FAIL)
AUDIT_INTEGRITY_STATUS1802무결성 상태 변경
AUDIT_INTEGRITY_HASH1803해시 계산 오류
AUDIT_INTEGRITY_PCR1804PCR 무효화
AUDIT_INTEGRITY_RULE1805정책 규칙 매칭 (audit action)
AUDIT_INTEGRITY_EVM_XATTR1806EVM xattr 검증 결과
AUDIT_INTEGRITY_POLICY_RULE1807정책 규칙 로드/변경

IMA 정책 문법

IMA 정책은 어떤 파일을 언제 어떻게 처리할지 결정하는 규칙 집합입니다. 커널 부트 파라미터(ima_policy=)로 내장 정책을 선택하거나, /sys/kernel/security/ima/policy에 커스텀 정책을 기록할 수 있습니다.

# 정책 규칙 형식
action  condition  [condition ...]  [template=] [pcr=]

# action: measure | dont_measure | appraise | dont_appraise | audit
# condition: func= | mask= | fowner= | uid= | euid= | fsuuid= |
#            fsmagic= | fsname= | subtype= | obj_type= | subj_type=
조건 키워드설명예시
func=LSM 후크 함수 지정FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK, FIRMWARE_CHECK, KEXEC_KERNEL_CHECK, POLICY_CHECK, KEY_CHECK
mask=파일 접근 모드MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND
fowner=파일 소유자 UIDfowner=0 (root 소유)
uid= / euid=프로세스(Process) UID/EUIDuid=0
fsuuid=파일시스템(Filesystem) UUIDfsuuid=a1b2c3d4-...
fsmagic=파일시스템 매직 넘버fsmagic=0x9fa0 (proc), 0x62656572 (sysfs)
fsname=파일시스템 이름fsname=ext4
obj_type=SELinux 객체 타입obj_type=httpd_exec_t
subj_type=SELinux 주체 타입subj_type=init_t
pcr=측정에 사용할 PCR 번호pcr=10 (기본), pcr=11
template=측정 레코드 템플릿template=ima-ng, template=ima-sig

내장 정책(Built-in Policy)

부트 파라미터동작
ima_policy=tcb모든 실행 파일, 공유 라이브러리, 커널 모듈 측정
ima_policy=appraise_tcbroot 소유 파일 평가 (enforce)
ima_policy=critical_data커널 모듈, 펌웨어, kexec 이미지 측정
ima_policy=secure_bootSecure Boot 키로 서명된 파일만 허용

커스텀 정책 예시

# /etc/ima/ima-policy — 실전 정책 예시

# 가상 파일시스템 측정 제외
dont_measure fsmagic=0x9fa0    # proc
dont_measure fsmagic=0x62656572 # sysfs
dont_measure fsmagic=0x64626720 # debugfs
dont_measure fsmagic=0x01021994 # tmpfs
dont_measure fsmagic=0x73636673 # securityfs
dont_measure fsmagic=0x28cd3d45 # cramfs
dont_measure fsmagic=0x1cd1     # devpts
dont_measure fsmagic=0x42494e4d # binfmt_misc

# 실행 파일과 공유 라이브러리 측정+평가
measure   func=BPRM_CHECK template=ima-ng pcr=10
appraise  func=BPRM_CHECK fowner=0
measure   func=MMAP_CHECK mask=MAY_EXEC template=ima-ng pcr=10
appraise  func=MMAP_CHECK mask=MAY_EXEC fowner=0

# 커널 모듈 측정+평가 (서명 필수)
measure   func=MODULE_CHECK template=ima-sig pcr=10
appraise  func=MODULE_CHECK appraise_type=imasig

# 펌웨어 측정+평가
measure   func=FIRMWARE_CHECK template=ima-ng pcr=10
appraise  func=FIRMWARE_CHECK appraise_type=imasig

# kexec 커널 이미지 서명 필수
appraise  func=KEXEC_KERNEL_CHECK appraise_type=imasig

# IMA 정책 자체도 서명 필수
appraise  func=POLICY_CHECK appraise_type=imasig

# SELinux 컨텍스트 기반 정책
measure   func=FILE_CHECK obj_type=httpd_exec_t template=ima-ng

# 특정 파일시스템만 감사
audit     func=FILE_CHECK fsname=ext4

# 정책 로드
# cat /etc/ima/ima-policy > /sys/kernel/security/ima/policy
⚠️

정책 로드는 단방향: 기본적으로 /sys/kernel/security/ima/policy에 기록된 정책은 추가(append)만 가능하고, 삭제나 수정은 불가능합니다. CONFIG_IMA_WRITE_POLICY=y를 설정하면 재기록이 가능하지만, 보안상 프로덕션에서는 권장하지 않습니다.

IMA 템플릿

IMA 템플릿은 측정 리스트 레코드의 형식을 정의합니다. 각 레코드가 어떤 정보(해시, 파일명, 서명 등)를 포함할지 결정합니다.

템플릿 이름필드설명커널 버전
imad|nSHA-1 해시 + 파일명 (레거시)2.6.30+
ima-ngd-ng|n-ng알고리즘 접두사 해시 + 긴 파일명3.13+
ima-sigd-ng|n-ng|sigima-ng + 디지털 서명3.13+
ima-bufd-ng|n-ng|bufima-ng + 임의 버퍼(Buffer) 데이터4.17+
ima-modsigd-ng|n-ng|sig|d-modsig|modsig모듈 내장 서명 포함5.4+

템플릿 필드 상세

필드설명형식
dSHA-1 해시 (고정)20바이트
n파일명 (256자 제한)null-terminated string
d-ng알고리즘:해시sha256:3b5a...c2f1
n-ng긴 파일명 (제한 없음)length-prefixed string
sigxattr의 IMA 서명PKCS#7 / 커스텀 v2
buf커널 버퍼 데이터가변 길이 바이너리
d-modsig모듈 appended 서명 해시algo:hash
modsig모듈 appended 서명 원본PKCS#7
# 현재 사용 중인 기본 템플릿 확인
cat /sys/kernel/security/ima/ima_template

# 템플릿 형식 확인
cat /sys/kernel/security/ima/ima_template_fmt

# 부트 파라미터로 템플릿 지정
# ima_template=ima-sig ima_hash=sha256
/* security/integrity/ima/ima_template_lib.c */
static struct ima_template_desc builtin_templates[] = {
    { .name = "ima",     .fmt = "d|n" },
    { .name = "ima-ng",  .fmt = "d-ng|n-ng" },
    { .name = "ima-sig", .fmt = "d-ng|n-ng|sig" },
    { .name = "ima-buf", .fmt = "d-ng|n-ng|buf" },
    { .name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig" },
};

커스텀 템플릿 정의

커널 6.x부터 부트 파라미터로 커스텀 템플릿 형식을 정의할 수 있습니다:

# 커스텀 템플릿 정의 (부트 파라미터)
ima_template_fmt=d-ng|n-ng|sig|buf

# 여러 템플릿을 정책 규칙별로 지정 가능
measure func=BPRM_CHECK template=ima-sig
measure func=KEY_CHECK template=ima-buf
measure func=CRITICAL_DATA template=ima-buf

IMA 템플릿 시스템의 확장성은 ima_template_field 구조체(Struct)의 field_init / field_show 콜백으로 구현됩니다:

/* security/integrity/ima/ima.h */
struct ima_template_field {
    const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN];
    int (*field_init)(struct ima_event_data *event_data,
                      struct ima_field_data *field_data);
    void (*field_show)(struct seq_file *m,
                       enum ima_show_type show,
                       struct ima_field_data *field_data);
};

/* 등록된 필드 함수들 */
static struct ima_template_field supported_fields[] = {
    { .field_id = "d",       .field_init = ima_eventdigest_init },
    { .field_id = "n",       .field_init = ima_eventname_init },
    { .field_id = "d-ng",    .field_init = ima_eventdigest_ng_init },
    { .field_id = "n-ng",    .field_init = ima_eventname_ng_init },
    { .field_id = "sig",     .field_init = ima_eventsig_init },
    { .field_id = "buf",     .field_init = ima_eventbuf_init },
    { .field_id = "d-modsig", .field_init = ima_eventdigest_modsig_init },
    { .field_id = "modsig",  .field_init = ima_eventmodsig_init },
};
💡

KEY_CHECK와 CRITICAL_DATA: 커널 5.11+에서 func=KEY_CHECK는 키링(Keyring)에 로드되는 인증서를 측정하고, func=CRITICAL_DATA는 SELinux 정책 해시, dm-crypt 키 설명 등 커널 내부 중요 데이터를 측정합니다. 이 기능은 ima-buf 템플릿과 함께 사용합니다.

다이제스트 리스트

대규모 배포 환경에서 모든 파일에 개별적으로 security.ima xattr을 설정하는 것은 비효율적입니다. 다이제스트 리스트(digest list)는 배포판이 제공하는 알려진 파일 해시 목록으로, IMA가 이 목록에 포함된 해시와 일치하면 파일을 신뢰합니다.

배포판 빌드 시스템 RPM/DEB 해시 생성 서명된 다이제스트 리스트 .compact / .tlv 형식 커널 해시 테이블 htable에 로드 파일 접근 해시 계산 다이제스트 리스트 조회 htable lookup 히트 → PASS 미스 → xattr 확인 또는 서명 검증 fallback
# digest-list-tools 패키지 사용

# RPM 패키지에서 다이제스트 리스트 생성
manage_digest_lists -a add -d /etc/ima/digest_lists \
    -i rpm+file -p /var/lib/rpm

# 다이제스트 리스트 서명
evmctl sign -k /etc/keys/privkey.pem \
    /etc/ima/digest_lists/0-metadata_list-compact-rpm

# 정책에서 다이제스트 리스트 평가 설정
appraise func=BPRM_CHECK appraise_type=imasig|imasig_digest_list

# 로드된 다이제스트 리스트 확인
cat /sys/kernel/security/ima/digests_count
ℹ️

compact list 형식: 다이제스트 리스트의 compact 형식은 헤더(알고리즘, 타입, 개수)와 연속된 해시 바이트로 구성됩니다. TLV(Type-Length-Value) 형식도 지원하며, 배포판별로 RPM, DEB 패키지 메타데이터에서 자동 생성됩니다.

다이제스트 리스트 데이터 구조

/* 다이제스트 리스트 compact 형식 헤더 */
struct compact_list_hdr {
    u8  version;        /* 형식 버전 */
    u8  _reserved;
    u16 type;           /* COMPACT_FILE, COMPACT_METADATA 등 */
    u16 modifiers;      /* 수정자 플래그 */
    u16 algo;           /* 해시 알고리즘 ID */
    u32 count;          /* 다이제스트 개수 */
    u32 datalen;        /* 다이제스트 데이터 전체 길이 */
} __packed;

/* 헤더 뒤에 count × digest_size 바이트의 해시가 연속 */
/* 예: SHA-256, 1000개 파일 → 32000 바이트 */
다이제스트 리스트 타입설명용도
COMPACT_FILE파일 내용 해시IMA appraise
COMPACT_METADATA메타데이터 해시EVM 검증
COMPACT_PARSER파서 바이너리 해시다이제스트 리스트 파서 자체
COMPACT_KEY키 해시키 검증
# 다이제스트 리스트 생성 워크플로 (RPM 기반)

# 1. RPM 데이터베이스에서 파일 해시 추출
rpm -qa --queryformat '%{FILEDIGESTS}\n' | head

# 2. manage_digest_lists로 compact 리스트 생성
manage_digest_lists -a add -d /etc/ima/digest_lists \
    -i rpm+file -p /var/lib/rpm

# 3. 생성된 리스트 확인
ls -la /etc/ima/digest_lists/

# 4. 다이제스트 리스트에 서명
for f in /etc/ima/digest_lists/0-*; do
    evmctl sign -k /etc/keys/ima-privkey.pem "$f"
done

# 5. 커널에 다이제스트 리스트 로드
echo "/etc/ima/digest_lists" > /sys/kernel/security/ima/digest_list_data

IMA 네임스페이스(Namespace)

컨테이너(Container) 환경에서 각 네임스페이스가 독립적인 IMA 정책과 측정 리스트를 가질 수 있도록 하는 기능입니다. 커널 6.x에서 IMA 네임스페이스 지원이 점진적으로 도입되고 있습니다.

기능지원 상태 (6.x)설명
네임스페이스별 정책실험적 (패치(Patch)셋)user namespace별 독립 IMA 정책
네임스페이스별 측정 리스트실험적컨테이너별 별도 ascii_runtime_measurements
네임스페이스별 securityfs부분 지원mount -t securityfs per namespace
네임스페이스별 appraise제한적부분적 키링 격리(Isolation)
/* IMA 네임스페이스 구조 (패치 기반) */
struct ima_namespace {
    struct user_namespace *user_ns;
    struct list_head      ima_measurements;  /* 네임스페이스별 측정 리스트 */
    struct list_head      ima_default_rules;
    struct list_head      ima_policy_rules;
    int                   ima_policy_loaded;
    struct mutex          ima_write_mutex;
};
⚠️

개발 중인 기능: IMA 네임스페이스는 아직 메인라인 커널에 완전히 통합되지 않았습니다. 실험적 패치셋이 존재하며, Stefan Berger 등의 개발자들이 user namespace 기반 IMA 격리를 제안하고 있습니다. 프로덕션 사용은 배포판의 백포트 상태를 확인하세요.

현재 프로덕션에서 컨테이너 IMA를 사용하려면 호스트 IMA 정책으로 컨테이너 내부 파일도 함께 관리하는 방식이 일반적입니다:

# 호스트 정책에서 특정 컨테이너 rootfs 대상 측정
measure func=FILE_CHECK fsuuid=container-rootfs-uuid template=ima-ng

# overlay 파일시스템 대상
measure func=FILE_CHECK fsname=overlay template=ima-ng

IMA 커널 내부 구현

IMA의 핵심 코드는 security/integrity/ima/ 디렉터리에 위치하며, 약 15개의 소스 파일로 구성됩니다.

VFS → security_file_open() ima_main.c ima_file_check() → process_measurement() ima_policy.c ima_match_policy() ima_api.c ima_collect/store/audit ima_crypto.c ima_calc_file_hash() ima_queue.c 측정 리스트 + PCR extend ima_appraise.c xattr 검증 / enforce ima_template_lib.c 레코드 직렬화 security/integrity/ — integrity_inode_get() / iint_cache / digsig.c / platform_certs/
소스 파일역할
ima_main.cLSM 후크 콜백, process_measurement() 핵심 흐름
ima_api.cima_collect_measurement(), ima_store_measurement(), ima_audit_measurement()
ima_policy.c정책 파싱, 매칭, securityfs 인터페이스
ima_crypto.c파일 해시 계산, ahash/shash 선택, 비동기 해싱
ima_queue.c측정 리스트 관리, TPM PCR extend
ima_appraise.cxattr 기반 평가 로직, enforce/fix/log 판정
ima_template.c템플릿 등록/조회, 커스텀 템플릿 지원
ima_template_lib.c필드별 직렬화(Serialization)/역직렬화 (d-ng, n-ng, sig 등)
ima_fs.csecurityfs 인터페이스 (measurements, policy, violations)
ima_init.c부팅 시 초기화, boot aggregate 측정

ima_crypto.c 해시 계산 상세

IMA는 파일 해시 계산 시 커널의 Crypto API를 사용하며, 비동기 해시(ahash)를 우선 시도하고 실패 시 동기 해시(shash)로 폴백합니다. 비동기 해시는 하드웨어 가속(AES-NI 기반 SHA 등)을 활용할 수 있어 대용량 파일에서 성능 이점이 있습니다.

/* security/integrity/ima/ima_crypto.c — 해시 계산 */
int ima_calc_file_hash(struct file *file,
                      struct ima_digest_data *hash)
{
    struct crypto_ahash *tfm;
    loff_t i_size = i_size_read(file_inode(file));

    /* 작은 파일: shash (동기) 사용 — 오버헤드 최소 */
    if (i_size <= IMA_HASH_READ_SIZE)
        return ima_calc_file_shash(file, hash);

    /* 큰 파일: ahash (비동기) 사용 — 하드웨어 가속 활용 */
    tfm = ima_alloc_ahash(hash->algo);
    if (IS_ERR(tfm))
        return ima_calc_file_shash(file, hash);

    /* 파일을 페이지 단위로 읽으며 해시 업데이트 */
    while (offset < i_size) {
        rbuf = read_page(file, offset);
        ahash_request_set_crypt(req, &sg, NULL, rbuf_len);
        rc = crypto_ahash_update(req);
        offset += rbuf_len;
    }

    crypto_ahash_final(req, hash->digest);
    return 0;
}

process_measurement() 핵심 흐름

/* security/integrity/ima/ima_main.c — 단순화된 흐름 */
static int process_measurement(struct file *file,
                               const struct cred *cred,
                               u32 secid,
                               char *buf, loff_t size,
                               int mask,
                               enum ima_hooks func)
{
    struct inode *inode = file_inode(file);
    struct integrity_iint_cache *iint;
    struct ima_template_desc *template_desc;
    int action;

    /* 1. 정책 매칭 — 어떤 action을 수행할지 결정 */
    action = ima_get_action(file->f_path.mnt, inode, cred,
                            secid, mask, func, &pcr,
                            &template_desc, NULL, NULL);
    if (!action)
        return 0;  /* 매칭 규칙 없음 → 통과 */

    /* 2. inode 무결성 캐시 조회/생성 */
    iint = integrity_inode_get(inode);

    /* 3. 파일 해시 수집 */
    if (action & IMA_COLLECTED && !(iint->flags & IMA_COLLECTED))
        ima_collect_measurement(iint, file, buf, size, hash_algo, modsig);

    /* 4. 측정 (measure) */
    if (action & IMA_MEASURE)
        ima_store_measurement(iint, file, template_desc);

    /* 5. 평가 (appraise) */
    if (action & IMA_APPRAISE_SUBMASK)
        rc = ima_appraise_measurement(func, iint, file, ...);

    /* 6. 감사 (audit) */
    if (action & IMA_AUDIT)
        ima_audit_measurement(iint, pathname);

    return rc;
}

EVM 아키텍처

EVM(Extended Verification Module)은 보안 관련 확장 속성(xattr)의 무결성을 보호합니다. security.ima, security.selinux, security.capability 등의 xattr이 변조되지 않았음을 HMAC 또는 디지털 서명으로 보장하며, 그 검증 값을 security.evm xattr에 저장합니다.

파일 inode 메타데이터 security.ima security.selinux security.capability security.apparmor + i_ino, i_generation, i_uid, i_gid, i_mode (EVM HMAC 입력) EVM 계산 엔진 HMAC-SHA1(key, xattr_concat || inode_meta) 또는 RSA/EC 서명 security.evm xattr

EVM이 HMAC를 계산할 때 포함하는 데이터:

  1. 보호 대상 xattr 값들: security.ima, security.selinux, security.capability, security.apparmor, security.SMACK64
  2. inode 메타데이터: i_ino, i_generation, i_uid, i_gid, i_mode
  3. 파일시스템 UUID
/* security/integrity/evm/evm_crypto.c */
static int evm_calc_hmac_or_hash(struct dentry *dentry,
                                const char *req_xattr_name,
                                const char *req_xattr_value,
                                size_t req_xattr_value_len,
                                char type,
                                struct evm_digest *data)
{
    /* 1. 각 보호 대상 xattr 값을 HMAC 입력에 추가 */
    for (xattr = evm_config_xattrnames; *xattr; xattr++) {
        rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, *xattr, ...);
        crypto_shash_update(desc, xattr_value, xattr_size);
    }

    /* 2. inode 메타데이터 추가 */
    hmac_add_misc(desc, inode, type, data);

    /* 3. 최종 HMAC/해시 계산 */
    crypto_shash_final(desc, data->digest);
}

EVM HMAC 모드

EVM HMAC 모드는 대칭 키를 사용하여 xattr의 무결성을 보호합니다. 키는 커널 키링에 로드되며, TPM sealed key를 사용하면 키가 TPM 외부에서 복호화(Decryption)될 수 없어 보안이 강화됩니다.

키 타입저장 방식보안 수준사용 사례
trusted keyTPM sealed blob높음프로덕션, TPM 있는 시스템
encrypted keymaster key로 암호화중간TPM 없는 환경
user key평문 커널 메모리낮음개발/테스트 전용
# TPM trusted key 생성 (TPM으로 sealed)
keyctl add trusted evm-key "new 32" @u

# trusted key를 파일로 백업 (sealed blob)
keyctl pipe $(keyctl search @u trusted evm-key) > /etc/keys/evm-trusted.blob

# 부팅 시 trusted key 복원
keyctl add trusted evm-key "load $(cat /etc/keys/evm-trusted.blob)" @u

# encrypted key 대안 (TPM 없는 경우)
keyctl add encrypted evm-key "new default user:masterkey 32" @u

# EVM 활성화 (키 로드 후)
echo 1 > /sys/kernel/security/evm

# EVM HMAC으로 xattr 보호 생성
evmctl hmac /usr/bin/bash

# EVM xattr 확인
getfattr -n security.evm -e hex /usr/bin/bash
ℹ️

HMAC 재계산: 보호 대상 xattr(security.ima, security.selinux 등)이 변경되면 EVM이 자동으로 security.evm HMAC을 재계산합니다. 단, EVM이 활성화(echo 1 > /sys/kernel/security/evm)된 상태에서만 동작합니다.

EVM 상태 값

의미설명
0비활성EVM 미초기화, xattr 검증 안 함
1HMAC 모드대칭 키(trusted/encrypted) 로드 완료
2서명 모드공개 키 로드 완료, 서명 검증만
6HMAC + 서명양쪽 모두 활성화 (1+2+4)
# EVM 초기화 시퀀스 (initramfs 또는 init 스크립트)

# 1. HMAC 키 로드 (TPM trusted key)
keyctl add trusted evm-key \
    "load $(xxd -p /etc/keys/evm-trusted.blob | tr -d '\n')" @u

# 2. 서명 검증용 공개 키 로드
keyctl padd asymmetric "" %keyring:.evm < /etc/keys/evm-cert.x509

# 3. EVM 활성화
echo 1 > /sys/kernel/security/evm      # HMAC 모드
# 또는
echo 2 > /sys/kernel/security/evm      # 서명 검증 전용

# 4. 상태 확인
cat /sys/kernel/security/evm
# 출력: 1 (HMAC) 또는 2 (서명) 또는 6 (둘 다)

# 5. 보호 대상 xattr 목록 확인
cat /sys/kernel/security/integrity/evm/evm_xattrs
# security.ima
# security.selinux
# security.capability
# security.apparmor
# security.SMACK64

EVM HMAC vs 디지털 서명 선택 기준

기준HMAC디지털 서명
키 관리대칭 키 하나공개/개인 키 쌍
서명 주체시스템 자체 (런타임)빌드 시스템(Build System)/관리자
변조 방지root도 키 없으면 위조 불가 (TPM sealed)개인 키 없으면 위조 불가
xattr 갱신자동 (커널이 재계산)수동 (evmctl sign)
이식성같은 시스템만 (키+inode 종속)portable 서명 사용 시 이식 가능
성능빠름 (HMAC-SHA1)느림 (RSA/EC 서명 검증)
권장 사용프로덕션 런타임패키지 서명, 배포

EVM 디지털 서명 모드

EVM 디지털 서명 모드는 비대칭 키(RSA/EC)를 사용합니다. 빌드/패키징 시점에 개인 키로 서명하고, 런타임에 공개 키로 검증합니다. HMAC과 달리 검증 키만 있으면 되므로 시스템이 서명을 위조할 수 없어 보안이 더 강합니다.

서명 버전형식특징
v2커스텀 바이너리 헤더기본, struct signature_v2_hdr
v5 (portable)PKCS#7 래핑이식가능, 파일시스템 간 이동 지원
/* security/integrity/integrity.h */
struct signature_v2_hdr {
    uint8_t  type;       /* DIGSIG_VERSION_2 (0x02) */
    uint8_t  version;    /* 서명 형식 버전 */
    uint8_t  hash_algo;  /* 해시 알고리즘 ID */
    uint32_t keyid;      /* 키 식별자 (SubjectKeyIdentifier 하위 4바이트) */
    uint16_t sig_size;   /* 서명 크기 */
    uint8_t  sig[];      /* 실제 서명 데이터 */
} __packed;

서명 헤더 상세

security.evm xattr의 첫 번째 바이트가 서명 타입을 나타냅니다:

타입 바이트의미설명
0x01EVM_XATTR_HMACHMAC 값 (20바이트 SHA-1)
0x02IMA_XATTR_DIGSIG디지털 서명 (signature_v2_hdr)
0x03EVM_IMA_XATTR_DIGSIGEVM 디지털 서명 (immutable)
0x04IMA_XATTR_DIGEST_NG알고리즘 지정 해시
0x05EVM_XATTR_PORTABLE_DIGSIG이식가능 서명 (portable)
# xattr 타입 확인 (첫 바이트)
getfattr -n security.evm -e hex /usr/bin/bash 2>/dev/null | grep "0x"
# 0x01... → HMAC
# 0x03... → immutable 서명
# 0x05... → portable 서명

getfattr -n security.ima -e hex /usr/bin/bash 2>/dev/null | grep "0x"
# 0x04... → digest-ng (해시)
# 0x03... → 디지털 서명
# EVM 서명 키 생성
openssl genrsa -out /etc/keys/evm-privkey.pem 2048
openssl rsa -in /etc/keys/evm-privkey.pem -pubout -out /etc/keys/evm-pubkey.pem

# X.509 인증서 생성 (커널 키링 로드용)
openssl req -new -x509 -key /etc/keys/evm-privkey.pem \
    -out /etc/keys/evm-cert.x509 -days 3650 -subj '/CN=EVM/'

# 커널 키링에 공개 키 로드
keyctl padd asymmetric "" %keyring:.evm < /etc/keys/evm-cert.x509

# EVM 디지털 서명 생성
evmctl sign -k /etc/keys/evm-privkey.pem /usr/bin/bash

# 서명 검증
evmctl verify /usr/bin/bash

이식가능 서명 (Portable Signature)

기본 EVM 서명(immutable)은 inode 번호, generation 번호 등 파일시스템 고유 메타데이터를 포함하므로, 파일을 다른 파일시스템으로 복사하면 서명이 무효화됩니다. 이식가능 서명(portable signature)은 파일시스템 독립적인 메타데이터만 사용하여 배포판 간 파일 이동을 지원합니다.

Immutable 서명 입력 xattr + i_ino + i_generation + i_uid + i_gid + i_mode + fs_uuid Portable 서명 입력 xattr + i_uid + i_gid + i_mode (파일시스템 독립) 빌드 시스템 서명 (evmctl sign --portable) 개인 키로 security.evm 생성 RPM/DEB 패키지에 xattr 포함 대상 시스템에서 서명 검증 (공개 키)
# 이식가능 서명 생성
evmctl sign --portable -k /etc/keys/evm-privkey.pem /usr/bin/bash

# 이식가능 서명 확인 (타입 필드가 0x05)
getfattr -n security.evm -e hex /usr/bin/bash
# 0x05... (portable) vs 0x03... (immutable)

# RPM 빌드 시 이식가능 서명 포함
# %__ ima_sign_file_cmd evmctl sign --portable -k key.pem %{buildroot}%{_bindir}/*
💡

Fedora/RHEL IMA: Fedora 39+와 RHEL 9에서는 RPM 패키지에 이식가능 서명을 기본으로 포함하는 실험적 지원이 진행 중입니다. rpm --import으로 IMA 서명 키를 시스템 키링에 로드하고, ima_appraise=enforce로 부팅하면 rpm 패키지 파일만 실행 가능합니다.

IMA + EVM + TPM 신뢰 체인

IMA/EVM과 TPM이 결합하면 부팅부터 런타임까지 이어지는 완전한 신뢰 체인(chain of trust)이 형성됩니다. UEFI Secure Boot → 부트로더(Bootloader) → 커널 → IMA 측정으로 이어지는 체인입니다.

TPM PCR PCR 0-7: UEFI/BIOS PCR 8-9: 부트로더 PCR 10: IMA PCR 11: 선택적 IMA PCR 14: MOK/shim Phase 1: UEFI Secure Boot — 펌웨어가 부트로더 서명 검증 PCR 0-7 extend (SRTM/DRTM) Phase 2: GRUB/shim — 커널 + initramfs 서명 검증 + 측정 PCR 8-9 extend Phase 3: 커널 부팅 — IMA 초기화, boot aggregate 측정 boot_aggregate = SHA-256(PCR 0 || PCR 1 || ... || PCR 9) Phase 4: initramfs — EVM 키 로드, IMA 정책 로드 echo 1 > /sys/kernel/security/evm (EVM 활성화) Phase 5: 런타임 — 모든 파일 접근 시 IMA 측정/평가 PCR 10 연속 extend → 원격 증명 서버가 Quote로 검증 Phase 6: 원격 증명 — TPM Quote + 측정 리스트 전송 → 검증 서버 keylime / IBM ACS / Google go-attestation
# boot aggregate 확인 (측정 리스트 첫 번째 엔트리)
head -1 /sys/kernel/security/ima/ascii_runtime_measurements
# 10 sha256:xxxx ima-ng sha256:yyyy boot_aggregate

# boot aggregate 수동 계산 (TPM 2.0)
# SHA-256(PCR0 || PCR1 || ... || PCR9)
tpm2_pcrread sha256:0,1,2,3,4,5,6,7,8,9 -o pcrs.bin
sha256sum pcrs.bin

dm-verity 연동

dm-verity는 블록 장치 수준에서 Merkle 트리를 사용한 읽기 전용 무결성 검증을 제공합니다. IMA와 dm-verity를 결합하면 블록 레벨과 파일 레벨의 이중 검증이 가능합니다.

파일시스템 (read-only) dm-verity target 블록 읽기 시 Merkle 트리 검증 데이터 파티션 원본 블록 데이터 해시 파티션 Merkle 트리 노드 Merkle 트리 root hash → level 1 hashes → level 0 hashes → 데이터 블록 root hash = 신뢰 기준점 (커널 cmdline / AVB vbmeta)
비교 항목dm-verityIMA
검증 단위블록 (4KB)파일
검증 시점블록 I/O 시파일 open/exec/mmap 시
쓰기 지원읽기 전용만읽기/쓰기 모두
해시 저장별도 파티션 (Merkle 트리)xattr 또는 다이제스트 리스트
TPM 연동root hash 서명 검증PCR extend, 원격 증명
대표 사용Android AVB, ChromeOSRHEL, Fedora, Keylime
# dm-verity 설정 (veritysetup)
veritysetup format /dev/sda2 /dev/sda3
# Root hash: 4a8c...f1d2 (이 값을 커널 cmdline에 전달)

# dm-verity 활성화
veritysetup open /dev/sda2 verified-root /dev/sda3 4a8c...f1d2
mount /dev/mapper/verified-root /mnt/root

# Android AVB (vbmeta에 root hash 포함)
# 커널 cmdline: dm="... verity ... root_hash=4a8c...f1d2"

# IMA와 dm-verity 결합: dm-verity 위에서 IMA 측정
# dm-verity가 블록 무결성 보장 + IMA가 파일 해시를 PCR에 기록
measure func=FILE_CHECK fsname=ext4 template=ima-ng

Android Verified Boot (AVB)와 IMA

Android는 dm-verity를 AVB(Android Verified Boot) 프레임워크의 핵심으로 사용합니다. vbmeta 파티션에 각 파티션의 dm-verity root hash를 서명하여 저장하고, 부트로더가 이를 검증합니다.

AVB 구성요소역할IMA 대응
vbmeta모든 파티션 해시 서명 저장IMA 다이제스트 리스트
dm-verity블록 단위 Merkle 검증IMA 파일 단위 해시
rollback protectionRPMB 카운터로 롤백(Rollback) 방지TPM monotonic counter
chain of trust부트로더→vbmeta→파티션Secure Boot→IMA→PCR
# dm-verity + IMA 결합 시나리오 (서버 환경)

# 읽기 전용 루트 (dm-verity 보호)
veritysetup format /dev/sda2 /dev/sda3
# Root hash: 4a8c3b...f1d2

# 부트 파라미터
# root=/dev/mapper/vroot ro
# dm="vroot,,0,ro,0 sectors verity ... root_hash=4a8c3b...f1d2"
# ima_policy=tcb ima_appraise=enforce

# dm-verity가 블록 무결성 보장
# + IMA가 실행 파일 해시를 TPM PCR에 기록
# + 원격 증명 서버가 PCR Quote로 전체 체인 검증

# dm-verity 상태 확인
dmsetup status vroot
# 0 sectors verity V ... (V=verified)
💡

dm-verity vs IMA 선택: 읽기 전용 루트 파일시스템이라면 dm-verity가 더 효율적입니다(블록 I/O 시 자동 검증). 읽기-쓰기 파일시스템이나 개별 파일 수준 정책이 필요하면 IMA가 적합합니다. 최고 보안은 둘을 결합하여 사용합니다.

fs-verity 연동

fs-verity는 파일 단위로 Merkle 트리를 사용하여 읽기 전용 파일의 무결성을 검증합니다. dm-verity와 달리 전체 파티션이 아닌 개별 파일에 적용되며, ext4와 f2fs에서 지원합니다. IMA의 appraise_type=sigv3를 통해 fs-verity 다이제스트 기반 IMA 평가가 가능합니다.

기능설명
fsverity enable파일에 Merkle 트리 추가 (이후 읽기 전용)
fsverity measure파일의 fs-verity 다이제스트 출력
fsverity sign다이제스트에 대한 PKCS#7 서명 생성
IMA sigv3IMA가 fs-verity 다이제스트를 appraise에 사용
# fs-verity 활성화 (ext4)
tune2fs -O verity /dev/sda1

# 파일에 fs-verity 적용
fsverity enable /usr/bin/bash
# 이후 파일은 읽기 전용 (쓰기 시도 시 -ETXTBSY)

# fs-verity 다이제스트 확인
fsverity measure /usr/bin/bash
# sha256:3b5a7c...f1d2  /usr/bin/bash

# fs-verity 서명 생성
fsverity sign /usr/bin/bash fsverity.sig \
    --key=/etc/keys/fsverity-privkey.pem \
    --cert=/etc/keys/fsverity-cert.pem

# 서명된 fs-verity 내장 설정
fsverity enable /usr/bin/bash --signature=fsverity.sig

# IMA 정책에서 fs-verity 기반 appraise
# appraise func=BPRM_CHECK appraise_type=sigv3
ℹ️

fs-verity vs IMA 해시: fs-verity는 파일 내용의 Merkle root hash를 사용하므로 전체 파일을 읽지 않고도 부분 검증이 가능합니다 (on-demand 검증). 반면 IMA는 전체 파일 해시를 계산합니다. 대용량 파일이 많은 환경에서 fs-verity가 성능상 유리합니다.

fs-verity + IMA 통합 상세

커널 5.15+에서 IMA는 appraise_type=sigv3를 통해 fs-verity 다이제스트 기반 평가를 지원합니다. 이 모드에서 IMA는 파일의 전체 해시를 직접 계산하는 대신, fs-verity 서브시스템이 제공하는 Merkle root hash를 사용합니다.

# fs-verity + IMA 정책 예시

# fs-verity 다이제스트 기반 IMA appraise (sigv3)
appraise func=BPRM_CHECK appraise_type=sigv3

# security.ima xattr에 fs-verity 다이제스트 서명 저장
# type = 0x05 (IMA_VERITY_DIGSIG)
evmctl ima_sign --verity -k /etc/keys/ima-privkey.pem /usr/bin/bash

# fs-verity 활성화 후 IMA 서명
fsverity enable /usr/bin/bash
evmctl ima_sign --verity -a sha256 -k /etc/keys/ima-privkey.pem /usr/bin/bash
/* security/integrity/ima/ima_appraise.c — fs-verity 지원 */
static int ima_get_verity_digest(struct integrity_iint_cache *iint,
                                 struct ima_max_digest_data *hash)
{
    enum hash_algo alg;
    int digest_len;

    /* fs-verity에서 Merkle root hash 가져오기 */
    digest_len = fsverity_get_digest(iint->inode,
                                     hash->digest,
                                     NULL, &alg);
    if (digest_len) {
        hash->hdr.algo = alg;
        hash->hdr.length = digest_len;
    }
    return digest_len;
}
비교 항목IMA 전체 해시IMA + fs-verity (sigv3)
해시 계산파일 전체 읽기 필요fs-verity Merkle root만 사용
파일 열기 성능O(n) — 파일 크기 비례O(1) — 메타데이터만
읽기 검증열기 시 1회모든 페이지 읽기마다 (on-demand)
쓰기 지원가능 (재해싱)불가 (읽기 전용)
xattr 타입0x03 (IMA_XATTR_DIGSIG)0x05 (IMA_VERITY_DIGSIG)

원격 증명 (Remote Attestation)

원격 증명은 신뢰할 수 없는 원격 시스템의 무결성을 검증하는 프로토콜입니다. IMA 측정 리스트와 TPM Quote를 결합하여, 원격 서버가 대상 시스템에서 실행된 모든 소프트웨어의 무결성을 검증할 수 있습니다.

대상 시스템 (Agent) IMA 측정 리스트 TPM Keylime Agent TPM Quote + 측정 리스트 수집 1. Nonce 수신 → 2. Quote 서명 3. Quote + 측정 리스트 전송 검증 서버 (Verifier) Keylime Verifier 주기적 검증 (polling) 4. TPM Quote 서명 검증 (AIK) 5. 측정 리스트 리플레이 → PCR 재계산 6. 재계산 PCR == Quote PCR ? TRUSTED UNTRUSTED TLS / mTLS

Keylime 설정

# Keylime 설치 (Python 패키지)
pip install keylime

# 또는 배포판 패키지
dnf install keylime  # Fedora/RHEL

# Keylime Verifier 시작
keylime_verifier

# Keylime Registrar 시작
keylime_registrar

# Agent 등록 (대상 시스템에서)
keylime_agent

# Tenant CLI로 에이전트 추가 (IMA 검증 활성화)
keylime_tenant -c add \
    --uuid d432fbb3-d2f1-4a97-9ef7-75bd81c00000 \
    -t 192.168.1.100 \
    --ima_sign_verification_keys /etc/keys/ima-cert.pem \
    --ima_allowlist /etc/keylime/allowlist.txt

# IMA allowlist 생성 (신뢰할 파일 해시 목록)
# sha256:3b5a... /usr/bin/bash
# sha256:7c2d... /usr/lib64/libc.so.6
create_allowlist.sh /etc/keylime/allowlist.txt
ℹ️

Keylime 아키텍처: Keylime은 3개 구성요소로 동작합니다. Registrar는 에이전트의 TPM EK/AIK 인증서를 등록하고, Agent는 대상 시스템에서 TPM Quote를 생성하며, Verifier는 주기적으로 Quote와 IMA 측정 리스트를 검증합니다. 검증 실패 시 revocation 스크립트를 실행하여 자동 대응합니다.

원격 증명 검증 알고리즘

검증 서버(Verifier)는 다음 단계로 측정 리스트의 진정성을 확인합니다:

  1. TPM Quote 검증: AIK(Attestation Identity Key)로 서명된 Quote를 검증하여 PCR 값이 TPM에서 직접 생성되었음을 확인합니다.
  2. 측정 리스트 리플레이: 수신한 측정 리스트의 각 엔트리를 순서대로 해싱하고 PCR extend 연산을 시뮬레이션합니다.
  3. PCR 비교: 리플레이 결과 PCR 값과 Quote에 포함된 PCR 값을 비교합니다. 일치하면 측정 리스트가 변조되지 않았음이 증명됩니다.
  4. allowlist 매칭: 측정 리스트의 각 엔트리 해시를 신뢰할 수 있는 해시 목록(allowlist)과 비교합니다.
  5. 서명 검증 (옵션): ima-sig 템플릿을 사용하면 각 엔트리의 서명도 검증할 수 있습니다.
/* 원격 증명 검증 의사코드 (Python/Go 구현 기반) */

/* 1. PCR 리플레이 */
pcr_simulated = bytes(32)  /* SHA-256 크기, 0으로 초기화 */

for entry in measurement_list:
    /* template_hash = SHA-256(filedata_hash || filename) */
    template_hash = entry.template_hash
    /* PCR extend 시뮬레이션 */
    pcr_simulated = SHA256(pcr_simulated + template_hash)

/* 2. Quote의 PCR 값과 비교 */
if pcr_simulated != quote.pcr_values[10]:
    FAIL("PCR mismatch — 측정 리스트 변조 의심")

/* 3. allowlist 확인 */
for entry in measurement_list:
    if entry.filedata_hash not in allowlist:
        ALERT("미승인 파일: %s", entry.filename)

대안 원격 증명 도구

도구개발사특징
KeylimeMIT/CNCFPython/Rust, IMA 통합, CNCF 프로젝트
go-attestationGoogleGo 라이브러리, GCE 통합
IBM ACSIBM엔터프라이즈, TPM 2.0 전용
ISECLIntelIntel Security Libraries, SGX 통합
RATSIETF표준 프로토콜 (RFC 9334)
⚠️

vTPM 주의: 클라우드 환경에서 vTPM(가상 TPM)을 사용하면 하이퍼바이저(Hypervisor)가 vTPM을 제어할 수 있어 하드웨어 TPM보다 신뢰 수준이 낮습니다. 높은 보안이 필요한 환경에서는 하드웨어 TPM 또는 Intel TXT/AMD SEV와 결합한 DRTM(Dynamic Root of Trust for Measurement)을 고려하세요.

LoadPin & IPE

LoadPin과 IPE(Integrity Policy Enforcement)는 IMA/EVM과 함께 커널의 파일 무결성을 강화하는 보조 메커니즘입니다.

LoadPin

LoadPin은 커널이 읽는 파일(모듈, 펌웨어, kexec 이미지)의 출처를 고정합니다. 첫 번째 커널 파일 로드 시 해당 파일시스템의 root를 "고정(pin)"하고, 이후 모든 커널 파일 로드는 동일한 root에서만 허용합니다.

설정설명
CONFIG_SECURITY_LOADPIN=yLoadPin LSM 활성화
loadpin.enforce=1부트 파라미터: 강제 모드
loadpin.exclude=제외할 파일 타입 (firmware 등)
/* security/loadpin/loadpin.c */
static int loadpin_read_file(struct file *file,
                            enum kernel_read_file_id id,
                            bool contents)
{
    struct super_block *load_root = READ_ONCE(pinned_root);

    /* 첫 번째 로드: root 고정 */
    if (!load_root) {
        cmpxchg(&pinned_root, NULL, file->f_path.mnt->mnt_sb);
        return 0;
    }

    /* 이후 로드: 고정된 root와 비교 */
    if (file->f_path.mnt->mnt_sb != load_root)
        return -EPERM;  /* 다른 파일시스템 → 거부 */

    return 0;
}

IPE (Integrity Policy Enforcement)

IPE는 커널 6.x에서 도입된 새로운 LSM으로, dm-verity 검증 파티션에서 온 파일만 실행을 허용하는 정책을 시행합니다.

# IPE 정책 예시
policy_name="example" policy_version=0.0.1
DEFAULT op=EXECUTE action=DENY
DEFAULT op=KERNEL_READ action=DENY

# dm-verity 검증된 볼륨의 파일만 실행 허용
op=EXECUTE dmverity_roothash=4a8c...f1d2 action=ALLOW
op=KERNEL_READ dmverity_roothash=4a8c...f1d2 action=ALLOW

# fs-verity 검증 파일도 허용
op=EXECUTE fsverity_digest=sha256:3b5a...c2f1 action=ALLOW
무결성 보호 계층 비교 IMA 파일 해시 측정 파일 해시 평가 파일 접근 감사 xattr (security.ima) TPM PCR extend 범위: 모든 파일 R/W 파일시스템 정책 기반 유연한 규칙 EVM xattr HMAC 보호 xattr 서명 검증 메타데이터 보호 xattr (security.evm) TPM sealed key 범위: xattr 보호 IMA와 결합 자동 동작 IMA 종속 LoadPin 커널 파일 출처 고정 단일 root FS 강제 모듈/펌웨어/kexec 설정 불요 (자동) TPM 불필요 범위: 커널 파일만 ChromeOS 사용 단순 (yes/no) 정책 없음 IPE 실행 정책 시행 dm-verity 기반 허용 fs-verity 기반 허용 정책 파일 (securityfs) TPM 불필요 범위: 실행 파일 Windows SI 유사 deny-by-default allowlist 기반

LoadPin과 IMA 비교 활용

시나리오권장 조합설명
임베디드 (읽기 전용 rootfs)dm-verity + LoadPin단순하고 오버헤드(Overhead) 최소
서버 (RHEL/Fedora)IMA + EVM + 원격 증명유연한 정책, TPM 기반 증명
컨테이너 호스트IMA + dm-verity + IPE이미지 무결성 + 실행 제어
클라우드 VMIMA + vTPM + Keylime가상 TPM 기반 원격 증명
데스크탑IMA measure (tcb)측정만, 평가는 선택적
# LoadPin + IMA 동시 사용 (커널 cmdline)
loadpin.enforce=1 loadpin.exclude=firmware \
ima_policy=tcb ima_appraise=enforce ima_hash=sha256

# IPE 정책 로드
echo "policy_name=prod policy_version=1.0.0
DEFAULT op=EXECUTE action=DENY
DEFAULT op=KERNEL_READ action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=KERNEL_READ boot_verified=TRUE action=ALLOW" \
> /sys/kernel/security/ipe/new_policy

# IPE 정책 활성화
echo 1 > /sys/kernel/security/ipe/prod/active

evmctl 명령어 레퍼런스

evmctl은 IMA/EVM 관련 xattr을 관리하는 사용자 공간(User Space) 도구로, ima-evm-utils 패키지에 포함됩니다.

명령어설명예시
ima_hash파일 해시를 security.ima에 저장evmctl ima_hash /usr/bin/bash
ima_sign파일 해시에 서명하여 security.ima에 저장evmctl ima_sign -k key.pem /usr/bin/bash
ima_verifysecurity.ima 서명 검증evmctl ima_verify /usr/bin/bash
ima_measurement측정 리스트 검증evmctl ima_measurement ascii_runtime_measurements
hmacEVM HMAC 생성evmctl hmac /usr/bin/bash
signEVM 디지털 서명 생성evmctl sign -k key.pem /usr/bin/bash
verifyEVM 서명 검증evmctl verify /usr/bin/bash
import키를 커널 키링에 로드evmctl import cert.x509 %keyring:.ima

실전 워크플로

# 1. 키 쌍 생성
openssl genrsa -out /etc/keys/ima-privkey.pem 2048
openssl req -new -x509 -key /etc/keys/ima-privkey.pem \
    -out /etc/keys/ima-cert.x509 -days 3650 -subj '/CN=IMA/'

# 2. 공개 키를 .ima 키링에 로드
evmctl import /etc/keys/ima-cert.x509 %keyring:.ima

# 3. 시스템 전체 파일에 IMA 서명 적용
find /usr/bin /usr/sbin /usr/lib64 -type f -exec \
    evmctl ima_sign -k /etc/keys/ima-privkey.pem -a sha256 {} \;

# 4. EVM 서명도 함께 적용
find /usr/bin /usr/sbin /usr/lib64 -type f -exec \
    evmctl sign --portable -k /etc/keys/evm-privkey.pem {} \;

# 5. 서명 검증
evmctl ima_verify -k /etc/keys/ima-cert.x509 /usr/bin/bash
evmctl verify -k /etc/keys/evm-cert.x509 /usr/bin/bash

# 6. 해시 알고리즘 지정
evmctl ima_hash -a sha512 /usr/bin/bash

# 7. 재귀적 서명 (디렉터리 전체)
evmctl ima_sign -r -k /etc/keys/ima-privkey.pem /usr/bin/

커널 설정 종합

설정 옵션설명기본
IMA 핵심
CONFIG_INTEGRITY무결성 서브시스템 루트y
CONFIG_IMAIMA 활성화y
CONFIG_IMA_MEASURE_PCR_IDX기본 PCR 번호10
CONFIG_IMA_DEFAULT_HASH기본 해시 알고리즘sha256
CONFIG_IMA_DEFAULT_TEMPLATE기본 템플릿ima-ng
CONFIG_IMA_APPRAISEIMA 평가 모드y
CONFIG_IMA_APPRAISE_BOOTPARAM부트 파라미터로 appraise 모드 설정y
CONFIG_IMA_WRITE_POLICY정책 재기록 허용n
CONFIG_IMA_READ_POLICY정책 읽기 허용y
CONFIG_IMA_APPRAISE_MODSIG모듈 appended 서명 지원n
CONFIG_IMA_TRUSTED_KEYRING.ima 키링에 system keyring 제한y
CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY빌트인/보조 키로 서명된 키만 .ima에 추가y
EVM
CONFIG_EVMEVM 활성화y
CONFIG_EVM_ATTR_FSUUIDHMAC에 파일시스템 UUID 포함y
CONFIG_EVM_EXTRA_SMACK_XATTRSSMACK xattr 추가 보호n
CONFIG_EVM_ADD_XATTRSEVM 보호 xattr 동적 추가n
지원 서브시스템
CONFIG_INTEGRITY_SIGNATURE무결성 서브시스템 서명 지원y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS비대칭 키 지원y
CONFIG_INTEGRITY_TRUSTED_KEYRING신뢰 키링y
CONFIG_INTEGRITY_PLATFORM_KEYRING플랫폼 키링 (UEFI db/MOK)y
CONFIG_INTEGRITY_MACHINE_KEYRING머신 키링 (MOK)y
CONFIG_FS_VERITYfs-verity 지원n
CONFIG_DM_VERITYdm-verity 지원m
CONFIG_SECURITY_LOADPINLoadPin LSMn
CONFIG_IPEIPE LSM (6.x+)n
# IMA/EVM 최소 설정 확인
grep -E "^CONFIG_(IMA|EVM|INTEGRITY)" /boot/config-$(uname -r)

# 권장 프로덕션 설정
# CONFIG_IMA=y
# CONFIG_IMA_APPRAISE=y
# CONFIG_IMA_DEFAULT_HASH="sha256"
# CONFIG_IMA_DEFAULT_TEMPLATE="ima-sig"
# CONFIG_IMA_APPRAISE_BOOTPARAM=y
# CONFIG_IMA_TRUSTED_KEYRING=y
# CONFIG_EVM=y
# CONFIG_EVM_ATTR_FSUUID=y
# CONFIG_INTEGRITY_SIGNATURE=y
# CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y

배포판별 기본 설정

배포판IMAEVM기본 정책appraise 모드
RHEL 9yytcb (비활성)off
Fedora 39+yytcb 실험적log (실험)
Ubuntu 22.04+yn (모듈)비활성off
SUSE SLES 15yy비활성off
Debian 12yn비활성off
ChromeOSynLoadPin + dm-verityN/A
Android (AOSP)부분적ndm-verity + AVBN/A
💡

RHEL에서 IMA 활성화: RHEL 9에서 IMA를 활성화하려면 grubby --update-kernel=ALL --args="ima_policy=appraise_tcb ima_appraise=fix"로 fix 모드 부팅 후 evmctl로 서명 작업을 수행하고, 이후 ima_appraise=enforce로 전환합니다.

initramfs에서 IMA/EVM 초기화 순서

IMA/EVM을 enforce 모드로 사용하려면 initramfs 단계에서 올바른 순서로 초기화해야 합니다:

# dracut IMA/EVM 초기화 스크립트 예시
# /usr/lib/dracut/modules.d/98integrity/module-setup.sh

# 1단계: EVM 키 로드
keyctl add trusted evm-key \
    "load $(cat /etc/keys/evm-trusted.blob)" @u

# 2단계: IMA 공개 키 로드
evmctl import /etc/keys/ima-cert.x509 %keyring:.ima

# 3단계: EVM 활성화 (HMAC 모드)
echo 1 > /sys/kernel/security/evm

# 4단계: IMA 커스텀 정책 로드 (선택)
cat /etc/ima/ima-policy > /sys/kernel/security/ima/policy

# 주의: 이 순서를 지키지 않으면 enforce 모드에서 부팅 실패
# - EVM 키 없이 enforce → 모든 파일 접근 거부
# - IMA 정책 로드 전 EVM 활성화 → 정상 동작
# - EVM 활성화 전 IMA 정책 로드 → 정상 동작

securityfs 인터페이스 종합

경로읽기/쓰기설명
/sys/kernel/security/ima/ascii_runtime_measurementsR텍스트 측정 리스트
/sys/kernel/security/ima/binary_runtime_measurementsR바이너리 측정 리스트 (원격 증명용)
/sys/kernel/security/ima/runtime_measurements_countR측정 엔트리 수
/sys/kernel/security/ima/violationsR무결성 위반 카운터
/sys/kernel/security/ima/policyR/W정책 읽기/추가
/sys/kernel/security/ima/ima_hashR현재 해시 알고리즘
/sys/kernel/security/ima/ima_templateR현재 템플릿
/sys/kernel/security/ima/ima_template_fmtR현재 템플릿 형식
/sys/kernel/security/evmR/WEVM 상태 (0/1/2/6)

부트 파라미터 종합

파라미터설명
ima_policy=tcb실행 파일/라이브러리/모듈 측정 (기본 정책)
appraise_tcbroot 소유 파일 평가
critical_data모듈/펌웨어/kexec만 측정
secure_bootSecure Boot 키 기반 평가
ima_appraise=enforce검증 실패 시 접근 거부 (기본)
fixxattr 자동 생성/업데이트
log로그만 남기고 허용
off평가 비활성화
ima_hash=sha256IMA 해시 알고리즘
sha512
sha1레거시 (비권장)
ima_template=ima-ng기본 템플릿
ima-sig서명 포함 템플릿
ima-buf버퍼 데이터 템플릿
ima_canonical_fmt(플래그)리틀 엔디안(Endianness) 정규 형식 사용
evm=fixEVM fix 모드 (초기 설정 시)
ima_tcb(플래그)ima_policy=tcb와 동일 (레거시)
# /etc/default/grub 예시 (RHEL/Fedora)
GRUB_CMDLINE_LINUX="ima_policy=appraise_tcb ima_appraise=enforce \
    ima_hash=sha256 ima_template=ima-sig"

# 초기 설정 시 (xattr 생성 모드)
GRUB_CMDLINE_LINUX="ima_policy=appraise_tcb ima_appraise=fix \
    evm=fix ima_hash=sha256"

# GRUB 설정 적용
grub2-mkconfig -o /boot/grub2/grub.cfg
⚠️

초기 설정 주의: ima_appraise=enforce로 부팅하기 전에 반드시 ima_appraise=fix 모드에서 모든 파일에 security.ima xattr을 생성해야 합니다. xattr 없이 enforce 모드로 부팅하면 시스템이 부팅되지 않을 수 있습니다.

IMA/EVM 초기 배포 절차 (단계별)

프로덕션 서버에 IMA/EVM을 처음 배포할 때의 권장 절차입니다:

# ================================================
# Phase 1: 키 생성 (오프라인 환경)
# ================================================

# IMA 서명 키 (RSA 2048 또는 EC P-256)
openssl ecparam -genkey -name prime256v1 -out /etc/keys/ima-privkey.pem
openssl req -new -x509 -key /etc/keys/ima-privkey.pem \
    -out /etc/keys/ima-cert.x509 -days 3650 \
    -subj '/O=MyOrg/CN=IMA Signing Key/'

# EVM 서명 키
openssl ecparam -genkey -name prime256v1 -out /etc/keys/evm-privkey.pem
openssl req -new -x509 -key /etc/keys/evm-privkey.pem \
    -out /etc/keys/evm-cert.x509 -days 3650 \
    -subj '/O=MyOrg/CN=EVM Signing Key/'

# ================================================
# Phase 2: fix 모드 부팅 (xattr 생성)
# ================================================

# /etc/default/grub:
# GRUB_CMDLINE_LINUX="ima_policy=appraise_tcb ima_appraise=fix
#     evm=fix ima_hash=sha256 ima_template=ima-sig"
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot

# ================================================
# Phase 3: 파일 서명 (fix 모드에서)
# ================================================

# 커널 키링에 키 로드
evmctl import /etc/keys/ima-cert.x509 %keyring:.ima

# EVM trusted key 생성 및 활성화
keyctl add trusted evm-key "new 32" @u
echo 1 > /sys/kernel/security/evm

# 시스템 전체 IMA 서명
find /usr /etc /boot /lib /sbin /bin -type f 2>/dev/null | \
    xargs -P4 -n100 evmctl ima_sign -k /etc/keys/ima-privkey.pem \
    -a sha256 2>/dev/null

# EVM 이식가능 서명
find /usr /etc /boot /lib /sbin /bin -type f 2>/dev/null | \
    xargs -P4 -n100 evmctl sign --portable \
    -k /etc/keys/evm-privkey.pem 2>/dev/null

# ================================================
# Phase 4: enforce 모드 전환
# ================================================

# /etc/default/grub 수정:
# GRUB_CMDLINE_LINUX="ima_policy=appraise_tcb ima_appraise=enforce
#     ima_hash=sha256 ima_template=ima-sig"
grub2-mkconfig -o /boot/grub2/grub.cfg

# EVM trusted key 백업 (중요!)
keyctl pipe $(keyctl search @u trusted evm-key) > /etc/keys/evm-trusted.blob
chmod 600 /etc/keys/evm-trusted.blob

reboot
⚠️

롤백 준비: enforce 모드 전환 전에 반드시 rescue 커널이나 USB 부팅 미디어를 준비하세요. 서명이 누락된 파일이 있으면 시스템이 부팅 불가 상태에 빠질 수 있습니다. ima_appraise=log 모드에서 먼저 테스트하는 것을 권장합니다.

컴플라이언스 매핑(Mapping)

IMA/EVM은 다양한 보안 인증과 컴플라이언스 표준의 요구사항을 충족합니다.

표준관련 요구사항IMA/EVM 충족 방법
FIPS 140-3암호 모듈 무결성 검증커널 암호 모듈의 IMA 서명 검증, HMAC 기반 무결성 테스트
Common Criteria (CC)EAL4+ 무결성 보호 (FIA, FPT)IMA appraise로 실행 파일 무결성, EVM으로 메타데이터 보호
NIST SP 800-155BIOS 무결성 측정 가이드라인IMA가 BIOS→부트로더→커널→사용자공간까지 체인 확장
STIG (DISA)V-230264: FIPS 모드, V-230502: 파일 무결성ima_appraise=enforce + fips=1
CIS Benchmark파일 무결성 모니터링 (1.4.1)IMA measure + 원격 증명으로 지속적 모니터링
PCI-DSS v411.5: 파일 무결성 모니터링IMA audit + 측정 리스트 모니터링
NIST SP 800-53SI-7: 소프트웨어/펌웨어/정보 무결성IMA measure/appraise + EVM 서명
TCG (Trusted Computing)TPM 기반 플랫폼 무결성IMA+TPM으로 TCG 사양 준수 측정/증명
# FIPS 140-3 + IMA 설정 예시
# 커널 cmdline:
# fips=1 ima_policy=appraise_tcb ima_appraise=enforce ima_hash=sha256

# STIG 준수 확인
fips-mode-setup --check
grep ima_appraise /proc/cmdline

# CIS 파일 무결성 체크
cat /sys/kernel/security/ima/violations
# 0이 아니면 무결성 위반 발생

# 원격 증명 기반 지속적 모니터링 (PCI-DSS 11.5)
keylime_tenant -c add --ima_sign_verification_keys /etc/keys/ima-cert.pem \
    --uuid $(cat /sys/class/dmi/id/product_uuid)

컴플라이언스별 IMA/EVM 구성 가이드

컴플라이언스필수 커널 설정부트 파라미터추가 요구사항
FIPS 140-3CONFIG_IMA=y
CONFIG_CRYPTO_FIPS=y
fips=1 ima_hash=sha256FIPS 인증 암호 모듈만 사용
CC EAL4+CONFIG_IMA_APPRAISE=y
CONFIG_EVM=y
ima_appraise=enforce전체 파일 서명, EVM 활성화
STIGCONFIG_IMA=yima_policy=appraise_tcbaide 또는 IMA 측정 리스트 모니터링
CIS Level 2CONFIG_IMA=yima_policy=tcb파일 무결성 모니터링 도구
PCI-DSS v4CONFIG_IMA=y
CONFIG_AUDIT=y
ima_policy=tcb
audit=1
변경 탐지 메커니즘, 주간 리포트
# FIPS + IMA 종합 체크 스크립트
#!/bin/bash

echo "=== FIPS 모드 확인 ==="
cat /proc/sys/crypto/fips_enabled

echo "=== IMA 상태 확인 ==="
echo "측정 엔트리: $(cat /sys/kernel/security/ima/runtime_measurements_count)"
echo "위반 수: $(cat /sys/kernel/security/ima/violations)"
echo "해시 알고리즘: $(cat /sys/kernel/security/ima/ima_hash 2>/dev/null || echo N/A)"
echo "템플릿: $(cat /sys/kernel/security/ima/ima_template 2>/dev/null || echo N/A)"

echo "=== EVM 상태 ==="
cat /sys/kernel/security/evm

echo "=== TPM PCR 10 ==="
tpm2_pcrread sha256:10 2>/dev/null || echo "TPM 접근 실패"

echo "=== 키링 상태 ==="
keyctl show %keyring:.ima 2>/dev/null
keyctl show %keyring:.evm 2>/dev/null

echo "=== Audit IMA 이벤트 (최근 10건) ==="
ausearch -m INTEGRITY_DATA -m INTEGRITY_STATUS -ts recent 2>/dev/null | tail -10

트러블슈팅

증상원인해결
부팅 중 Permission denied 폭주ima_appraise=enforce + xattr 미설정ima_appraise=fix로 부팅 후 evmctl ima_sign
security.ima: unable to set읽기 전용 파일시스템 또는 xattr 미지원mount -o remount,rw, tune2fs -O user_xattr
EVM: verification failedEVM 키 미로드 상태에서 접근echo 1 > /sys/kernel/security/evm 후 재시도
측정 리스트가 비어있음IMA 정책 미로드ima_policy=tcb 부트 파라미터 추가
appraise: MISSINGsecurity.ima xattr 없음evmctl ima_hash 또는 evmctl ima_sign
appraise: FAIL파일 변경 후 xattr 미갱신evmctl ima_sign -k key.pem 파일경로
TPM PCR 값 불일치TPM 접근 실패 또는 tpm2-tss 문제systemctl restart tpm2-abrmd, TPM 드라이버 확인
Key was rejected by service서명 키가 .ima/.evm 키링에 없음evmctl import cert.x509 %keyring:.ima
initramfs 내 파일 appraise 실패initramfs 재생성 시 서명 미포함dracut --rebuild --force + IMA 서명
violations 카운터 증가파일 변경 후 측정 전 접근정책 순서 점검, TOE(Time of Evaluation) 확인

디버그 절차

# 1. IMA 상태 전반 확인
cat /sys/kernel/security/ima/ascii_runtime_measurements | wc -l
cat /sys/kernel/security/ima/violations
cat /sys/kernel/security/ima/runtime_measurements_count

# 2. 현재 로드된 정책 확인
cat /sys/kernel/security/ima/policy 2>/dev/null || \
    echo "CONFIG_IMA_READ_POLICY=n 또는 정책 미로드"

# 3. EVM 상태 확인
cat /sys/kernel/security/evm
# 0: 비활성, 1: HMAC, 2: 서명, 6: HMAC+서명

# 4. xattr 상세 확인
getfattr -d -m security /usr/bin/bash
getfattr -n security.ima -e hex /usr/bin/bash
getfattr -n security.evm -e hex /usr/bin/bash

# 5. audit 로그에서 IMA 이벤트 검색
ausearch -m INTEGRITY_DATA -m INTEGRITY_STATUS \
    -m INTEGRITY_RULE -m INTEGRITY_PCR -ts recent

# 6. dmesg에서 IMA/EVM 메시지 확인
dmesg | grep -iE "ima|evm|integrity"

# 7. 키링 상태 확인
keyctl show %keyring:.ima
keyctl show %keyring:.evm
keyctl show %keyring:.builtin_trusted_keys
keyctl show %keyring:.platform

# 8. TPM 상태 확인
tpm2_pcrread sha256:10
tpm2_getcap properties-fixed | grep -i manufacturer
파일 접근 거부 (-EACCES) security.ima xattr 존재? No → evmctl ima_sign 실행 해시 일치? (evmctl ima_verify) No → 파일 변경됨, 재서명 EVM 검증 통과? (security.evm) No → EVM 키 확인, 재서명 정책/키링 점검

성능 영향과 최적화

IMA/EVM은 파일 접근 경로에 암호화 연산을 추가하므로 성능 영향이 있습니다. 특히 ima_appraise=enforce 모드에서 대량의 파일을 여는 워크로드(예: 컴파일, 컨테이너 이미지 풀)에서 체감됩니다.

시나리오성능 영향최적화 방법
IMA measure만 (tcb)1~3%dont_measure로 가상 FS 제외
IMA appraise (enforce)3~8%iint 캐시, dont_appraise 활용
EVM HMAC추가 1~2%HMAC-SHA1 (SHA256보다 빠름)
대용량 파일 해싱I/O 바운드비동기 해시 (ahash), fs-verity 전환
컨테이너 이미지 풀5~15%다이제스트 리스트, 이미지 사전 서명
# IMA 성능 프로파일링

# 1. 파일 열기 지연 측정 (strace)
strace -T -e trace=open,openat ls /usr/bin/ 2>&1 | tail

# 2. IMA 해시 계산 시간 (ftrace)
echo 1 > /sys/kernel/debug/tracing/events/ima/ima_hash/enable
cat /sys/kernel/debug/tracing/trace_pipe

# 3. iint 캐시 히트율 확인
cat /proc/slabinfo | grep ima_iint

# 4. 비동기 해시 사용 확인
grep -r "ahash" /sys/kernel/security/ima/ 2>/dev/null

# 5. 정책 최적화 — 불필요한 파일시스템 제외
dont_measure fsmagic=0x9fa0     # proc
dont_measure fsmagic=0x62656572  # sysfs
dont_measure fsmagic=0x64626720  # debugfs
dont_measure fsmagic=0x01021994  # tmpfs
dont_measure fsmagic=0x73636673  # securityfs
dont_measure fsmagic=0xcafe4a11  # bpf
dont_measure fsmagic=0x27e0eb   # cgroup
dont_measure fsmagic=0x63677270  # cgroup2
dont_measure fsmagic=0x19800202  # mqueue
dont_measure fsmagic=0x858458f6  # ramfs
dont_measure fsmagic=0x6e736673  # nsfs
💡

성능 최적화 핵심: IMA의 성능 영향을 최소화하려면 (1) 가상 파일시스템(VFS)을 dont_measure/dont_appraise로 제외하고, (2) CONFIG_IMA_DEFAULT_HASH=sha256을 사용하며(SHA-512보다 빠름), (3) 다이제스트 리스트를 활용하여 xattr 조회 횟수를 줄이세요. fs-verity 지원 환경에서는 sigv3 모드가 대용량 파일에서 가장 빠릅니다.