dm-integrity

dm-integrity 目標模擬了一個塊裝置,該裝置具有額外的按扇區標籤,可用於儲存完整性資訊。

將完整性標籤與每個扇區一起儲存的一個普遍問題是,寫入扇區和完整性標籤必須是原子的——即在崩潰的情況下,要麼扇區和完整性標籤都寫入,要麼都不寫入。

為了保證寫入原子性,dm-integrity 目標使用日誌,它將扇區資料和完整性標籤寫入日誌,提交日誌,然後將資料和完整性標籤複製到各自的位置。

dm-integrity 目標可以與 dm-crypt 目標一起使用——在這種情況下,dm-crypt 目標生成完整性資料,並透過附加到 bio 的 bio_integrity_payload 將它們傳遞給 dm-integrity 目標。在此模式下,dm-crypt 和 dm-integrity 目標提供經過身份驗證的磁碟加密——如果攻擊者修改加密裝置,則會返回 I/O 錯誤而不是隨機資料。

dm-integrity 目標也可以作為獨立目標使用,在此模式下,它在內部計算並驗證完整性標籤。在此模式下,dm-integrity 目標可用於檢測磁碟上或 I/O 路徑中的靜默資料損壞。

dm-integrity 還有一種替代操作模式,它使用點陣圖而不是日誌。如果點陣圖中的一個位為 1,則對應區域的資料和完整性標籤未同步——如果機器崩潰,未同步區域將被重新計算。點陣圖模式比日誌模式快,因為我們不必寫入兩次資料,但它也更不可靠,因為如果機器崩潰時發生資料損壞,可能無法檢測到。

首次載入目標時,核心驅動程式將格式化裝置。但它只會在超級塊包含零時格式化裝置。如果超級塊既無效又非零,則無法載入 dm-integrity 目標。

對包含校驗和(又稱標籤)的磁碟元資料區域的訪問透過 dm-bufio 進行緩衝。當訪問任何給定元資料區域時,每個唯一的元資料區域都會獲得其自己的緩衝區。緩衝區大小限制為元資料區域的大小,但可能更小,從而需要多個緩衝區來表示完整的元資料區域。較小的緩衝區大小將為小讀取/寫入生成對元資料區域的較小讀取/寫入操作。即使在對單個緩衝區覆蓋的資料進行完全寫入時,元資料仍然會被讀取。

首次使用目標

  1. 用零覆蓋超級塊

  2. 以一個扇區大小載入 dm-integrity 目標,核心驅動程式將格式化裝置

  3. 解除安裝 dm-integrity 目標

  4. 從超級塊讀取“provided_data_sectors”值

  5. 以目標大小“provided_data_sectors”載入 dm-integrity 目標

  6. 如果您想將 dm-integrity 與 dm-crypt 一起使用,請以大小“provided_data_sectors”載入 dm-crypt 目標

目標引數

  1. 底層塊裝置

  2. 裝置開頭的保留扇區數——dm-integrity 不會讀取或寫入這些扇區

  3. 完整性標籤的大小(如果使用“-”,則大小取自內部雜湊演算法)

  4. 模式

    D - 直接寫入(無日誌)

    在此模式下,不使用日誌,資料扇區和完整性標籤單獨寫入。在崩潰的情況下,資料和完整性標籤可能不匹配。

    J - 日誌寫入

    資料和完整性標籤寫入日誌,並保證原子性。在崩潰的情況下,要麼資料和標籤都寫入,要麼都不寫入。日誌模式會將寫入吞吐量降低一倍,因為資料必須寫入兩次。

    B - 點陣圖模式 - 資料和元資料寫入時沒有任何

    同步,驅動程式維護一個髒區域的點陣圖,其中資料和元資料不匹配。此模式只能與內部雜湊一起使用。

    R - 恢復模式 - 在此模式下,日誌不重放,

    校驗和不檢查,並且不允許寫入裝置。如果裝置無法以任何其他標準模式啟用,此模式對於資料恢復很有用。

    I - 內聯模式 - 在此模式下,dm-integrity 將儲存完整性

    資料直接儲存在底層裝置扇區中。底層裝置必須具有允許儲存使用者完整性資料併為所選完整性標籤提供足夠空間的完整性配置檔案。

  5. 附加引數的數量

附加引數

journal_sectors:數量

日誌的大小,此引數僅在格式化裝置時使用。如果裝置已格式化,則使用超級塊中的值。

interleave_sectors:數量 (預設 32768)

交錯扇區數。此值向下舍入到二的冪。如果裝置已格式化,則使用超級塊中的值。

meta_device:裝置

不要在裝置上交錯資料和元資料。為元資料使用單獨的裝置。

buffer_sectors:數量 (預設 128)

一個元資料緩衝區中的扇區數。該值向下舍入到二的冪。

journal_watermark:數量 (預設 50)

日誌水印百分比。當日志大小超過此水印時,將啟動重新整理日誌的執行緒。

commit_time:數量 (預設 10000)

提交時間(毫秒)。當此時間過去時,日誌將被寫入。如果收到 FLUSH 請求,日誌也會立即寫入。

internal_hash:演算法(:金鑰) (金鑰可選)

使用內部雜湊或 CRC。當使用此引數時,dm-integrity 目標將不接受來自上層目標的完整性標籤,但它將自動生成和驗證完整性標籤。

您可以使用 CRC 演算法(例如 crc32),然後完整性目標將保護資料免受意外損壞。您還可以使用 HMAC 演算法(例如“hmac(sha256):0123456789abcdef”),在此模式下,它將提供資料的加密認證而無需加密。

當不使用此引數時,完整性標籤將從上層目標(例如 dm-crypt)接收。上層目標應檢查完整性標籤的有效性。

recalculate

自動重新計算完整性標籤。僅在使用內部雜湊時有效。

journal_crypt:演算法(:金鑰) (金鑰可選)

使用給定演算法加密日誌,以確保攻擊者無法讀取日誌。您可以在此處使用分組密碼(例如“cbc(aes)”)或流密碼(例如“chacha20”或“ctr(aes)”)。

日誌包含塊裝置上次寫入的歷史記錄,攻擊者讀取日誌可以看到上次寫入的扇區號。從扇區號,攻擊者可以推斷出寫入檔案的大小。為了防止這種情況,您可以加密日誌。

journal_mac:演算法(:金鑰) (金鑰可選)

保護日誌中的扇區號免受意外或惡意修改。為了防止意外修改,請使用 CRC 演算法;為了防止惡意修改,請使用帶有金鑰的 HMAC 演算法。

在使用內部雜湊時不需要此選項,因為在此模式下,在重放日誌時會檢查日誌條目的完整性。因此,在此階段將檢測到修改的扇區號。

block_size:數量 (預設 512)

資料塊的大小(位元組)。塊大小越大,每塊完整性元資料的開銷越小。支援的值為 512、1024、2048 和 4096 位元組。

sectors_per_bit:數量

在點陣圖模式下,此引數指定與一個位圖位對應的 512 位元組扇區數。

bitmap_flush_interval:數量

點陣圖重新整理間隔(毫秒)。當此間隔到期時,元資料緩衝區將同步。

allow_discards

允許對完整性裝置進行塊丟棄請求(即 TRIM)。丟棄僅允許用於使用內部雜湊的裝置。

fix_padding

使用更小的標籤區域填充,更節省空間。如果不存在此選項,則使用大填充——這是為了與舊核心相容。

fix_hmac

提高 internal_hash 和 journal_mac 的安全性

  • 區段號混入 mac 中,以便攻擊者無法將扇區從一個日誌區段複製到另一個日誌區段

  • 超級塊受 journal_mac 保護

  • 超級塊中儲存的 16 位元組鹽值混入 mac 中,以便攻擊者無法檢測到兩個磁碟具有相同的 HMAC 金鑰,並且也禁止攻擊者將扇區從一個磁碟移動到另一個磁碟

legacy_recalculate

允許重新計算帶有 HMAC 金鑰的卷。出於安全原因,預設停用此功能——攻擊者可以修改卷,將 recalc_sector 設定為零,而核心將不會檢測到修改。

日誌模式 (D/J)、buffer_sectors、journal_watermark、commit_time 和 allow_discards 可以在重新載入目標時更改(載入非活動表並使用 suspend 和 resume 交換表)。重新載入目標時,其他引數不應更改,因為磁碟資料的佈局取決於它們,重新載入的目標將無法工作。

例如,在預設 interleave_sectors 為 32768、block_size 為 512,以及內部雜湊為 crc32c 且標籤大小為 4 位元組的裝置上,跟蹤完整資料區域需要 128 KiB 的標籤,每個資料區域需要 256 個元資料扇區。預設 buffer_sectors 為 128,這意味著每個元資料區域將有 2 個緩衝區,或者每 16 MiB 資料有 2 個緩衝區。

狀態行

  1. 完整性不匹配的數量

  2. 提供的扇區資料——即使用者可以使用的扇區數量

  3. 當前重新計算位置(如果未重新計算,則為‘-’)

格式化塊裝置的佈局

  • 保留扇區

    (它們不被此目標使用,可用於儲存 LUKS 元資料或用於其他目的),保留區域的大小在目標引數中指定

  • 超級塊 (4kiB)
    • 魔術字串 - 標識裝置已格式化

    • 版本

    • log2(交錯扇區)

    • 完整性標籤大小

    • 日誌區段數

    • 提供的扇區資料——此目標提供的扇區數(即裝置大小減去所有元資料和填充的大小)。此目標的使用者不應傳送超出“提供的扇區資料”限制的 BIOS 訪問資料。

    • 標誌
      SB_FLAG_HAVE_JOURNAL_MAC
      • 如果使用 journal_mac,則設定此標誌

      SB_FLAG_RECALCULATING
      • 正在重新計算

      SB_FLAG_DIRTY_BITMAP
      • 日誌區域包含髒塊的點陣圖

    • log2(每塊扇區數)

    • 重新計算完成的位置

  • 日誌

    日誌分為多個區段,每個區段包含

    • 元資料區域 (4kiB),其中包含日誌條目

      • 每個日誌條目包含

        • 邏輯扇區(指定資料和標籤應寫入的位置)

        • 資料的最後 8 位元組

        • 完整性標籤(大小在超級塊中指定)

      • 每個元資料扇區以

        • mac (8 位元組) 結尾,8 個元資料扇區中的所有 mac 組成一個 64 位元組的值。它用於儲存日誌區段中扇區號的 HMAC,以防止攻擊者篡改日誌中的扇區號。

        • 提交 ID

    • 資料區域(大小可變;取決於有多少日誌條目適合元資料區域)

      • 資料區域中的每個扇區都包含

        • 資料(504 位元組的資料,最後 8 位元組儲存在日誌條目中)

        • 提交 ID

    為了測試整個日誌區段是否正確寫入,日誌的每個 512 位元組扇區都以 8 位元組的提交 ID 結尾。如果日誌區段中所有扇區的提交 ID 都匹配,則假定該區段已正確寫入。如果提交 ID 不匹配,則該區段僅部分寫入,不應重放。

  • 一個或多個交錯標籤和資料的執行。

    每個執行包含

    • 標籤區域 - 包含完整性標籤。資料區域中的每個扇區都有一個標籤。此區域的大小始終為 4KiB 或更大。

    • 資料區域 - 包含資料扇區。一個執行中的資料扇區數必須是二的冪。此值的 log2 儲存在超級塊中。