반면:
GNU/Linux를 실행하는 서버 및
해당 서버의 섀시 침입 감지 스위치
침입 감지 상태를 추적하여 이를
freeipmi
읽을 수 있도록 하는 해당 서버의 BIOS(또는 UEFI)
서버 상자가 열려 있는 경우 해당 서버가 작업을 수행하도록 하려면 어떻게 해야 합니까(예: 이메일 보내기 또는 간단히 종료)?
사용자숲security.stackexchange에 대해서는 "를 폴링하는 것이 좋습니다./dev/nvram
스토리지 섀시 침입 횟수에 대한 값을 얻으려면 약 0.5초마다 구문 분석하세요.. " (라이센스:CC-SA 3.0.) 이것은 비효율적인 것 같습니다. 확실히 더 좋은 방법이 있을까요?
답변1
다음은 펌웨어.intel.com/blog/accessing-uefi-variables-linux에서 인용되었습니다.
게시자: mfleming, 날짜: 2014년 1월 3일
이 문서에서는 UEFI 런타임 변수에 액세스하기 위해 Linux에서 제공하는 두 가지 방법과 장단점 및 일부 기록을 요약합니다.
The Legacy efivars Interface
Matt Domsch가 작성한 UEFI 변수와 상호 작용하기 위한 원래 인터페이스는 일반적인 Linux 커널 sysfs 파일 시스템을 통해 내보내집니다. 인터페이스는 UEFI 이전 EFI 시대에 Itanium 컴퓨터용으로 생성되었으므로 일부 역사적인 수하물이 함께 제공됩니다.
레거시 efivars 인터페이스는 sysfs 마운트 지점을 기준으로 "firmware/efi/vars/" 경로를 통해 내보내집니다. sysfs가 /sys에 설치되어 있다고 가정하면 efivars 파일이 포함된 디렉터리는 다음과 같습니다.
/sys/firmware/efi/vars/
new_var
특수 파일 및 를 제외하고del_var
위 마운트 지점의 각 항목은 그 자체로 디렉터리입니다. 즉, 런타임 시 액세스할 수 있는 각 UEFI 변수에 대한 디렉터리입니다.Boot0000-12345678-abcd-abcd-abcd-123456789abc/ Boot0001-12345678-abcd-abcd-abcd-123456789abc/ BootCurrent-12345678-abcd-abcd-abcd-123456789abc/ BootOrder-12345678-abcd-abcd-abcd-123456789abc/ BootSetup-12345678-abcd-abcd-abcd-123456789abc/ del_var Lang-12345678-abcd-abcd-abcd-123456789abc/ LangCodes-12345678-abcd-abcd-abcd-123456789abc/ new_var Setup-12345678-abcd-abcd-abcd-123456789abc/
UEFI 변수의 디렉터리 이름은 변수 이름과 변수의 GUID(Globally Unique Identifier)로 구성됩니다. 이 예:
Boot0000-12345678-abcd-abcd-abcd-123456789abc/
첫 번째 UEFI 부팅 변수의 디렉터리일 수 있습니다. 각 디렉토리에는 다음 파일이 있습니다.
attributes data guid raw_var size
이러한 파일의 대부분 내용은 사람이 읽을 수 있으며 동일한 이름의 UEFI 변수 매개 변수에 해당합니다. 바이너리 데이터가 포함된 "raw_var" 파일은 예외입니다. 예를 들어 위 부팅 항목의 "속성" 파일에는 다음 ASCII 문자열과 같은 내용이 포함됩니다.
EFI_VARIABLE_NON_VOLATILE EFI_VARIABLE_BOOTSERVICE_ACCESS EFI_VARIABLE_RUNTIME_ACCESS
이 변수는 비휘발성이며 UEFI 부팅 서비스 ExitBootServices() 호출 전후에 액세스할 수 있음을 나타냅니다. 사람이 읽을 수 있는 이러한 파일에 쓰는 것은 불가능합니다. 유일한 목적은 사용자에게 변수의 세부 정보를 제공하는 것입니다.
raw_var
사용자 공간에서 커널에 사용되는 UEFI 가변 바이너리 데이터 구조에 대한 읽기/쓰기를 허용하며 레거시 인터페이스의 핵심 부분입니다. 기존 변수에 대한 모든 수정은 "struct efi_variable" 개체를 전달하여 이 파일을 통해 수행됩니다.struct efi_variable { efi_char16_t VariableName[1024/sizeof(efi_char16_t)]; efi_guid_t VendorGuid; unsigned long DataSize; __u8 Data[1024]; efi_status_t Status; __u32 Attributes; } __attribute__((packed));
이름에서 알 수 있듯이 최상위 디렉터리의 특수 파일 "new_var" 및 "del_var"는 UEFI 변수를 생성하고 삭제하는 데 사용됩니다. 이러한 파일은 사람이 읽을 수 있는 텍스트를 사용하지 않습니다. 대신 "struct efi_variable" 개체가 커널과 사용자 공간 사이를 오가며 전달되어 새 변수를 생성하거나 기존 UEFI 변수를 삭제합니다.
Linux 커널에서 efivars 인터페이스를 유지하는 주된 이유는 이 인터페이스만 사용하는 일부 도구가 여전히 있기 때문입니다. efibootmgr 도구는 모든 Linux 배포판에서 사용할 수 있으며 UEFI 시스템에서 부팅 순서를 제어하는 데 사용되지만 여전히 이 인터페이스를 사용합니다. 레거시 도구 인터페이스.
그러나 기존 efivars 인터페이스에는 시간이 지남에 따라 골칫거리가 되기 시작한 몇 가지 제한 사항이 있었습니다.
가장 뚜렷한 단점은 읽고 쓸 수 있는 UEFI 변수 데이터의 크기에 상한이 있다는 것입니다. 커널 데이터 구조가 설계된 방식으로 인해 1024바이트 이상의 변수 데이터를 읽거나 쓰는 것은 불가능하며 일부 사용 사례에서는 이러한 제한이 문제가 됩니다.
또한 efivars 인터페이스에는 "new_var", "del_var" 및 "raw_var" 특수 파일을 통해 UEFI 변수의 중요한 "struct efi_variable" 데이터 구조의 읽기/쓰기 복사본만 처리하기 때문에 본질적으로 UEFI 변수를 조작하는 도구가 필요합니다. "struct efi_variable" 개체를 빌드하고 "del_var" 파일에 쓰지 않으면 UEFI 변수를 삭제할 수 없습니다.
efivarfs 파일 시스템
기존 efivar 인터페이스의 한계를 극복하기 위해 Matthew Garrett과 Jeremy Kerr는 새로운 Linux 파일 시스템을 만들었습니다. 이 새로운 파일 시스템의 이름은 "efivarfs"이며 Linux 커널 v3.10의 일부입니다.
다른 모든 Linux 파일 시스템과 마찬가지로 efivarfs는 파일에 액세스하려면 어딘가에 마운트해야 하며 다음 명령을 실행하여 수행할 수 있습니다.
mount -t efivarfs none /sys/firmware/efi/efivars
efivarfs에는 디렉터리가 포함되어 있지 않지만 이름이 UEFI 변수 이름 및 GUID로 구성된 파일이 포함되어 있습니다.
Boot0000-12345678-abcd-abcd-abcd-123456789abc Boot0001-12345678-abcd-abcd-abcd-123456789abc BootCurrent-12345678-abcd-abcd-abcd-123456789abc BootOrder-12345678-abcd-abcd-abcd-123456789abc BootSetup-12345678-abcd-abcd-abcd-123456789abc
각 파일에는 이진 데이터(예: 레거시 인터페이스의
new_var
,del_var
)가 포함되어 있지만 efivarfs의 데이터 구조는 UEFI 변수 속성 비트마스크에 대해 4바이트만 포함하고 나머지는 UEFI 변수 데이터입니다.struct new_efi_variable { u32 attributes; u8 data[0]; };
다른 모든 정보(변수 이름, GUID, 크기 등)는 읽고 쓰는 파일 이름에서 추론됩니다. 이를 통해 파일을 생성하거나 삭제하여 UEFI 변수를 생성하거나 삭제하는 것이 간단해졌습니다.
예를 들어, 다음 셸 명령은 새 변수를 생성합니다.
printf "\x07\x00\x00\x00\x00" > myvar-12345678-1234-1234-1234-123456789abc
myvar
GUID 와12345678-1234-1234-1234-123456789abc
bitmask 속성에 설정된 비트와EFI_VARIABLE_NON_VOLATILE
1 바이트의 데이터(마지막 )를 사용하여 이름이 지정됩니다.EFI_VARIABLE_BOOTSERVICE_ACCESS
EFI_VARIABLE_RUNTIME_ACCESS
\x00
파일 크기를 가져오는 일반적인 방법을 사용하여 변수 크기와 4바이트 속성 데이터를 찾을 수 있습니다. 예를 들어 다음 셸 명령을 실행합니다.
du -b myvar-12345678-1234-1234-1234-12345678abc
"5" - 변수 속성 비트마스크 4바이트와 데이터 1바이트를 인쇄합니다.
변수를 삭제하려면 efivarfs 파일 시스템에서 삭제하면 됩니다.
rm myvar-12345678-1234-1234-1234-12345678abc
분명히 이것은 명령줄과 셸 스크립트에서 UEFI 변수에 액세스하기 위한 보다 직관적인 인터페이스입니다. 무엇보다도, 기존 인터페이스와 달리 UEFI 변수에 읽고 쓸 수 있는 데이터 양에 제한이 없습니다.
물론 efivarfs에서 사용하는 데이터 구조는 레거시 인터페이스보다 훨씬 간단하지만 여전히 바이너리 데이터로 읽고 쓰며 레거시 인터페이스에서 제공하는 사람이 읽을 수 있는 파일보다 더 많은 정신적 처리가 필요합니다.
이 기사에서는 런타임 시 UEFI 변수에 액세스하기 위해 Linux에서 제공하는 두 가지 솔루션에 대해 간략하게 설명했습니다. 새로운 efivarfs 파일 시스템은 셸 스크립트(또는 명령줄에서도)에서 UEFI 변수에 액세스하는 데 유용한 인터페이스를 제공하지만 일부 도구는 여전히 이전 인터페이스를 사용하고 경우에 따라 사람이 읽을 수 있는 파일을 사용합니다. 순수 바이너리 인터페이스보다 더 나을 수도 있습니다. 에피바르프의.
Matt Fleming은 인텔 오픈 소스 기술 센터의 소프트웨어 엔지니어이자 Linux 커널(U)EFI 관리자입니다.