搜尋
首頁後端開發php教程PHP主|監視文件完整性

PHP Master | Monitoring File Integrity

關鍵要點

  • 監控文件完整性對於網站管理至關重要,它有助於檢測何時意外或惡意添加、修改、刪除或損壞文件。對文件內容進行哈希處理是監控此類更改的可靠方法。
  • PHP 的 hash_file() 函數可用於創建用於監控的文件結構配置文件。可以存儲每個文件的哈希值,以便以後進行比較以檢測任何更改。
  • 可以設置數據庫表來存儲文件的哈希值,其中 file_path 存儲服務器上文件的路徑,file_hash 存儲文件的哈希值。
  • PHP 的 RecursiveDirectoryIterator 類可用於遍歷文件樹並收集用於比較的哈希值。然後可以使用這些哈希值更新 integrity_hashes 數據庫。可以使用 PHP 的 array_diff_assoc() 函數檢查差異,這有助於識別已添加、刪除或更改的文件。

應對網站管理中的各種情況

考慮一下在管理網站時如何解決以下情況:

  • 意外添加、修改或刪除文件
  • 惡意添加、修改或刪除文件
  • 文件損壞

更重要的是,您是否知道是否發生了這些情況之一?如果您的答案是否定的,請繼續閱讀。在本指南中,我將演示如何創建文件結構配置文件,該配置文件可用於監控文件的完整性。

確定文件是否已被更改的最佳方法是對其內容進行哈希處理。 PHP 提供了多種哈希函數,但對於此項目,我決定使用 hash_file() 函數。它提供了各種不同的哈希算法,如果我決定稍後進行更改,這將使我的代碼易於修改。哈希用於各種應用程序,從密碼保護到 DNA 測序。哈希算法通過將數據轉換為固定大小的可重複加密字符串來工作。它們的設計使得即使對數據進行輕微修改也應該產生非常不同的結果。當兩個或多個不同的數據產生相同的字符串結果時,則稱為“衝突”。每種哈希算法的強度可以通過其速度和衝突概率來衡量。在我的示例中,我將使用 SHA-1 算法,因為它速度快,衝突概率低,並且已被廣泛使用和充分測試。當然,歡迎您研究其他算法並使用任何您喜歡的算法。獲得文件的哈希值後,可以將其存儲起來以便以後進行比較。如果以後對文件進行哈希處理沒有返回與之前相同的哈希字符串,那麼我們就知道該文件已被更改。

數據庫

首先,我們需要佈局一個基本表來存儲文件的哈希值。我將使用以下模式:

CREATE TABLE integrity_hashes (
    file_path VARCHAR(200) NOT NULL,
    file_hash CHAR(40) NOT NULL,
    PRIMARY KEY (file_path)
);

file_path 存儲服務器上文件的路徑,由於該值始終是唯一的(因為兩個文件不能佔用文件系統中的同一位置),因此它是我們的主鍵。我將其最大長度指定為 200 個字符,這應該允許一些較長的文件路徑。 file_hash 存儲文件的哈希值,它將是一個 SHA-1 40 字符的十六進製字符串。

收集文件

下一步是構建文件結構的配置文件。我們定義要開始收集文件的路徑,並遞歸地迭代每個目錄,直到我們覆蓋了文件系統的整個分支,並可以選擇性地排除某些目錄或文件擴展名。我們在遍歷文件樹時收集所需的哈希值,然後將其存儲在數據庫中或用於比較。 PHP 提供了幾種遍歷文件樹的方法;為簡單起見,我將使用 RecursiveDirectoryIterator 類。

<?php define("PATH", "/var/www/");
$files = array();

// 要获取的扩展名,空数组将返回所有扩展名
$ext = array("php");

// 要忽略的目录,空数组将检查所有目录
$skip = array("logs", "logs/traffic");

// 构建配置文件
$dir = new RecursiveDirectoryIterator(PATH);
$iter = new RecursiveIteratorIterator($dir);
while ($iter->valid()) {
    // 跳过不需要的目录
    if (!$iter->isDot() && !in_array($iter->getSubPath(), $skip)) {
        // 获取特定文件扩展名
        if (!empty($ext)) {
            // PHP 5.3.4: if (in_array($iter->getExtension(), $ext)) {
            if (in_array(pathinfo($iter->key(), PATHINFO_EXTENSION), $ext)) {
                $files[$iter->key()] = hash_file("sha1", $iter->key());
            }
        } else {
            // 忽略文件扩展名
            $files[$iter->key()] = hash_file("sha1", $iter->key());
        }
    }
    $iter->next();
}

請注意,我在 $skip 數組中兩次引用了相同的文件夾 logs。僅僅因為我選擇忽略特定目錄並不意味著迭代器也會忽略所有子目錄,這取決於您的需求,這可能很有用或很煩人。 RecursiveDirectoryIterator 類使我們可以訪問多種方法:

  • valid() 檢查我們是否正在使用有效文件
  • isDot() 確定目錄是否為“.”或“..”
  • getSubPath() 返回文件指針當前所在的文件夾名稱
  • key() 返回完整路徑和文件名
  • next() 重新啟動循環

還有更多可用的方法,但大多數情況下,上面列出的方法是我們所需的所有方法,儘管在 PHP 5.3.4 中添加了 getExtension() 方法,該方法返回文件擴展名。如果您的 PHP 版本支持它,您可以使用它來過濾不需要的條目,而不是我使用 pathinfo() 所做的操作。執行後,代碼應使用類似於以下內容的結果填充 $files 數組:

<code>Array
(
    [/var/www/test.php] => b6b7c28e513dac784925665b54088045cf9cbcd3
    [/var/www/sub/hello.php] => a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
    [/var/www/sub/world.php] => da39a3ee5e6b4b0d3255bfef95601890afd80709
)</code>

構建配置文件後,更新數據庫非常容易。

<?php $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
    DB_USER, DB_PASSWORD);

// 清除旧记录
$db->query("TRUNCATE integrity_hashes");

// 插入更新的记录
$sql = "INSERT INTO integrity_hashes (file_path, file_hash) VALUES (:path, :hash)";
$sth = $db->prepare($sql);
$sth->bindParam(":path", $path);
$sth->bindParam(":hash", $hash);
foreach ($files as $path => $hash) {
    $sth->execute();
}

檢查差異

您現在知道如何構建目錄結構的新配置文件以及如何更新數據庫中的記錄。下一步是將其組合到某種實際應用程序中,例如帶有電子郵件通知的 cron 作業、管理界面或任何您喜歡的其他內容。如果您只想收集已更改的文件列表,而不在乎它們如何更改,那麼最簡單的方法是將數據從數據庫提取到類似於 $files 的數組中,然後使用 PHP 的 array_diff_assoc() 函數來去除不需要的內容。

CREATE TABLE integrity_hashes (
    file_path VARCHAR(200) NOT NULL,
    file_hash CHAR(40) NOT NULL,
    PRIMARY KEY (file_path)
);

在此示例中,$diffs 將填充任何發現的差異,或者如果文件結構完整,則它將是一個空數組。與 array_diff() 不同,array_diff_assoc() 將在比較中使用鍵,這在我們發生衝突時很重要,例如兩個空文件具有相同的哈希值。如果您想更進一步,您可以添加一些簡單的邏輯來準確確定文件是如何受到影響的,無論是被刪除、更改還是添加。

<?php define("PATH", "/var/www/");
$files = array();

// 要获取的扩展名,空数组将返回所有扩展名
$ext = array("php");

// 要忽略的目录,空数组将检查所有目录
$skip = array("logs", "logs/traffic");

// 构建配置文件
$dir = new RecursiveDirectoryIterator(PATH);
$iter = new RecursiveIteratorIterator($dir);
while ($iter->valid()) {
    // 跳过不需要的目录
    if (!$iter->isDot() && !in_array($iter->getSubPath(), $skip)) {
        // 获取特定文件扩展名
        if (!empty($ext)) {
            // PHP 5.3.4: if (in_array($iter->getExtension(), $ext)) {
            if (in_array(pathinfo($iter->key(), PATHINFO_EXTENSION), $ext)) {
                $files[$iter->key()] = hash_file("sha1", $iter->key());
            }
        } else {
            // 忽略文件扩展名
            $files[$iter->key()] = hash_file("sha1", $iter->key());
        }
    }
    $iter->next();
}

當我們遍歷數據庫中的結果時,我們會進行多次檢查。首先,使用 array_key_exists() 檢查我們的數據庫中的文件路徑是否出現在 $files 中,如果沒有,則該文件必須已被刪除。其次,如果文件存在但哈希值不匹配,則該文件必須已被更改或未更改。我們將每個檢查存儲到名為 $tmp 的臨時數組中,最後,如果 $files 中的數量大於數據庫中的數量,那麼我們就知道那些剩餘的未檢查文件已被添加。完成後,$diffs 要么是一個空數組,要么包含以多維數組形式找到的任何差異,這可能如下所示:

<code>Array
(
    [/var/www/test.php] => b6b7c28e513dac784925665b54088045cf9cbcd3
    [/var/www/sub/hello.php] => a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
    [/var/www/sub/world.php] => da39a3ee5e6b4b0d3255bfef95601890afd80709
)</code>

為了以更用戶友好的格式顯示結果(例如管理界面),您可以例如遍歷結果並以項目符號列表的形式輸出它們。

<?php $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
    DB_USER, DB_PASSWORD);

// 清除旧记录
$db->query("TRUNCATE integrity_hashes");

// 插入更新的记录
$sql = "INSERT INTO integrity_hashes (file_path, file_hash) VALUES (:path, :hash)";
$sth = $db->prepare($sql);
$sth->bindParam(":path", $path);
$sth->bindParam(":hash", $hash);
foreach ($files as $path => $hash) {
    $sth->execute();
}

此時,您可以提供一個鏈接來觸發使用新的文件結構更新數據庫的操作(在這種情況下,您可能選擇將 $files 存儲在會話變量中),或者如果您不批准差異,您可以根據需要處理它們。

總結

希望本指南能幫助您更好地理解文件完整性監控。在您的網站上安裝此類內容是一種寶貴的安全措施,您可以放心,您的文件將完全按照您的意圖保持不變。當然,不要忘記定期備份。以防萬一。

(此處應保留原文的FAQ部分,因為該部分內容與代碼部分無關,屬於補充說明,不屬於偽原創的範疇)

以上是PHP主|監視文件完整性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
絕對會話超時有什麼區別?絕對會話超時有什麼區別?May 03, 2025 am 12:21 AM

絕對會話超時從會話創建時開始計時,閒置會話超時則從用戶無操作時開始計時。絕對會話超時適用於需要嚴格控制會話生命週期的場景,如金融應用;閒置會話超時適合希望用戶長時間保持會話活躍的應用,如社交媒體。

如果會話在服務器上不起作用,您將採取什麼步驟?如果會話在服務器上不起作用,您將採取什麼步驟?May 03, 2025 am 12:19 AM

服務器會話失效可以通過以下步驟解決:1.檢查服務器配置,確保會話設置正確。 2.驗證客戶端cookies,確認瀏覽器支持並正確發送。 3.檢查會話存儲服務,如Redis,確保其正常運行。 4.審查應用代碼,確保會話邏輯正確。通過這些步驟,可以有效診斷和修復會話問題,提升用戶體驗。

session_start()函數的意義是什麼?session_start()函數的意義是什麼?May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

為會話cookie設置httponly標誌的重要性是什麼?為會話cookie設置httponly標誌的重要性是什麼?May 03, 2025 am 12:10 AM

設置httponly標誌對會話cookie至關重要,因為它能有效防止XSS攻擊,保護用戶會話信息。具體來說,1)httponly標誌阻止JavaScript訪問cookie,2)在PHP和Flask中可以通過setcookie和make_response設置該標誌,3)儘管不能防範所有攻擊,但應作為整體安全策略的一部分。

PHP會議在網絡開發中解決了什麼問題?PHP會議在網絡開發中解決了什麼問題?May 03, 2025 am 12:02 AM

phpsessions solvathepromblymaintainingStateAcrossMultipleHttpRequestsbyStoringDataTaNthEserVerAndAssociatingItwithaIniquesestionId.1)他們儲存了AtoredAtaserver side,通常是Infilesordatabases,InseasessessionIdStoreDistordStoredStoredStoredStoredStoredStoredStoreDoreToreTeReTrestaa.2)

可以在PHP會話中存儲哪些數據?可以在PHP會話中存儲哪些數據?May 02, 2025 am 12:17 AM

phpsessionscanStorestrings,數字,數組和原始物。

您如何開始PHP會話?您如何開始PHP會話?May 02, 2025 am 12:16 AM

tostartaphpsession,usesesses_start()attheScript'Sbeginning.1)placeitbeforeanyOutputtosetThesessionCookie.2)useSessionsforuserDatalikeloginstatusorshoppingcarts.3)regenerateSessiveIdStopreventFentfixationAttacks.s.4)考慮使用AttActAcks.s.s.4)

什麼是會話再生,如何提高安全性?什麼是會話再生,如何提高安全性?May 02, 2025 am 12:15 AM

會話再生是指在用戶進行敏感操作時生成新會話ID並使舊ID失效,以防會話固定攻擊。實現步驟包括:1.檢測敏感操作,2.生成新會話ID,3.銷毀舊會話ID,4.更新用戶端會話信息。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器