728x90
🚀 개요
Rocky Linux 8.6 환경에서 Dell 서버의 iDRAC(IPMI) 관리를 위한 **ipmitool 1.8.18**을 소스 코드로 직접 컴파일하고 설치하는 방법을 공유합니다.
특히, 외부망이 차단된 환경에서 발생할 수 있는 OpenSSL 호환성 오류 및 컴파일 이슈를 해결한 과정까지 상세히 기록했습니다.
📋 1. 사전 준비
- OS: Rocky Linux 8.6
- 목표: ipmitool 1.8.18 소스 컴파일 및 설치
- 환경: 외부망 차단 (오프라인 설치)
📦 2. 필수 패키지 설치 (인터넷 연결된 시스템에서)
- 인터넷 연결된 환경에서 다운로드후 scp, usb 등의 방법으로 데이터를 옮깁니다.
# sudo dnf install --downloadonly --downloaddir=./rpms gcc make autoconf automake libtool openssl-devel
⚙️ 3. ipmitool 소스 코드 다운로드
# wget https://github.com/ipmitool/ipmitool/archive/refs/tags/IPMITOOL_1_8_18.tar.gz
# tar -xvzf IPMITOOL_1_8_18.tar.gz
# cd ipmitool-IPMITOOL_1_8_18
🔗 4. 오프라인 서버에 패키지 설치
# sudo dnf install ./*.rpm
🚀 5. ipmitool 컴파일 및 설치
# ./bootstrap
# ./configure
# make
# sudo make install
❗ 6. 오류 발생 및 해결 과정 (Troubleshooting)
🔴 오류 1: error: storage size of ‘ctx’ isn’t known
- 원인 : OpenSSL 1.1 이상에서는 EVP_CIPHER_CTX 구조체의 직접 선언이 불가능합니다.
- 해결 방법 : src/plugins/lanplus/lanplus_crypt_impl.c 파일 수정
// 기존 코드
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
// 수정된 코드
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (ctx == NULL) {
return;
}
🔴 오류 2: passing argument 1 of ‘EVP_EncryptUpdate’ from incompatible pointer type
- 원인: EVP_EncryptUpdate에 포인터를 잘못 전달한 경우 발생
- 해결 방법: &ctx → ctx로 수정
// 잘못된 코드
EVP_EncryptUpdate(&ctx, output, &len, input, input_length);
// 수정된 코드
EVP_EncryptUpdate(ctx, output, &len, input, input_length);
🔴 오류 3: return with a value, in function returning void
- 원인: void 함수에서 return -1; 사용
- 해결 방법: return;으로 수정
// 잘못된 코드
return -1;
// 수정된 코드
return;
🟢오류 사항 모두 적용된 상태
# cat src/plugins/lanplus/lanplus_crypt_impl.c
----------------------------------------------------------------
#include "ipmitool/log.h"
#include "ipmitool/ipmi_constants.h"
#include "lanplus.h"
#include "lanplus_crypt_impl.h"
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <assert.h>
/* PRNG 초기화 */
int lanplus_seed_prng(uint32_t bytes)
{
return RAND_load_file("/dev/urandom", bytes) ? 0 : 1;
}
/* 랜덤 데이터 생성 */
int lanplus_rand(uint8_t *buffer, uint32_t num_bytes)
{
return RAND_bytes(buffer, num_bytes) ? 0 : 1;
}
/* HMAC 처리 */
uint8_t *lanplus_HMAC(uint8_t mac, const void *key, int key_len,
const uint8_t *d, int n, uint8_t *md, uint32_t *md_len)
{
const EVP_MD *evp_md = NULL;
if ((mac == IPMI_AUTH_RAKP_HMAC_SHA1) || (mac == IPMI_INTEGRITY_HMAC_SHA1_96))
evp_md = EVP_sha1();
else if ((mac == IPMI_AUTH_RAKP_HMAC_MD5) || (mac == IPMI_INTEGRITY_HMAC_MD5_128))
evp_md = EVP_md5();
#ifdef HAVE_CRYPTO_SHA256
else if ((mac == IPMI_AUTH_RAKP_HMAC_SHA256) || (mac == IPMI_INTEGRITY_HMAC_SHA256_128))
evp_md = EVP_sha256();
#endif
else
{
lprintf(LOG_DEBUG, "Invalid mac type 0x%x in lanplus_HMAC\n", mac);
assert(0);
}
return HMAC(evp_md, key, key_len, d, n, md, (unsigned int *)md_len);
}
/* AES CBC 128 암호화 */
void lanplus_encrypt_aes_cbc_128(const uint8_t *iv, const uint8_t *key,
const uint8_t *input, uint32_t input_length,
uint8_t *output, uint32_t *bytes_written)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0, total_len = 0;
*bytes_written = 0;
if (ctx == NULL)
return;
if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if (EVP_EncryptUpdate(ctx, output, &len, input, input_length) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
total_len += len;
if (EVP_EncryptFinal_ex(ctx, output + total_len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
total_len += len;
*bytes_written = total_len;
EVP_CIPHER_CTX_free(ctx);
}
/* AES CBC 128 복호화 */
void lanplus_decrypt_aes_cbc_128(const uint8_t *iv, const uint8_t *key,
const uint8_t *input, uint32_t input_length,
uint8_t *output, uint32_t *bytes_written)
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0, total_len = 0;
*bytes_written = 0;
if (ctx == NULL)
return;
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
assert((input_length % IPMI_CRYPT_AES_CBC_128_BLOCK_SIZE) == 0);
if (EVP_DecryptUpdate(ctx, output, &len, input, input_length) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
total_len += len;
if (EVP_DecryptFinal_ex(ctx, output + total_len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return;
}
total_len += len;
*bytes_written = total_len;
EVP_CIPHER_CTX_free(ctx);
}
✅ 7. 설치 확인
# ipmitool -V
ipmitool version 1.8.18-csv
🌐 8. iDRAC 원격 관리 예제
# ipmitool -I lanplus -H <iDRAC_IP> -U <ID> -P <PASSWORD> chassis power status
'OS > Linux' 카테고리의 다른 글
[Linux] Prometheus & Grafana 소스 컴파일 설치 및 Trouble Shooting (0) | 2025.02.21 |
---|---|
[Linux] PostgreSQL & Airflow 연동간 발생한 문제 (0) | 2025.02.20 |
[Linux] PostgreSQL, Airflow 및 OS 계정 연동 (0) | 2025.02.18 |
[Linux] Airflow 2.7.3 & PostgreSQL 13.18 설치 및 설정 매뉴얼 (Python 3.10.14 환경) (0) | 2025.02.17 |
[Linux] CentOS7.4 버전에서 Python 3.10.14 설치 및 Troubleshooting 매뉴얼 (0) | 2025.02.16 |