Linux分区加密

基础知识

  • 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  [key file]
# Example:
cryptsetup -q luksFormat /dev/xvda4 .key
# Third, open LUKS format disk
# Usage: cryptsetup [option] luksOpen  
# 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 
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的解密和挂载操作
  • 对boot分区中的Initrd文件加密

    • 采用分区加密时,boot分区不能加密,因此使系统的Initrd文件暴露给入侵者。一旦Initrd被解包,rootfs的秘钥就被知晓了
    • 使用对称加密方法对Initrd进行加密,实现简单,又加大了破解Initrd的难度,使系统文件处于较安全的状态
$./gen_init_cpio
Usage:
        ./gen_init_cpio 

 is a file containing newline separated entries that
describe the files to be included in the initramfs archive:

# a comment
file      []
dir    
nod       
slink     
pipe    
sock    

       name of the file/dir/nod/etc in the archive
   location of the file in the current filesystem
             expands shell variables quoted with ${}
     link target
       mode/permissions of the file
        user id (0=root)
        group id (0=root)
   device type (b=block, c=character)
        major number of nod
        minor number of nod
 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

参考链接

  • Initrd wiki
  • Device mapper wiki
  • Cryptsetup linux man page
  • Symmetric key algorithm wiki
  • Switch_root linux man page

你可能感兴趣的:(Linux分区加密)