黃 沾,楊景賀
(中國電子科技網絡信息安全有限公司,四川 成都 610041)
隨著計算機和網絡的飛速發展,海量的數據存儲在各種設備中。其中,塊設備是最主要的存儲設備,攜帶著大量涉密文檔。倘若系統存在漏洞被未授權使用或者塊設備被盜、丟失,都會引起政府、企業或個人的重大經濟和精神損失。如何有效地保護涉密文檔的安全性,尤其在計算機丟失或失竊后,防止機密信息非法泄露,對目前普遍存在的存儲安全提出了新的挑戰。在通用消費者領域,Android智能手機操作系統在其3.0版本中提供了存儲加密功能[1],而微軟的Windows也推出了BitLocker功能[2],可以對整個磁盤進行加密。但式,這些解決方案需要大量的用戶響應(如輸入密碼),無疑不適應于工業環境中運行的設備,因為這些設備要求7×24 h運行,無人工干預。因此,本文設計并實現了一個適用于工業環境的非交互式全盤加密系統,下面將從設計目標、方案和實現3個方面分別進行描述。
本系統的設計目標是一個盡量利用現有硬件設施,在不增加硬件成本的基礎上,使用軟件方來提高設備存儲私密性,同時對現有應用做到無縫銜接。
(1)兼容性:設計方案必須保持對現有設備的兼容性,如ARM平臺、X86平臺和龍芯平臺等。
(2)密鑰隨機:每臺設備的密鑰都可以隨機設置,避免一臺主機被破解后所有主機都告破,形成事實上的“后門”。
(3)硬件綁定:每個存儲的訪問都與該存儲所在設備綁定,將存儲通過物理方法取出直接訪問,或者放置到其他任何設備無法直接訪問存儲。
(4)易用性:方案應盡量減少對現有應用的干擾,即現有應用可以不做任何更改。
(5)非交互式:由于設備運行要求7×24 h無人值守運行,必須要求系統必須是非交互式的,與現有的加密系統有根本區別。
將系統分為MBR鏡像、Bootloader(這里為GRUB2)、內核與文件系統和其他分區等,位置如圖1所示。

圖1 存儲分區
MBR鏡像位于是磁盤第一個扇區(512 Bytes),包含了分區表與GRUB2的stage1加載代碼。GRUB2鏡像位于MBR與實際分區間的空隙,由于設備本身沒有加解密設施,所以GRUB2這里未被加密。而內核與文件系統及后面的分區都已被加密處理(圖1中陰影部分)。GRUB2會在啟動過程中自動獲取密鑰并將內核與文件系統解密,然后再啟動解密后的內核。
基于設計目標,需要將密鑰存放于設備的硬件中,以達到與設備綁定的目的,同時存儲的信息必須保留。同時,為了安全性,密鑰至少需要保留16 Bytes以上,以防止暴力破解。基于以上考慮,選擇網卡ROM存放密鑰。
在設備未加密前,需要進行系統初始化工作。在進入系統后:
(1)隨機生成密鑰并將密鑰寫入網卡ROM中;
(2)調用cryptsetup工具,將未加密分區轉換為加密分區。
在GRUB2中,需要應對分區加密與未加密兩種情況。最重要的是獲取密鑰并解密,因為網卡一般采用PCI接口與設備相連,而GRUB2提供了完善的PCI訪問接口,可以較容易地進行PCI設備寄存器訪問。
在設備運行過渡到內核并切換到文件系統后,為了讓其他應用程序能訪問存儲分區,需要再次將存儲解密。這里比較簡單,獲取ROM以及解密都有現成的工具可用。
為了實現上述系統,需要整合多個現有技術。下面從關鍵技術及其用法出發,闡述功能實現的方法。
3.1.1 GRUB2
GRUB2(GRand Unified Bootloader 2) 是 原GRUB的升級版本,支持多個體系平臺和多種部署方式,同時內置了對多個加密方法的支持,包括LUKS、geli等。此外,GRUB2支持密碼鎖定等常見安全措施。
3.1.2 LUKS
LUKS(Linux Unified Key Setup)是 Linux硬盤加密標準,通過提供標準的磁盤格式,不僅可以促進發行版之間的兼容性,還可以提供對多個用戶密碼的安全管理。
對于本方案而言,使用LUKS有以下幾點考慮:
(1)實現相對容易,在GRUB2中已有基本的LUKS模塊,實現了基本的LUKS加密分區讀取,后續只要獲取密鑰傳遞給LUKS模塊即可。
(2)支持多個密碼:LUKS支持增加和刪除用戶密碼,后續在系統更新時可隨時更換密碼,提高了安全性。
(3)LUKS作為廣泛應用的加密標準,安全性得到了良好驗證,同時其對應的工具cryptsetup功能強大、穩定可靠。
密鑰的存放與獲取是本方案的關鍵,這里以網卡ROM作為密鑰存放點為例。實際使用中還可以將ROM中的信息做多重變換,如使用pbkdf2算法增加破解難度。
密鑰的設置是在文件系統啟動后進行,而密鑰的讀取同時存在于GRUB2與文件系統啟動后。
所以,設置一個可執行文件diskkey作為文件系統啟動后密鑰的寫入與讀取,而在GRUB2流程中將作為補丁打入GRUB2的LUKS模塊,替換原有的提示用戶輸入密碼部分。
3.2.1 diskkey實現
diskkey實現密鑰的讀取與寫入,實現必須保密,防止對外泄露。diskkey的實現與設備高度關聯,而且應該不定時變換。
示例:
ethtool -e eth0 raw on offset 0 length 32
ethtool讀取網卡ROM信息中前32位信息作為密鑰輸出。
3.2.2 GRUB2實現
以Intel網卡芯片82540為例,其開發手冊記錄了如何使用EEPROM Read register(EERD)寄存器來訪問網卡ROM。
示例:

regs是寄存器基地址,根據手冊EERD位于0x14h,即第5個雙字的位置。regs[0x5]=eerd將想要訪問的ROM地址賦予EERD寄存器,后續檢測EERD的DONE bit是否置位,置位表示網卡已經將ROM內容寫入EERD寄存器。需要注意,該函數每次能夠讀取兩字節(一個字)長度的ROM,需要按照密鑰存儲約定多次調用。而regs變量的獲得,可以通過調用grub2 pci接口相關API獲取。
設備啟動后會加載GRUB2,而GRUB2必須判斷存儲是否已經加密。如果未加密,則走初始化流程;如果已經加密,則必須調用解密命令,再加載解密后的內核與文件系統。
一個GRUB2配置文件示例:

GRUB2一開始加載biosdisk和part_msdos兩個模塊,以便后續訪問設備上的存儲及其分區,然后加載LUKS模塊。LUKS模塊已經經過修改,不會再提示用戶輸入密碼,能自動加載磁盤密碼。
if linux (hd0,msdos1)/vmlinuz這行嘗試直接加載分區上的內核,如果成功,說明磁盤還沒有加密,繼續加載initramfs,然后啟動。如果加載失敗,系統嘗試使用cryptomount解密分區。解密后的分區用crypto0表示,如果linux指令依然無法訪問內核,則表示解密過程失敗,設備可能存在異常情況,系統進行關機處理。
系統啟動后,需要將原加密分區進行解密,這樣對其他應用不會造成干擾。解密過程主要使用cryptsetup工具[3],示例如下(DEVICE變量為LUKS所在分區設備名):


cryptsetup isLuks判斷分區是否經過LUKS加密。diskkey讀取加密密鑰,cryptsetup luksOpen完成解密過程,最后調用mount掛載加密分區,后續使用與普通分區相同。
系統啟動后,必須確保系統訪問是授權情況。如果解密方式公開,意味著加密失效。所以,在現有Linux安全防護措施基礎上,對整個啟動流程進行了全方面的系統安全加固。
3.5.1 鎖定GRUB2
GRUB2是系統啟動的第一步,可以任意指定內核、文件系統、內核參數等。所以,為了系統的安全啟動,必須鎖定GRUB2。GRUB2提供了鎖定其運行配置文件的方法,使GRUB2只能按照指定的流程運行,包括固定的內核、內核參數等。
示例:

set superusers="root"設置超級用戶為root,后面password_pbkdf2設置root密碼(即XXXX部分),root密碼調用grub-mkpasswd-pbkdf2命令生成。menuentry表示后面的啟動命令無需認證即可執行。
最后達到的效果是menuentry中的啟動流程可以無干擾執行,而要修改啟動項如修改內核參數,需要輸入root用戶密碼進行認證。
3.5.2 禁用init與rdinit內核參數
由于GRUB2是未加密的,雖然在上一步已做鎖定GRUB2,但是仍然要堤防GRUB2配置文件被修改。必須假定GRUB2傳給內核的參數已經被修改,而內核默認提供了init(rdinit)內核參數來自定義內核啟動的init進程執行文件路徑。通過修改init參數,如直接修改為/bin/sh,可以直接繞過登錄認證訪問文件系統,就直接暴露了diskkey的實現,導致加密系統告破。由于使用initramfs啟動,對應的是rdinit參數,只需要禁用rdinit參數即可。解決辦法比較簡單,將內核中rdinit參數處理函數注釋掉即可,對應的代碼位于init/main.c中,不做贅述。
3.5.3 系統固件加密
系統揭秘方法也在系統的升級固件中可以獲取,所以系統固件必須加密。由于各個系統實現不同,這部分不做展開。
本文提出的非交互式全盤加密系統解決了在現有硬件設備存儲安全的問題,同時系統還有很多需要改進的地方,包括對現有安全硬件技術的支持(如UEFI Secure Boot、TPM)等,將是下一步的研究內容。