操作系统:Ubuntu 20.04
磁盘加密方案:基于LUKS与主板序列号的双重保护机制
1 核心目标
为服务器磁盘提供物理安全防护,确保磁盘在非授权服务器上无法被访问,同时保持合法服务器上的自动解密能力。
2 方案概述
本方案采用LUKS(Linux Unified Key Setup)磁盘加密标准,结合服务器主板序列号对加密密钥进行二次加密,实现以下安全特性:
磁盘级加密:使用AES-256加密算法保护数据,即使磁盘被盗也无法直接读取。硬件绑定:通过主板序列号生成唯一密钥,确保加密磁盘仅能在原服务器上解密。自动解密:在合法服务器上通过预置脚本实现开机自动解密,无需人工干预。
3 技术实现细节
3.1 对磁盘设置LUKS加密
选择Ubuntu启动盘选择镜像,进入安装界面

选择安装Ubuntu,其余默认,在选择安装类型界面,点击清除整个磁盘安装Ubuntu
并勾选加密ubuntu新安装以提高安全性,勾选加密整个磁盘空间

设置磁盘luks密码 将改动写入磁盘-创建用户信息-等待重启完成安装

3.2 绑定主板序列号的自动解密方案
3.2.1 方案架构
主板序列号 → 加密密钥文件 → LUKS解密 → 系统启动
↑ ↑
绑定验证 自动解密
3.2.2 环境准备
安装必要的工具
sudo apt-get update
sudo apt-get install -y cryptsetup openssl dmidecode
创建工作目录
sudo mkdir -p /etc/luks-keys
sudo chmod 700 /etc/luks-keys
3.2.3 创建自动解密脚本
主配置脚本 /usr/local/sbin/luks-bind-motherboard.sh
#!/bin/bash
# LUKS主板序列号绑定脚本
# 用法: sudo ./luks-bind-motherboard.sh /dev/sdX
set -e
# 参数检查
if [ "$#" -ne 1 ] || [ ! -b "$1" ]; then
echo "用法: $0 /dev/sdX (例如: /dev/sda3)"
exit 1
fi
# 检查root权限
if [ "$(id -u)" -ne 0 ]; then
echo "错误: 必须使用root权限运行"
exit 1
fi
DEVICE="$1"
DEVICE_BASENAME=$(basename "$DEVICE")
LUKS_MAPPER="sda3_crypt" # 根据你的crypttab修改
KEY_DIR="/etc/luks-keys"
KEY_FILE="$KEY_DIR/${DEVICE_BASENAME}.key"
ENC_KEY_FILE="$KEY_DIR/${DEVICE_BASENAME}.enc"
SERIAL_FILE="$KEY_DIR/motherboard.serial"
echo "[+] 正在绑定LUKS设备 $DEVICE 到主板序列号..."
# 获取主板序列号
echo "[+] 提取主板序列号..."
MB_SERIAL=$(dmidecode -t baseboard | grep "Serial Number" | awk '{print $3}')
if [ -z "$MB_SERIAL" ]; then
# 备用方法: 使用系统序列号
MB_SERIAL=$(dmidecode -s system-serial-number)
fi
if [ -z "$MB_SERIAL" ] || [ "$MB_SERIAL" = "Not Specified" ]; then
echo "错误: 无法获取主板序列号"
exit 1
fi
echo "[+] 主板序列号: $MB_SERIAL"
# 保存序列号
echo "$MB_SERIAL" > "$SERIAL_FILE"
chmod 400 "$SERIAL_FILE"
# 生成随机密钥
echo "[+] 生成LUKS密钥..."
dd if=/dev/urandom of="$KEY_FILE" bs=512 count=1 status=none
chmod 400 "$KEY_FILE"
# 使用主板序列号加密密钥
echo "[+] 加密密钥文件..."
openssl enc -aes-256-cbc -pbkdf2 -salt -iter 100000
-in "$KEY_FILE"
-out "$ENC_KEY_FILE"
-k "$MB_SERIAL"
chmod 400 "$ENC_KEY_FILE"
# 添加密钥到LUKS
echo "[+] 添加密钥到LUKS..."
cryptsetup luksAddKey "$DEVICE" "$KEY_FILE"
# 删除原密钥文件,可进行备份
rm -rf $KEY_FILE
echo "[+] LUKS绑定完成!"
echo "设备: $DEVICE"
echo "主板序列号: $MB_SERIAL"
echo "应急密钥: $KEY_FILE"
设置权限
sudo chmod +x /usr/local/sbin/luks-bind-motherboard.sh
3.2.4 创建initramfs解密脚本
解密脚本 /etc/initramfs-tools/scripts/local-top/luks-mb-decrypt
#!/bin/sh
PREREQ=""
prereqs() { echo "$PREREQ"; }
case $1 in
prereqs) prereqs; exit 0;;
esac
# 日志函数
log() {
echo "luks-mb-decrypt: $@" >/dev/kmsg 2>/dev/null || echo "luks-mb-decrypt: $@" >&2
}
. /scripts/functions
log "开始主板序列号自动解密..."
# 配置参数
LUKS_DEVICE="/dev/sda3"
LUKS_MAPPER="sda3_crypt"
KEY_DIR="/etc/luks-keys"
ENC_KEY_FILE="$KEY_DIR/sda3.enc"
SERIAL_FILE="$KEY_DIR/motherboard.serial"
# 检查必要文件
if [ ! -f "$SERIAL_FILE" ] || [ ! -f "$ENC_KEY_FILE" ]; then
log "错误: 缺少密钥文件,需要手动解密"
exit 0 # 退出但不阻止手动解密
fi
# 获取当前主板序列号
log "读取当前主板序列号..."
if [ -r /sys/class/dmi/id/board_serial ]; then
CURRENT_SERIAL=$(cat /sys/class/dmi/id/board_serial 2>/dev/null)
else
CURRENT_SERIAL=$(dmidecode -t baseboard 2>/dev/null | grep "Serial Number" | awk '{print $3}')
fi
# 备用方法: 使用系统序列号
if [ -z "$CURRENT_SERIAL" ] || [ "$CURRENT_SERIAL" = "Not Specified" ]; then
CURRENT_SERIAL=$(dmidecode -s system-serial-number 2>/dev/null)
fi
if [ -z "$CURRENT_SERIAL" ]; then
log "错误: 无法读取当前主板序列号"
exit 0
fi
log "当前序列号: $CURRENT_SERIAL"
# 读取存储的序列号
STORED_SERIAL=$(cat "$SERIAL_FILE" 2>/dev/null)
if [ -z "$STORED_SERIAL" ]; then
log "错误: 无法读取存储的序列号"
exit 0
fi
log "存储序列号: $STORED_SERIAL"
# 验证序列号
if [ "$CURRENT_SERIAL" != "$STORED_SERIAL" ]; then
log "错误: 主板序列号不匹配! 需要手动解密"
exit 0
fi
# 解密密钥文件
log "解密密钥文件..."
if ! openssl enc -aes-256-cbc -d -pbkdf2 -iter 100000 -md sha256
-in "$ENC_KEY_FILE"
-out /tmp/decrypted.key
-k "$CURRENT_SERIAL" 2>/dev/null; then
log "错误: 密钥解密失败"
exit 0
fi
# 解锁LUKS设备
log "解锁LUKS设备 $LUKS_DEVICE..."
if ! cryptsetup open --key-file /tmp/decrypted.key "$LUKS_DEVICE" "$LUKS_MAPPER" 2>/dev/null; then
log "错误: LUKS解锁失败"
rm -f /tmp/decrypted.key
exit 0
fi
# 清理临时文件
rm -f /tmp/decrypted.key
log "主板序列号自动解密成功"
exit 0
3.2.5 创建initramfs hook脚本
Hook脚本 /etc/initramfs-tools/hooks/luks-mb-decrypt
#!/bin/sh
PREREQ=""
prereqs() { echo "$PREREQ"; }
case $1 in
prereqs) prereqs; exit 0;;
esac
. /usr/share/initramfs-tools/hook-functions
# 复制必要工具
copy_exec /usr/bin/openssl
copy_exec /usr/sbin/cryptsetup
copy_exec /usr/sbin/dmidecode
# 复制密钥文件
if [ -d /etc/luks-keys ]; then
mkdir -p "$DESTDIR/etc/luks-keys"
cp /etc/luks-keys/motherboard.serial "$DESTDIR/etc/luks-keys/" 2>/dev/null || true
cp /etc/luks-keys/sda3.enc "$DESTDIR/etc/luks-keys/" 2>/dev/null || true
fi
# 确保内核模块可用
manual_add_modules dm_mod dm_crypt
设置权限
sudo chmod +x /etc/initramfs-tools/hooks/luks-mb-decrypt
3.2.6 配置系统模块
添加内核模块
echo -e "dm_mod
dm_crypt" | sudo tee -a /etc/initramfs-tools/modules
配置crypttab,确保 /etc/crypttab 包含:
sda3_crypt UUID=1445cda8-c36a-4353-b5d0-c81f81d568ef none luks,discard
3.2.7 执行绑定和解密配置
运行绑定脚本
sudo /usr/local/sbin/luks-bind-motherboard.sh /dev/sda3
更新initramfs
sudo update-initramfs -u -k all
验证initramfs内容
lsinitramfs /boot/initrd.img-$(uname -r) | grep -E "luks-keys|luks-mb-decrypt"
3.2.8 验证和测试
测试自动解密
# 重启系统测试
sudo reboot
# 检查启动日志
dmesg | grep -i "luks-mb-decrypt"
journalctl -b | grep -i "主板序列号"
验证解密状态
# 检查设备状态
lsblk -f
sudo cryptsetup status sda3_crypt
# 检查密钥文件
sudo ls -l /etc/luks-keys/
4 安全优势
● 防物理迁移:磁盘移至其他服务器时,因主板序列号不匹配,无法解密密钥文件。
● 密钥管理:主密钥不直接存储,只保留通过主板序列号加密后的密钥,降低泄露风险。
● 合规性:符合国内外数据保护法规对加密存储的要求。
5 客户价值
● 数据安全:即使磁盘被盗,数据仍保持加密状态,防止未授权访问。
● 无缝体验:合法服务器上实现自动化解密,不影响业务连续性。
● 灵活部署:支持物理服务器、虚拟机及云环境,适应不同IT架构。




