IPMI工具BMC配置完全指南

IPMI工具BMC配置完全指南

本文为您提供IPMI(智能平台管理接口)和BMC(基板管理控制器)的完整配置指南。通过本指南,您将学会如何使用ipmitool管理服务器的硬件监控和远程管理功能。

章节内容
1. 简介IPMI和BMC基础概念
2. 准备工作软件安装和环境配置
3. 基本概念IPMI通道、权限级别详解
4. 连接方式本地和远程连接方法
5. 网络配置BMC网络设置详解
6. 用户管理用户创建、权限设置
7. 传感器监控硬件状态监控
8. 电源管理远程电源控制
9. 系统事件日志SEL管理
10. 串口重定向SOL配置
11. 可更换单元FRU信息管理
12. 安全最佳实践安全配置建议
13. 故障排除常见问题解决

简介

### 什么是IPMI? **智能平台管理接口(IPMI)** 是一种标准化的硬件管理接口规范,它使管理员能够在不依赖操作系统的情况下远程管理和监控服务器。它通过专用的**基板管理控制器(BMC)** 运行,BMC是一个嵌入式微控制器,具有自己的处理器、内存和网络接口。 ### 什么是BMC? **基板管理控制器(BMC)** 是IPMI功能的核心。这是一个专用的服务处理器,具有以下特点: - 独立于主CPU和操作系统运行 - 拥有专用网络接口(可以与主机共享或使用专用端口) - 监控系统健康传感器(温度、电压、风扇) - 控制系统电源状态 - 提供远程控制台访问(KVM over IP,串口重定向) - 记录硬件事件 - 即使服务器断电也能保持运行(待机电源) ### 什么是ipmitool? `ipmitool` 是用于管理支持IPMI设备的开源命令行工具。它可以: - 配置BMC网络设置 - 管理BMC用户账户 - 读取传感器数据 - 控制电源状态 - 访问系统事件日志 - 建立串口重定向会话 ---

准备工作

### 软件安装 ```bash # Debian/Ubuntu sudo apt-get update sudo apt-get install ipmitool openipmi # RHEL/CentOS/Rocky/AlmaLinux sudo dnf install ipmitool OpenIPMI OpenIPMI-tools # SUSE/openSUSE sudo zypper install ipmitool # Arch Linux sudo pacman -S ipmitool ``` ### 内核模块 对于本地访问,加载所需的内核模块: ```bash # 加载IPMI驱动 sudo modprobe ipmi_devintf sudo modprobe ipmi_si sudo modprobe ipmi_msghandler # 验证模块是否加载 lsmod | grep ipmi # 设置开机自启 echo -e "ipmi_devintf\nipmi_si\nipmi_msghandler" | sudo tee /etc/modules-load.d/ipmi.conf ``` ### 验证本地访问 ```bash # 检查IPMI设备是否存在 ls -la /dev/ipmi* # 测试基本连接 sudo ipmitool mc info ``` ---

基本概念

### IPMI通道 IPMI使用**通道**进行通信。每个通道代表一个通信路径: | 通道 | 典型用途 | |------|----------| | 0 | IPMB(智能平台管理总线) | | 1 | 主要LAN通道(远程访问最常用) | | 2 | 次要LAN或串口 | | 6-7 | LAN保留 | | 14 | 当前通道(SMbus) | | 15 | 系统接口 | **查找可用通道:** ```bash # 检查通道1的信息(典型LAN) ipmitool channel info 1 # 遍历通道查找活动通道 for i in {0..15}; do echo "=== 通道 $i ===" ipmitool channel info $i 2>/dev/null done ``` ### 用户权限级别 | 级别 | 数值 | 权限 | |------|------|------| | 回调 | 1 | 最低 - 仅回调访问 | | 用户 | 2 | 只读访问传感器、SEL | | 操作员 | 3 | 读取 + 有限配置 | | 管理员 | 4 | 访问所有IPMI功能 | | OEM | 5 | 厂商特定扩展访问 | | 无访问 | 15 | 账户禁用 | ### 认证类型 | 类型 | 描述 | |------|------| | NONE | 无认证(不安全!) | | MD2 | MD2哈希认证 | | MD5 | MD5哈希认证 | | PASSWORD | 明文(避免使用!) | | OEM | 厂商特定 | **现代BMC支持IPMI 2.0与RMCP+(推荐):** - 使用更强加密(AES,HMAC) - 支持完整性检查 - 提供保密性 ---

连接方式

### 本地访问 在具有IPMI硬件的服务器上直接运行命令: ```bash # 基本格式(使用/dev/ipmi0或/dev/ipmi/0) sudo ipmitool # 显式指定接口 sudo ipmitool -I open # 示例 sudo ipmitool mc info # BMC信息 sudo ipmitool sensor list # 所有传感器 sudo ipmitool chassis status # 机箱状态 ``` ### 通过LAN远程访问(IPMI 1.5) ```bash # 基本格式 ipmitool -I lan -H -U -P # 使用环境变量存储密码(更安全) export IPMI_PASSWORD="your_password" ipmitool -I lan -H 192.168.1.100 -U admin -E # 指定端口(默认:623) ipmitool -I lan -H 192.168.1.100 -p 623 -U admin -P password ``` ### 通过LANPLUS远程访问(IPMI 2.0 - 推荐) ```bash # LANPLUS提供加密和更强认证 ipmitool -I lanplus -H -U -P # 指定密钥套件(默认通常是3) ipmitool -I lanplus -H 192.168.1.100 -U admin -P password -C 17 ``` **密钥套件参考:** | 套件 | 认证 | 完整性 | 保密性 | |------|------|--------|--------| | 0 | 无 | 无 | 无 | | 1 | HMAC-SHA1 | 无 | 无 | | 2 | HMAC-SHA1 | HMAC-SHA1-96 | 无 | | 3 | HMAC-SHA1 | HMAC-SHA1-96 | AES-CBC-128 | | 17 | HMAC-SHA256 | HMAC-SHA256-128 | AES-CBC-128 | **当可用时,始终使用密钥套件17以获得最高安全性。** ### 接口汇总 | 接口 | 标志 | 用途 | |------|------|------| | `open` | `-I open` | 通过内核驱动本地访问 | | `lan` | `-I lan` | 远程IPMI 1.5(无加密) | | `lanplus` | `-I lanplus` | 远程IPMI 2.0(加密) | | `serial` | `-I serial` | 直接串口连接 | | `usb` | `-I usb` | USB接口(某些系统) | ---

网络配置

### 查看当前LAN设置 ```bash # 通道1的完整LAN配置 ipmitool lan print 1 # 示例输出: # 设置进度 : 设置完成 # 支持认证类型 : NONE MD2 MD5 PASSWORD # 启用认证类型 : 回调 : MD2 MD5 # : 用户 : MD2 MD5 # : 操作员 : MD2 MD5 # : 管理员 : MD2 MD5 # : OEM : MD2 MD5 # IP地址来源 : 静态地址 # IP地址 : 192.168.1.100 # 子网掩码 : 255.255.255.0 # MAC地址 : 00:25:90:xx:xx:xx # 默认网关IP : 192.168.1.1 # VLAN ID : 禁用 # ... ``` ### 配置静态IP地址 ```bash # 设置IP地址来源为静态 ipmitool lan set 1 ipsrc static # 设置IP地址 ipmitool lan set 1 ipaddr 192.168.1.100 # 设置子网掩码 ipmitool lan set 1 netmask 255.255.255.0 # 设置默认网关 ipmitool lan set 1 defgw ipaddr 192.168.1.1 # 可选设置备用网关 ipmitool lan set 1 bakgw ipaddr 192.168.1.2 ``` ### 配置DHCP ```bash # 启用DHCP ipmitool lan set 1 ipsrc dhcp # 验证更改 ipmitool lan print 1 | grep -E "IP地址来源|IP地址" ``` ### VLAN配置 ```bash # 启用VLAN,ID为100 ipmitool lan set 1 vlan id 100 # 设置VLAN优先级(0-7,默认0) ipmitool lan set 1 vlan priority 3 # 禁用VLAN ipmitool lan set 1 vlan id off ``` ### 访问控制 ```bash # 设置通道1的访问模式 ipmitool lan set 1 access on # 配置认证类型(按权限级别) # 格式:auth ipmitool lan set 1 auth admin md5 ipmitool lan set 1 auth operator md5 ipmitool lan set 1 auth user md5 # 启用密钥套件权限 # 仅允许管理员使用密钥套件17 ipmitool lan set 1 cipher_privs XXXXXXXXXXXXXXXa # |||||||||||||||| # 0123456789012345(密钥套件) # X=无,a=管理员,o=操作员,u=用户 # 验证密钥套件 ipmitool lan print 1 | grep -i cipher ``` ### ARP配置 ```bash # 启用免费ARP ipmitool lan set 1 arp respond on ipmitool lan set 1 arp generate on # 设置ARP间隔(秒) ipmitool lan set 1 arp interval 2 ``` ### IPv6配置(如支持) ```bash # 检查IPv6支持 ipmitool lan6 print 1 # 启用IPv6 ipmitool lan6 set 1 enables static # 设置静态IPv6地址 ipmitool lan6 set 1 static_addr 0 2001:db8::100/64 # 设置IPv6网关 ipmitool lan6 set 1 gateway 0 2001:db8::1 ``` ---

用户管理

### 列出用户 ```bash # 列出通道1上的用户 ipmitool user list 1 # 输出: # ID 名称 呼叫 链路认证 IPMI消息 通道权限限制 # 1 true false false 无访问 # 2 admin true true true 管理员 # 3 operator true true true 操作员 # 4 readonly true true true 用户 ``` ### 创建新用户 ```bash # 查找未使用槽位(先检查用户列表) # 用户ID 1-15通常可用(ID 1通常是空/匿名) # 为用户ID 3设置用户名 ipmitool user set name 3 newadmin # 设置密码(会提示输入密码) ipmitool user set password 3 # 或直接设置密码(较不安全 - 在进程列表中可见) ipmitool user set password 3 "SecureP@ssw0rd!" # 启用用户 ipmitool user enable 3 # 设置权限级别(1=回调,2=用户,3=操作员,4=管理员) ipmitool user priv 3 4 1 # 用户3,管理员权限,通道1 # 启用用户的通道访问 ipmitool channel setaccess 1 3 callin=on ipmi=on link=on privilege=4 ``` ### 修改现有用户 ```bash # 更改密码 ipmitool user set password 2 # 更改权限级别 ipmitool user priv 2 3 1 # 将用户2更改为操作员,通道1 # 重命名用户(在某些BMC上可能需要先禁用) ipmitool user set name 2 newname ``` ### 禁用/删除用户 ```bash # 禁用用户 ipmitool user disable 3 # 移除通道访问 ipmitool channel setaccess 1 3 callin=off ipmi=off link=off privilege=15 # 删除用户(将名称设为空) ipmitool user set name 3 "" ``` ### 密码要求 大多数现代BMC强制执行: - 最少8个字符(有些要求12+) - 最多16-20个字符 - 大写字母、小写字母、数字、符号混合 - 密码中不能包含用户名 ```bash # 通过尝试设置弱密码测试密码策略 ipmitool user set password 3 "weak" # 可能返回:"设置用户密码命令失败(用户3)" ``` ---

传感器监控

### 列出所有传感器 ```bash # 带读数的完整传感器列表 ipmitool sensor list # 输出格式: # 传感器名称 | 值 | 单位 | 状态 | LNR | LCR | LNC | UNC | UCR | UNR # 进气温度 | 24.000 | C | ok | na | na | na | 42 | 46 | na # CPU1温度 | 45.000 | C | ok | na | na | na | 85 | 90 | na # FAN1 | 5400 | RPM | ok | 500 | 700 | na | na | na | na # PSU1功率 | 180 | Watts | ok | na | na | na | 900 | 950 | na # 阈值含义: # LNR = 下限不可恢复 # LCR = 下限临界 # LNC = 下限非临界 # UNC = 上限非临界 # UCR = 上限临界 # UNR = 上限不可恢复 ``` ### 传感器数据存储库(SDR) ```bash # 完整SDR转储(详细传感器信息) ipmitool sdr list # 特定类型 ipmitool sdr type list # 列出传感器类型 ipmitool sdr type Temperature # 仅温度传感器 ipmitool sdr type Fan # 仅风扇传感器 ipmitool sdr type Voltage # 仅电压传感器 ipmitool sdr type "Power Supply" # 电源传感器 # 按名称获取特定传感器 ipmitool sdr get "CPU1 Temp" # 基于实体查询 ipmitool sdr entity 3.1 # CPU1(实体3,实例1) ``` ### 读取特定传感器 ```bash # 获取单个传感器读数 ipmitool sensor get "进气温度" # 详细输出: # 正在定位传感器记录... # 传感器ID : 进气温度(0x1) # 实体ID : 7.1(系统板) # 传感器类型(阈值) : 温度 # 传感器读数 : 24 (+/- 0.500) 摄氏度 # 状态 : ok # 下限不可恢复 : na # 下限临界 : na # 下限非临界 : na # 上限非临界 : 42.000 # 上限临界 : 46.000 # 上限不可恢复 : na ``` ### 设置传感器阈值 ```bash # 设置阈值(顺序:lnr, lcr, lnc, unc, ucr, unr) # 对不想更改的阈值使用'na' ipmitool sensor thresh "进气温度" upper 40 45 50 # 设置下限阈值 ipmitool sensor thresh "FAN1" lower 400 600 800 # 完整阈值设置 ipmitool sensor thresh "CPU1温度" lower 5 10 15 upper 80 85 90 ``` ### 持续监控 ```bash # 监控传感器(每2秒刷新) watch -n 2 'ipmitool sensor list | grep -E "温度|风扇|功率"' # 导出CSV进行分析 ipmitool sensor list | awk -F'|' '{print $1","$2","$3","$4}' > sensors.csv ``` ---

电源管理

### 检查电源状态 ```bash # 机箱状态(包括电源状态) ipmitool chassis status # 输出: # 系统电源 : 开启 # 电源过载 : false # 电源互锁 : 非活动 # 主电源故障 : false # 电源控制故障 : false # 电源恢复策略 : 总是开启 # 上次电源事件 : 命令 # 机箱入侵 : 非活动 # 前面板锁定 : 非活动 # 驱动器故障 : false # 冷却/风扇故障 : false # 快速电源检查 ipmitool power status # 输出:机箱电源已开启 ``` ### 电源控制 ```bash # 开启电源 ipmitool power on # 或 ipmitool chassis power on # 优雅关机(ACPI信号 - 需要操作系统支持) ipmitool power soft # 硬关机(立即 - 如同按住电源按钮) ipmitool power off # 电源循环(关闭然后开启) ipmitool power cycle # 硬重置(如按重置按钮) ipmitool power reset # 诊断中断(NMI) ipmitool power diag ``` ### 电源恢复策略 控制断电后交流电源恢复时发生的情况: ```bash # 检查当前策略 ipmitool chassis status | grep "电源恢复" # 设置策略 ipmitool chassis policy always-on # 交流电源恢复后总是开启 ipmitool chassis policy always-off # 保持关闭,等待手动电源开启 ipmitool chassis policy previous # 返回断电前的状态 ``` ### 启动设备配置 ```bash # 设置下次启动设备(一次性) ipmitool chassis bootdev pxe # 网络启动(PXE) ipmitool chassis bootdev disk # 硬盘 ipmitool chassis bootdev cdrom # CD/DVD驱动器 ipmitool chassis bootdev bios # 进入BIOS设置 ipmitool chassis bootdev floppy # 软盘(旧式) ipmitool chassis bootdev none # 无覆盖 # 持久启动设备(重启后仍有效) ipmitool chassis bootdev disk options=persistent # EFI启动选项 ipmitool chassis bootdev disk options=efiboot # 强制传统启动 ipmitool chassis bootdev disk options=legacy # 检查启动参数 ipmitool chassis bootparam get 5 ``` ### 启动标志 ```bash # 查看当前启动标志 ipmitool raw 0x00 0x09 0x05 0x00 0x00 # 清除启动标志 ipmitool raw 0x00 0x08 0x05 0x80 0x00 0x00 0x00 0x00 ``` ---

系统事件日志(SEL)

(SEL) ### 查看SEL ```bash # 查看所有SEL条目 ipmitool sel list # 输出: # 1 | 2024-01-15 | 10:30:45 | 温度 #0x01 | 上限临界变高 # 2 | 2024-01-15 | 10:30:50 | 温度 #0x01 | 上限临界变低 # 3 | 2024-01-15 | 14:22:10 | 电源单元 #0x02 | 电源关闭/下降 # 扩展/详细SEL ipmitool sel elist # 获取特定条目 ipmitool sel get 1 # 时间范围(如支持) ipmitool sel list first 10 # 前10个条目 ipmitool sel list last 10 # 最后10个条目 ``` ### SEL信息 ```bash # SEL详细信息 ipmitool sel info # 输出: # SEL信息 # 版本 : 1.5(v1.5,v2兼容) # 条目 : 45 # 空闲空间 : 8832字节 # 使用百分比 : 35% # 最后添加时间 : 2024-01-15 14:22:10 # 最后删除时间 : 不可用 # 溢出 : false # 支持命令 : '预留' '获取分配信息' ``` ### 清除SEL ```bash # 清除所有条目(警告:不可恢复) ipmitool sel clear # 验证清除 ipmitool sel info ``` ### 保存SEL ```bash # 保存到文件(清除前有用) ipmitool sel save sel_backup_$(date +%Y%m%d).txt # 保存扩展格式 ipmitool sel elist > sel_extended_$(date +%Y%m%d).txt # 写入格式化的可读输出 ipmitool sel list | while read line; do echo "$(date '+%Y-%m-%d %H:%M:%S') - $line" done > sel_timestamped.log ``` ### SEL时间戳 ```bash # 获取BMC时间 ipmitool sel time get # 设置BMC时间(UTC) ipmitool sel time set "01/15/2024 10:30:00" # 与系统时间同步 ipmitool sel time set "$(date -u '+%m/%d/%Y %H:%M:%S')" ``` ---

串口重定向(SOL)

(SOL) ### 什么是SOL? **串口重定向(SOL)** 将服务器的串口控制台输出重定向到网络,允许: - 远程BIOS配置 - 引导加载程序访问(GRUB,systemd-boot) - 网络断开时的紧急控制台 - 内核调试 ### 配置SOL ```bash # 检查SOL状态 ipmitool sol info # 在通道1上启用SOL ipmitool sol set enabled true 1 # 设置SOL权限级别(使用SOL所需的最低级别) ipmitool sol set privilege-level admin 1 # 设置波特率(必须匹配服务器的串口配置) ipmitool sol set volatile-bit-rate 115200 1 ipmitool sol set non-volatile-bit-rate 115200 1 # SOL负载通道(通常匹配LAN通道) ipmitool sol payload enable 1 2 # 为用户ID 2在通道1上启用SOL ``` ### 激活SOL会话 ```bash # 启动SOL会话(远程) ipmitool -I lanplus -H 192.168.1.100 -U admin -P password sol activate # SOL会话控制: # ~. 终止会话 # ~^Z 暂停会话(如果使用SSH类终端) # ~B 发送中断 # ~? 帮助 # 停用SOL(如果卡住) ipmitool -I lanplus -H 192.168.1.100 -U admin -P password sol deactivate ``` ### 服务器端配置 要使SOL正常工作,服务器的操作系统/BIOS必须重定向串口输出: **GRUB2配置(/etc/default/grub):** ```bash GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8" GRUB_TERMINAL="serial console" GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" ``` **重新生成GRUB:** ```bash grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/CentOS update-grub # Debian/Ubuntu ``` **登录提示的Getty(/etc/systemd/system/serial-getty@ttyS0.service):** ```bash systemctl enable serial-getty@ttyS0.service systemctl start serial-getty@ttyS0.service ``` ---

可更换单元(FRU)

(FRU) ### 什么是FRU? **可更换单元(FRU)** 数据包含硬件标识和库存信息: - 序列号 - 零件号 - 制造商信息 - 产品名称 - 资产标签 ### 读取FRU数据 ```bash # 列出所有FRU设备 ipmitool fru print # 输出: # FRU设备描述 : 内置FRU设备(ID 0) # 板制造日期 : 2024年1月15日 星期一 10:00:00 # 板制造商 : 戴尔公司 # 板产品 : PowerEdge R640 # 板序列 : XXXXXX # 板零件号 : 0XXXX # 产品制造商 : 戴尔公司 # 产品名称 : PowerEdge R640 # 产品零件号 : PowerEdge R640 # 产品序列 : SVCTAGXXX # 产品资产标签 : # 读取特定FRU ID ipmitool fru print 0 # 原始FRU转储 ipmitool fru read 0 fru_backup.bin ``` ### 编辑FRU数据 ```bash # 设置资产标签 ipmitool fru edit 0 field p 5 "ASSET-12345" # 字段: # c = 机箱 # b = 板 # p = 产品 # 字段编号因区域而异(检查FRU规范) # 从文件写入FRU ipmitool fru write 0 fru_data.bin ``` ---

安全最佳实践

### 1. 网络隔离 ```bash # BMC应在隔离的管理网络上 # 示例VLAN设置 ipmitool lan set 1 vlan id 100 # 在管理网络上使用防火墙规则 # 仅允许来自已知管理员子网的访问 ``` ### 2. 强认证 ```bash # 使用IPMI 2.0与最强密钥套件 ipmitool -I lanplus -C 17 ... # 禁用弱认证 ipmitool lan set 1 auth admin md5 # 移除NONE,MD2 ipmitool lan set 1 auth operator md5 ipmitool lan set 1 auth user md5 # 或限制密钥套件 ipmitool lan set 1 cipher_privs XXXXXXXXXXXXXXXXa # 仅管理员允许套件17 ``` ### 3. 用户管理 ```bash # 禁用未使用的用户槽位 for i in 3 4 5 6 7 8 9 10; do ipmitool user disable $i done # 移除默认/工厂账户 ipmitool user set name 2 "localadmin" # 重命名默认账户 ipmitool user set password 2 # 更改密码 # 使用基于角色的访问 # 为监控(用户)、操作(操作员)、完全访问(管理员)创建单独账户 ``` ### 4. 禁用不必要的服务 ```bash # 如果不使用SOL ipmitool sol set enabled false 1 # 如果可能,禁用BMC Web界面的HTTP/HTTPS访问 # (厂商特定,通常通过Web UI或原始命令) ``` ### 5. 定期审计 ```bash # 检查SEL中的未授权访问尝试 ipmitool sel list | grep -i -E "auth|login|user|password" # 监控活动会话 ipmitool session info all # 终止可疑会话 ipmitool session info all | grep -v "session handle" | awk '{print $1}' | while read id; do ipmitool session close $id done ``` ### 6. 固件更新 ```bash # 检查BMC固件版本 ipmitool mc info | grep "Firmware Revision" # 更新是厂商特定的 - 通常通过: # - Web界面 # - 厂商工具(戴尔racadm,惠普hponcfg,超微sum) # - TFTP更新 ``` ---

故障排除

### 连接问题 ```bash # 测试基本连通性 ping # 检查IPMI端口(UDP 623) nc -vzu 623 # 尝试不同接口/密钥套件 ipmitool -I lanplus -C 3 -H -U admin -P password mc info ipmitool -I lan -H -U admin -P password mc info # 启用详细输出 ipmitool -I lanplus -H -U admin -P password -v mc info ipmitool -I lanplus -H -U admin -P password -vvv mc info # 更详细 ``` ### 认证失败 ```bash # 首先本地验证凭证 sudo ipmitool user list 1 # 重置为已知密码 sudo ipmitool user set password 2 "NewPassword123!" # 检查用户是否启用 sudo ipmitool user enable 2 # 验证通道访问 sudo ipmitool channel getaccess 1 2 ``` ### BMC重置 ```bash # 温重置(软件重置) ipmitool mc reset warm # 冷重置(硬件重置 - 更彻底) ipmitool mc reset cold # 等待30-60秒让BMC恢复 sleep 60 ipmitool mc info ``` ### 传感器读取问题 ```bash # 重新读取SDR缓存 ipmitool sdr dump sensor_cache.bin ipmitool sdr list -S sensor_cache.bin # 强制传感器重新扫描 ipmitool sdr list -v 2>/dev/null | head -50 ``` ### SOL不工作 ```bash # 检查SOL配置 ipmitool sol info # 验证SOL对用户启用 ipmitool sol payload status 1 2 # 通道1,用户2 # 如需要启用 ipmitool sol payload enable 1 2 # 强制停用任何卡住的会话 ipmitool sol deactivate # 检查波特率匹配 ipmitool sol set volatile-bit-rate 115200 1 ``` ### 常见错误消息 | 错误 | 原因 | 解决方案 | |------|------|----------| | "无法打开设备" | 缺少IPMI驱动 | 加载ipmi_si,ipmi_devintf模块 | | "无法建立LAN会话" | 网络/认证问题 | 检查IP、用户、密码、防火墙 | | "权限级别不足" | 用户缺少权限 | 提高用户权限级别 | | "RAKP 2 HMAC无效" | 密码不匹配 | 验证密码,尝试较短密码 | | "会话限制超出" | 活动会话过多 | 关闭未使用会话 | | "命令不受支持" | BMC不支持 | 检查BMC功能 | ---

自动化配置脚本

除了上述指南,我们还创建了一个自动化脚本来执行常见的BMC配置任务:

#!/bin/bash

# IPMI Tool BMC Configuration Script
# This script automates common BMC configuration tasks using ipmitool
# Requires: ipmitool, sudo access (for local operations)

set -euo pipefail  # Exit on error, undefined vars, pipe failures

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Logging function
log() {
    echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}

success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Configuration variables
BMC_HOST=""
BMC_USER="admin"
BMC_PASS=""
BMC_INTERFACE="lanplus"
BMC_CIPHER_SUITE="17"  # Use strongest cipher by default
LOCAL_ACCESS=false

# Function to display usage
usage() {
    cat </dev/null 2>&1; then
        success "BMC connectivity established"
        return 0
    else
        error "Failed to connect to BMC"
        return 1
    fi
}

# Function to view BMC status
view_bmc_status() {
    log "Fetching BMC status..."
    
    echo "=== BMC Information ==="
    $IPMITOOL_CMD mc info
    
    echo -e "\n=== Chassis Status ==="
    $IPMITOOL_CMD chassis status
    
    echo -e "\n=== FRU Information ==="
    $IPMITOOL_CMD fru print
    
    echo -e "\n=== SEL Information ==="
    $IPMITOOL_CMD sel info
}

# Function to configure network settings
configure_network() {
    log "Configuring network settings..."
    
    # Get current network settings
    echo "Current network configuration:"
    $IPMITOOL_CMD lan print 1
    
    # Ask for network configuration
    read -p "Configure static IP? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        read -p "Enter IP address: " IP_ADDR
        read -p "Enter subnet mask: " SUBNET_MASK
        read -p "Enter default gateway: " GATEWAY
        
        log "Setting static IP configuration..."
        $IPMITOOL_CMD lan set 1 ipsrc static
        $IPMITOOL_CMD lan set 1 ipaddr "$IP_ADDR"
        $IPMITOOL_CMD lan set 1 netmask "$SUBNET_MASK"
        $IPMITOOL_CMD lan set 1 defgw ipaddr "$GATEWAY"
        
        success "Network configuration updated"
        echo "New network configuration:"
        $IPMITOOL_CMD lan print 1
    fi
    
    # VLAN configuration
    read -p "Configure VLAN? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        read -p "Enter VLAN ID (or 'off' to disable): " VLAN_ID
        if [ "$VLAN_ID" != "off" ]; then
            $IPMITOOL_CMD lan set 1 vlan id "$VLAN_ID"
            success "VLAN ID set to $VLAN_ID"
        else
            $IPMITOOL_CMD lan set 1 vlan id off
            success "VLAN disabled"
        fi
    fi
}

# Function to manage users
configure_users() {
    log "Managing users..."
    
    echo "Current users:"
    $IPMITOOL_CMD user list 1
    
    read -p "Create new user? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        # Find next available user ID
        NEXT_ID=3  # Start from 3, assuming 1 is reserved and 2 might be admin
        while $IPMITOOL_CMD user list 1 | grep -q "^$NEXT_ID "; do
            ((NEXT_ID++))
            if [ $NEXT_ID -gt 15 ]; then
                error "No available user slots"
                return 1
            fi
        done
        
        read -p "Enter username: " USERNAME
        read -p "Enter privilege level (1=Callback, 2=User, 3=Operator, 4=Admin): " PRIV_LEVEL
        
        # Validate privilege level
        if ! [[ "$PRIV_LEVEL" =~ ^[1-4]$ ]]; then
            error "Invalid privilege level. Must be 1-4"
            return 1
        fi
        
        log "Creating user $USERNAME with ID $NEXT_ID..."
        $IPMITOOL_CMD user set name $NEXT_ID "$USERNAME"
        
        # Set password (will prompt)
        $IPMITOOL_CMD user set password $NEXT_ID
        
        $IPMITOOL_CMD user enable $NEXT_ID
        $IPMITOOL_CMD user priv $NEXT_ID $PRIV_LEVEL 1
        $IPMITOOL_CMD channel setaccess 1 $NEXT_ID callin=on ipmi=on link=on privilege=$PRIV_LEVEL
        
        success "User $USERNAME created with ID $NEXT_ID"
    fi
    
    # Option to disable unused accounts
    read -p "Disable unused user accounts? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        for id in {3..15}; do
            # Check if user exists and is not enabled
            if $IPMITOOL_CMD user list 1 | grep -q "^$id " && ! $IPMITOOL_CMD user list 1 | grep -q "^$id .*ADMINISTRATOR\|OPERATOR\|readonly"; then
                log "Disabling user ID $id"
                $IPMITOOL_CMD user disable $id
                $IPMITOOL_CMD channel setaccess 1 $id callin=off ipmi=off link=off privilege=15
            fi
        done
        success "Unused accounts disabled"
    fi
}

# Function to apply security hardening
configure_security() {
    log "Applying security hardening..."
    
    # Ensure strong authentication is enabled
    log "Configuring strong authentication..."
    $IPMITOOL_CMD lan set 1 auth admin md5
    $IPMITOOL_CMD lan set 1 auth operator md5
    $IPMITOOL_CMD lan set 1 auth user md5
    
    # Restrict cipher suites (only allow strong ones for admin)
    log "Restricting cipher suites..."
    # Allow only cipher suite 17 for admin (a), 3 for operator (o), 2 for user (u)
    # Format: 0123456789012345 (positions 0-15)
    # For admin: only allow suite 17 (position 17 doesn't exist, so we'll use 'a' in position 3)
    # Actually, the cipher_privs command uses positions 0-15 for cipher suites 1-16
    # Position 0 = cipher suite 1, position 15 = cipher suite 16
    # For cipher suite 17, the position is different in the string
    # Let's use a more conservative approach: only enable strong suites
    $IPMITOOL_CMD lan set 1 cipher_privs XXXXXXXXXXXXXXXa  # Only admin can use strong cipher
    
    # Enable ARP responses
    log "Configuring ARP settings..."
    $IPMITOOL_CMD lan set 1 arp respond on
    $IPMITOOL_CMD lan set 1 arp generate on
    $IPMITOOL_CMD lan set 1 arp interval 2
    
    # Disable SOL if not needed
    read -p "Disable SOL (Serial Over LAN)? (y/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        $IPMITOOL_CMD sol set enabled false 1
        success "SOL disabled"
    fi
    
    # Audit current SEL for security events
    log "Checking SEL for security events..."
    $IPMITOOL_CMD sel list | grep -i -E "auth|login|user|password" || echo "No authentication-related events found"
    
    success "Security hardening applied"
}

# Function to monitor sensors
monitor_sensors() {
    log "Starting sensor monitoring..."
    
    # Create a temporary file for monitoring
    TEMP_FILE=$(mktemp)
    
    # Initial sensor readings
    log "Initial sensor readings:"
    $IPMITOOL_CMD sensor list | grep -E "Temp|Fan|Power|Voltage"
    
    # Continuous monitoring
    log "Monitoring sensors continuously (Press Ctrl+C to stop)..."
    
    # Set up trap to clean up on exit
    trap 'rm -f $TEMP_FILE; echo -e "\nMonitoring stopped.";' INT TERM EXIT
    
    # Monitor loop
    while true; do
        # Get sensor readings and check for issues
        $IPMITOOL_CMD sensor list > "$TEMP_FILE"
        
        # Check for non-ok statuses
        CRITICAL_COUNT=$(grep -c -v "ok\|Disabled\|na" "$TEMP_FILE" || true)
        
        if [ "$CRITICAL_COUNT" -gt 0 ]; then
            warning "Found $CRITICAL_COUNT sensor(s) with non-ok status:"
            grep -v "ok\|Disabled\|na" "$TEMP_FILE"
            
            # Send notification (log to file for now)
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] CRITICAL SENSOR ALERT: $(grep -v 'ok\|Disabled\|na' "$TEMP_FILE")" >> /tmp/bmc_sensor_alerts.log
        fi
        
        # Display temperature and fan readings
        echo -e "\n[$(date '+%Y-%m-%d %H:%M:%S')] Sensor Status:"
        grep -E "Temp|Fan|Power|Voltage" "$TEMP_FILE" | grep -v "ok\|Disabled\|na" || echo "All monitored sensors OK"
        
        sleep 30  # Wait 30 seconds before next check
    done
}

# Main execution based on selected options
main() {
    log "Starting BMC configuration script..."
    
    # Test connectivity first if not local
    if [ "$LOCAL_ACCESS" = false ]; then
        if ! test_connectivity; then
            exit 1
        fi
    else
        log "Using local access mode"
    fi
    
    # Execute requested operations
    if [ "${VIEW_STATUS:-}" = true ]; then
        view_bmc_status
    fi
    
    if [ "${CONFIGURE_NETWORK:-}" = true ]; then
        configure_network
    fi
    
    if [ "${CONFIGURE_USERS:-}" = true ]; then
        configure_users
    fi
    
    if [ "${CONFIGURE_SECURITY:-}" = true ]; then
        configure_security
    fi
    
    if [ "${MONITOR_SENSORS:-}" = true ]; then
        monitor_sensors
    fi
    
    # If no specific action was requested, show menu
    if [ -z "${CONFIGURE_NETWORK:-}${CONFIGURE_USERS:-}${CONFIGURE_SECURITY:-}${MONITOR_SENSORS:-}${VIEW_STATUS:-}" ]; then
        log "No specific action requested. Showing menu:"
        echo "1. View BMC Status"
        echo "2. Configure Network"
        echo "3. Configure Users"
        echo "4. Apply Security Hardening"
        echo "5. Monitor Sensors"
        echo "6. Exit"
        
        read -p "Select an option (1-6): " OPTION
        
        case $OPTION in
            1) view_bmc_status ;;
            2) configure_network ;;
            3) configure_users ;;
            4) configure_security ;;
            5) monitor_sensors ;;
            6) exit 0 ;;
            *) error "Invalid option" ;;
        esac
    fi
    
    success "BMC configuration script completed"
}

# Run main function
main "$@"

总结

本指南涵盖了使用ipmitool进行IPMI和BMC配置的各个方面。通过遵循这些步骤和最佳实践,您可以有效地管理服务器的硬件层面,实现远程监控、电源控制、事件日志管理等功能。如需更多信息,请参阅官方IPMI规范和硬件供应商的文档。

发表回复

后才能评论