基礎知識
-
Initrd(Initial RamDisk)
- Initrd是在Linux內核加載后,系統引導過程中掛載的一個臨時根文件系統。
- 使用Initrd的啟動過程分兩步:
- 掛載Initrd
- 掛載rootfs
- Initrd的組成部分
-
/bin
一些必要的命令:busybox cat echo mount lsmod depmod insmod cryptsetup ...
-
/dev
一些必要的字符設備文件:console null zero tty0 ...
-
/lib
一些必要的動態鏈接庫和內核模塊:libc.so libblkid.so libuuid.so libcryptsetup.so e1000.ko xen-blkfront.ko ...
-
init
掛載Initrd后執行的shell腳本:- 從grub的CMDLINE獲取rootfs所在分區及其他引導選項
- 加載內核模塊
- 掛載rootfs(解密)
switch_root
-
- Initrd 非必須,很多情況下可以只使用內核便進入系統。但對于存在某些重要分區,需要在Initrd中進行操作(例如解密)的情況,Initrd就是必須的
- 文件格式:通常是一個經過gzip壓縮的cpio歸檔格式(早期的Initrd是loop設備,可以掛載之后查看文件內容)
-
對稱加密
- 特點:對源文件的加密和對加密文件的解密采用同一份密鑰
- 優勢:計算量小、算法公開、速度快、效率高
- 劣勢:密鑰的保存與傳輸成了安全性的重要考量、密鑰數量巨大時難以管理
- 常見的對稱加密算法:RC2、RC4、AES等
- RC4
- Ron Rivest在1987年設計,但RSA并未真正發表過RC4
- RC4后來被證明容易被破解,因此慢慢從SSL/TSL等眾多舞臺中退出
- 原理:主要是利用xor實現加密、解密使用同一份密鑰
device mapper
device mapper
是一種linux內核提供的、用于建立物理塊設備和虛擬塊設備之間映射關系的框架-
基于
device mapper
的應用- 邏輯卷管理(LVM)
- dm-crypt/cryptsetup
- TrueCrypt
- Docker
-
創建或管理mappered device的兩種方法(libdevmapper.so)
- 通過設備節點
/dev/mapper/control
- 通過shell的
dmsetup
命令
- 通過設備節點
dm-crypt/cryptsetup
-
dm-crypt
基于Linux內核提供的crypto API
,從2.5.45版本開始引入,是Linux內核提供的磁盤加密功能(內核態)。為了在用戶態能夠使用dm-crypt提供的功能,編譯內核時需要打開以下三個選項:CONFIG_DM_CRYPT
CONFIG_BLK_DEV_DM
CONFIG_CRYPTO_XTS
-
cryptsetup
是提供用戶使用的命令行工具(用戶態),有些發行版可能需要單獨安裝gentoo: emerge cryptsetup
debian/ubuntu: apt-get install cryptsetup
centos/fedora: yum install cryptsetup
- ...
-
cryptsetup
的優缺點- 優勢:
- 與LVM都基于device mapper機制,無縫銜接
- 眾多發行版均已內置,無需額外安裝
- 支持多種加密格式,如LUKS、TCRYPT等
- 缺點:
- 不能對系統中已有的數據加密,必須創建加密的分區
- 一旦忘記密碼或丟失密鑰文件,數據將永遠丟失
- 優勢:
LUKS on cryptsetup
# First, partition
Device Size Id Type
/dev/xvda1 3M 83 Linux
/dev/xvda2 300M 83 Linux
/dev/xvda3 2G 82 Linux swap / Solaris
/dev/xvda4 37.7G 83 Linux
# Second, encrypt using LUKS format
# Usage: cryptsetup [option] luksFormat <device> [key file]
# Example:
cryptsetup -q luksFormat /dev/xvda4 .key
# Third, open LUKS format disk
# Usage: cryptsetup [option] luksOpen <device> <name>
# Example:
cryptsetup -d .key luksOpen /dev/xvda4 root
# Fourth, make file system
# Now, using /dev/mapper/root instead of /dev/xvda4
mkfs.ext3 /dev/mapper/root
# Fifth, mount file system
mount /dev/mapper/root /mnt/gentoo
$df -h
Filesystem Size Mounted on
/dev/mapper/root 37.7G /mnt/gentoo
$blkid
# different block device, different UUID
/dev/xvda4: UUID="..." TYPE="crypto_LUKS" PARTUUID="..."
/dev/mapper/root: UUID="..." TYPE="ext3"
# Umount LUKS partition
umount /dev/xvda4
# Close LUKS partition
# Uasge: crypt luksClose <name>
cryptsetup luksClose root
-
加密原理
- LUKS格式的加密盤不能直接掛載
- 密碼錯誤或密鑰文件不正確時,
luksOpen
會失敗
-
密鑰文件
- 可以使用一個填充任意字符串的文件作為密鑰文件
- 使用
dd
隨機生成的密鑰文件安全性更高
dd if=/dev/urandom of=.key bs=1 count=32
系統加密的例子
用
cryptsetup
對rootfs分區進行加密-
定制Initrd
- 使用linux內核提供的工具
gen_init_cpio
生成 - 將rootfs的秘鑰文件包含在Initrd中
- Initrd中自定義
init
腳本,完成rootfs的解密和掛載操作
- 使用linux內核提供的工具
-
對boot分區中的Initrd文件加密
- 采用分區加密時,boot分區不能加密,因此使系統的Initrd文件暴露給入侵者。一旦Initrd被解包,rootfs的秘鑰就被知曉了
- 使用對稱加密方法對Initrd進行加密,實現簡單,又加大了破解Initrd的難度,使系統文件處于較安全的狀態
$./gen_init_cpio
Usage:
./gen_init_cpio <cpio_list>
<cpio_list> is a file containing newline separated entries that
describe the files to be included in the initramfs archive:
# a comment
file <name> <location> <mode> <uid> <gid> [<hard links>]
dir <name> <mode> <uid> <gid>
nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
slink <name> <target> <mode> <uid> <gid>
pipe <name> <mode> <uid> <gid>
sock <name> <mode> <uid> <gid>
<name> name of the file/dir/nod/etc in the archive
<location> location of the file in the current filesystem
expands shell variables quoted with ${}
<target> link target
<mode> mode/permissions of the file
<uid> user id (0=root)
<gid> group id (0=root)
<dev_type> device type (b=block, c=character)
<maj> major number of nod
<min> minor number of nod
<hard links> space separated list of other links to file
example:
# A simple initramfs
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /root 0700 0 0
dir /sbin 0755 0 0
file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0