Linux服务器硬盘加解密方案

操作系统:Ubuntu 20.04

磁盘加密方案:基于LUKS与主板序列号的双重保护机制

1 核心目标

为服务器磁盘提供物理安全防护,确保磁盘在非授权服务器上无法被访问,同时保持合法服务器上的自动解密能力。

2 方案概述

本方案采用‌LUKS(Linux Unified Key Setup)‌磁盘加密标准,结合服务器主板序列号对加密密钥进行二次加密,实现以下安全特性:

‌磁盘级加密‌:使用AES-256加密算法保护数据,即使磁盘被盗也无法直接读取。‌硬件绑定‌:通过主板序列号生成唯一密钥,确保加密磁盘仅能在原服务器上解密。‌自动解密‌:在合法服务器上通过预置脚本实现开机自动解密,无需人工干预。

3 技术实现细节

3.1 对磁盘设置LUKS加密

选择Ubuntu启动盘选择镜像,进入安装界面
Linux服务器硬盘加解密方案

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

设置磁盘luks密码 将改动写入磁盘-创建用户信息-等待重启完成安装
Linux服务器硬盘加解密方案

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架构。

© 版权声明

相关文章

暂无评论

none
暂无评论...