Quantcast
Channel: SQLParty »文件系统
Viewing all articles
Browse latest Browse all 3

eCryptfs企业级加密文件系统

$
0
0

Ecryptfs是一个功能强大的企业级加密文件系统,通过堆叠在其它文件系统之上(如 Ext2, Ext3, ReiserFS, JFS 等),为应用程序提供透明、动态、高效和安全的加密功能。
其有如下特点:

  • 支持文件粒度:加密到每一个文件。你可以单独取出一个文件进行解密。而不是像其它软件那样,制作一个大大的文件包。
  • 系统内核支持,用户透明:解密文件夹挂载点(在哪查看解密文件夹),对用户和系统是透明的(与平常文件夹没有区别)。可以对复杂软件进行加密支持,比如sql数据库文件夹、web文件夹、聊天记录(对软件没有影响,也不需设置)。
  • 多种加密方式:与普通软件不同,它提供了不同强度、方式的加密。
  • 防止文件窃取:加密文件经过对称密钥算法加密后一密文的形式存放在物理介质上,即使文件丢失或被窃取,在加密密钥未泄漏的情况下,非授权用户几乎无法通过密文逆向获得文件的明文。 可以应对存储介质失窃的威胁。

本质上,eCryptfs 就像是一个内核版本的 Pretty Good Privacy(PGP)服务,插在 VFS(虚拟文件系统层)和 下层物理文件系统之间,充当一个“过滤器”的角色。用户应用程序对加密文件的写请求,经系统调用层到达 VFS 层,VFS 转给 eCryptfs 文件系统组件(后面会介绍)处理,处理完毕后,再转给下层物理文件系统;读请求(包括打开文件)流程则相反。

eCryptfs加密文件系统的架构

eCryptfs

eCryptfs2

eCryptfs 不足

根据 http://www.ibm.com/developerworks/cn/linux/l-cn-ecryptfs/ 中的描述,有如下不足:

  1. 写操作性能比较差。读操作的开销不算太大,最多降低 29%,有些小文件测试项目反而性能更好;对于写操作,所有测试项目的结果都很差,普遍下降 16 倍左右。这是因为 Page Cache 里面只存放明文,因此首次数据的读取需要解密操作,后续的读操作没有开销;而每一次写 x 字节的数据,就会涉及 ((x – 1) / extent_size + 1) * extent_size 字节的加密操作,因此开销比较大。
  2. 有两种情况可能造成信息泄漏:

a. 当系统内存不足时,Page Cache 中的加密文件的明文页可能会被交换到 swap 区,目前的解决方法是用 dm-crypt 加密 swap 区。
b. 应用程序也有可能在读取加密文件后,将其中某些内容以临时文件的方式写入未挂载 eCryptfs 的目录中(比如直接写到 /tmp 中),解决方案是配置应用程序或修改其实现。

eCryptfs 实现的安全性完全依赖于操作系统自身的安全。如果 Linux Kernel 被攻陷,那么黑客可以轻而易举地获得文件的明文,FEK 等重要信息。

eCryptfs使用方法

eCryptfs需要内核组件和用户层组件。
内核组件需要包含:

 Code maturity level options --->
 [*] Prompt for development and/or
 incomplete code/drivers
Security options --->
 Enable access key retention support
Cryptographic options --->
  MD5 digest algorithm
 AES cipher algorithms
File systems --->
 Miscellaneous filesystems --->
  eCrypt filesystem layer support (EXPERIMENTAL)

首先需要加载eCryptfs内核模块
shell>modprobe ecryptfs
然后将eCryptfs挂载到准备存放加密文件的目录
shell>mount -t ecryptfs <real_path> <ecryptfs_mounted_path> #推荐ecryptfs_mounted_path和真实目录real_path一致,这样非授权用户不能通过原路径访问加密文件。
有时会在mount时报错:
mount: wrong fs type, bad option, bad superblock on /db/test,
missing codepage or helper program, or other error
In some cases useful info is found in syslog – try
dmesg | tail or so
其原因是没有安装对应的ecryptfs-utils,确认是否有安装:
shell>rpm -qa | grep -i ecryptfs
如果确认没有安装,则表示缺失用户层组件,需要安装,这里分别下载了
http://mirror.centos.org/centos/6/os/x86_64/Packages/ecryptfs-utils-82-6.el6_1.3.x86_64.rpm
http://mirror.centos.org/centos/6/os/x86_64/Packages/trousers-0.3.4-4.el6.x86_64.rpm
进行安装后,可以成功mount。
说明:
eCryptfs默认使用AES-128算法以及用口令加密FEK。如果用户想使用公钥加密算法加密FEK,需要事先用OpenSSL产生公钥/私钥对。

eCryptfs使用示例

示例将/db/test的内容加密挂载到/db/test目录下。

shell>cd /db/test/
shell>echo “hello” > before.txt #在加密前创建文件before.txt
shell>mount -t ecryptfs /db/test /db/test #将/db/test加载到/db/test目录中
Select key type to use for newly created files:
1) passphrase
2) tspi
3) openssl
Selection: 1 #这里选择密码验证的方式
Passphrase: #输入密码,这里不会显示出来,一定要记牢!
Select cipher:
1) aes: blocksize = 16; min keysize = 16; max keysize = 32 (not loaded)
2) blowfish: blocksize = 16; min keysize = 16; max keysize = 56 (not loaded)
3) des3_ede: blocksize = 8; min keysize = 24; max keysize = 24 (not loaded)
4) cast6: blocksize = 16; min keysize = 16; max keysize = 32 (not loaded)
5) cast5: blocksize = 8; min keysize = 5; max keysize = 16 (not loaded)
Selection [aes]: #选择加密方式。这里直接回车,选择默认的aes加密方式
Select key bytes:
1) 16
2) 32
3) 24
Selection [16]: #选择加密位数。这里直接回车,选择默认的16位
Enable plaintext passthrough (y/n) [n]: #是否正常显示未经加密文件,默认是 n,以确保你不会误将秘密写入未经加密文件。
Enable filename encryption (y/n) [n]: y #是否把文件名也进行加密,默认是 n。如果选择y,那么在没有解密的情况下,文件名呈现乱码。
Filename Encryption Key (FNEK) Signature [a216278e6e397a04]:
Attempting to mount with the following options:
ecryptfs_unlink_sigs
ecryptfs_fnek_sig=a216278e6e397a04
ecryptfs_passthrough
ecryptfs_key_bytes=16
ecryptfs_cipher=aes
ecryptfs_sig=a216278e6e397a04
WARNING: Based on the contents of [/root/.ecryptfs/sig-cache.txt], #如果设置的密码是第一次使用,它会提示你输入可能有误,因为/root/.ecryptfs/sig-cache.txt中没有相关记录。密码标识只存在于你现在的系统中,是怕你忘记密码,它会告诉你这个密码是否用过。因为ecryptfs在密码错误的情况下一样可以进行错误解密,实际上是另外一种形式的加密。这里可以忽略之。
it looks like you have never mounted with this key
before. This could mean that you have typed your
passphrase wrong.

Would you like to proceed with the mount (yes/no)? : yes #是否继续mount?当然是!否则就退出mount操作。
Would you like to append sig [a216278e6e397a04] to
[/root/.ecryptfs/sig-cache.txt]
in order to avoid this warning in the future (yes/no)? : no #是否把密码标识保存起来?选择no会有更好的安全性,但是你自己得把密码和密码标识保存好。这一步与上面的WARNING相关。
Not adding sig to user sig cache file; continuing with mount.
Mounted eCryptfs
shell>mount

/db/test on /db/test type ecryptfs (rw,ecryptfs_sig=a216278e6e397a04,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_fnek_sig=a216278e6e397a04,ecryptfs_unlink_sigs)
1.测试能够访问加密前文件
shell>cat before.txt
hello
2.测试新建文件,添加内容
shell>echo “hello after” > after1.txt
shell>cat after1.txt
hello after
shell>ls -lrt
total 8
-rw-r–r–. 1 root root 6 Apr 24 09:55 before.txt
-rw-r–r–. 1 root root 12 Apr 24 10:00 after1.txt
3.拷贝新旧文件至未加密文件夹
shell>cp before.txt after1.txt /tmp
shell>cat /tmp/before.txt /tmp/after1.txt
hello
hello after
shell>ls -lrt /tmp/before.txt /tmp/after1.txt
-rw-r–r–. 1 root root 6 Apr 24 10:02 /tmp/before.txt
-rw-r–r–. 1 root root 12 Apr 24 10:02 /tmp/after1.txt
4.新建终端连接,相同用户,执行类似操作
shell2>cd /db/test
shell2>ls -lrt
ls -lrt
total 8
-rw-r–r–. 1 root root 6 Apr 24 09:55 before.txt
-rw-r–r–. 1 root root 12 Apr 24 10:00 after1.txt
shell2>cat before.txt
cat: before.txt: Input/output error
shell2>cat after1.txt
cat: after1.txt: Input/output error
shell2>cat /tmp/before.txt
hello
shell2>cat /tmp/after1.txt
hello after
【重要】
以上测试完全看不出mount eCryptfs时如“不应正常显示未经加密文件”,“文件名进行加密”等的设置,而且不同用户连接有不同的表现,这是为什么???
这个问题一度困扰我这个初次接触eCryptfs的人,偶然想到,eCryptfs实质是在原有文件系统之上堆叠了一层。第一个用户在mount之前就切换到了/db/test目录下,那么在mount之后,/db/test其实包括两层文件系统。第一个用户依然在两层文件系统的下面一层文件系统(即原文件系统)活动!这样第一个用户的操作其实未经过eCryptfs这一层的任何处理,包括创建的after1.txt其实是未加密的!!
而第二个用户再次进入/db/test目录时,已经处于上层文件系统控制,即eCryptfs之上,任何操作都受eCryptfs管理。所以其查看before.txt和after1.txt这两个实际未加密的文件,由于eCryptfs的设置,无法查看,所以报错Input/output error。
5.理清思路后,接着使用第一个用户进行试验
shell>cd /db/test #重新进入/db/test,这次实际是进入eCryptfs文件系统
shell>echo “hello after2″ > after2.txt
shell>ls -lrt
total 20
-rw-r–r–. 1 root root 6 Apr 24 09:55 before.txt
-rw-r–r–. 1 root root 12 Apr 24 10:00 after1.txt
-rw-r–r–. 1 root root 13 Apr 24 10:21 after2.txt
shell>cat *
cat: after1.txt: Input/output error
hello after2
cat: before.txt: Input/output error
shell>cp after2.txt /tmp/after2.txt
shell>cat /tmp/after2.txt
hello after2
6.卸载加密目录
shell>umount /db/test
umount: /db/test: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
umount: /db/test: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
shell>cd .. #卸载时,由于自身在该目录下,即挂载的目录处于busy状态,先退出该目录
shell>umount /db/test
7.检查文件
shell>cd test
shell>ls -lrt
total 20
-rw-r–r–. 1 root root 6 Apr 24 09:55 before.txt
-rw-r–r–. 1 root root 12 Apr 24 10:00 after1.txt
-rw-r–r–. 1 root root 12288 Apr 24 10:21 ECRYPTFS_FNEK_ENCRYPTED.FWaW3WSCPXZu.-SDIr9k1mgbIGpz2af9QFYeFaEfTpC3JN6NiPzuA7R6gU–
可以看到,卸载后,加密文件名称呈现乱码,而且大小为12288,加密后大小与实际大小不同。
shell>cat EC* #尝试查看加密文件
<显示乱码>
shell>cat /tmp/after2.txt
hello after2
shell>cat before.txt after1.txt
hello
hello after

小结

以上测试可以看出eCryptfs的实现效果。

  1. mount后,对应用透明,从加密文件系统中拷出的内容,自动解密。
  2. mount时如果指定不允许Enable plaintext passthrough,那么对未加密文件无法操作。
  3. mount时如果指定Enable filename encryption,那么对文件名会做加密处理,umount后可以看到效果。
  4. umount后,所有加密文件内容无法被看到。

eCryptfs开机自动挂载

这里演示密钥文件保存到U盘,开机依次挂载U盘和eCryptfs文件系统。
U盘对应设备为/dev/sdb1。
shell>mkdir /mnt/usb
shell>mount -t vfat /dev/sdb1 /mnt/usb
获取/root/.ecryptfs/sig-cache.txt文件中的密码标识,或者之前记录的密码标识,这里为a216278e6e397a04。
shell>vi /root/.ecryptfsrc
key=passphrase:passphrase_passwd_file=/mnt/usb/passwd_file.txt
ecryptfs_sig=a216278e6e397a04
ecryptfs_fnek_sig=a216278e6e397a04
ecryptfs_cipher=aes
ecryptfs_key_bytes=16
ecryptfs_passthrough=n
ecryptfs_enable_filename_crypto=y
当进行mount时,eCryptfs首先尝试读取当前用户HOME目录下的.ecryptfsrc文件中的选项,然后读入命令行给定的参数。eCryptfs对于没有给出具体值的必填项会提示用户输入。
一旦成功完成mount,写入<ecryptfs_mounted_path>的文件会被自动加密,保存到<real_path>中去。
shell>vi /mnt/usb/passwd_file.txt
passphrase_passwd=some_passphrase #记录挂载需要的密码。确保使用正确的密码
shell>vi /etc/fstab #添加usb与eCryptfs的挂载

/dev/sdb1 /mnt/usb vfat ro 0 0
/db/test /db/test ecryptfs defaults 0 0
shell>mount -a #尝试挂载
Attempting to mount with the following options:
ecryptfs_unlink_sigs
ecryptfs_fnek_sig=a216278e6e397a04
ecryptfs_key_bytes=16
ecryptfs_cipher=aes
ecryptfs_sig=a216278e6e397a04
Mounted eCryptfs

有时,此步骤会报错:
Error attempting to evaluate mount options: [-2] No such file or directory
Check your system logs for details on why this happened.
Try updating your ecryptfs-utils package, and/or
submit a bug report on https://launchpad.net/ecryptfs
原因可能是passphrase_passwd_file=xxx 中xxx后面紧跟了空格。具体可以查看系统日志。

如果必要的话,重启测试下。如果USB设备不能自动挂载(eCryptfs也就无法挂载),那么可以尝试在/etc/rc.d/rc.local中加入:
/bin/mount -a
exit 0

参考:
http://wiki.ubuntu.org.cn/Ecryptfs%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%8A%A0%E5%AF%86%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F
http://wiki.ubuntu.org.cn/Ecryptfs
http://www.ibm.com/developerworks/cn/linux/l-cn-ecryptfs/
http://www.linuxjournal.com/article/9400

The post eCryptfs企业级加密文件系统 appeared first on SQLParty.


Viewing all articles
Browse latest Browse all 3

Trending Articles