Maison >développement back-end >tutoriel php >PHP Master | Surveillance de l'intégrité du fichier

PHP Master | Surveillance de l'intégrité du fichier

Christopher Nolan
Christopher Nolanoriginal
2025-03-03 08:26:131001parcourir

PHP Master | Monitoring File Integrity

Points clés

  • La surveillance de l'intégrité des fichiers est essentielle pour la gestion des sites Web et aide à détecter lorsque les fichiers sont ajoutés, modifiés, supprimés ou corrompus par malveillance. Le hachage du contenu d'un fichier est un moyen fiable de surveiller ces modifications.
  • La fonction
  • PHP hash_file() peut être utilisée pour créer un fichier de configuration de structure de fichiers pour la surveillance. La valeur de hachage de chaque fichier peut être stockée pour des comparaisons ultérieures pour détecter toute modification.
  • Vous pouvez définir une table de base de données pour stocker la valeur de hachage d'un fichier, où file_path stocke le chemin d'accès du fichier sur le serveur, et file_hash stocke la valeur de hachage d'un fichier.
  • La classe
  • PHP RecursiveDirectoryIterator peut être utilisée pour traverser l'arborescence de fichiers et collecter des hachages pour comparaison. La base de données integrity_hashes peut ensuite être mise à jour avec ces hachages. La fonction array_diff_assoc() de PHP peut être utilisée pour vérifier les différences, ce qui aide à identifier les fichiers qui ont été ajoutés, supprimés ou modifiés.

Collaborer sur diverses situations dans la gestion des sites Web

Considérez comment résoudre les situations suivantes lors de la gestion d'un site Web:

  • Ajouter accidentellement, modifier ou supprimer des fichiers
  • Ajouter, modifier ou supprimer des fichiers malicieusement
  • Les fichiers sont corrompus

Plus important encore, savez-vous si l'un d'eux se produit? Si votre réponse est non, veuillez continuer à lire. Dans ce guide, je vais montrer comment créer un fichier de configuration de structure de fichiers qui peut être utilisé pour surveiller l'intégrité des fichiers.

La meilleure façon de déterminer si un fichier a été modifié est de hacher son contenu. PHP fournit plusieurs fonctions de hachage, mais pour ce projet, j'ai décidé d'utiliser la fonction hash_file(). Il fournit une variété d'algorithmes de hachage différents, ce qui rendra mon code facile à modifier si je décide de le modifier plus tard. Le hachage est utilisé dans une variété d'applications, de la protection des mots de passe au séquençage de l'ADN. L'algorithme de hachage fonctionne en convertissant les données en une chaîne cryptée répétable de taille fixe. Ils sont conçus de telle sorte que même de légères modifications des données devraient produire des résultats très différents. Lorsque deux données différentes ou plus produisent le même résultat de chaîne, elle est appelée "conflit". La force de chaque algorithme de hachage peut être mesurée par sa vitesse et sa probabilité de collision. Dans mon exemple, j'utiliserai l'algorithme SHA-1 car il est rapide, a une faible probabilité de conflit et a été largement utilisé et entièrement testé. Bien sûr, vous êtes invités à rechercher d'autres algorithmes et à utiliser tout algorithme que vous aimez. Après avoir obtenu la valeur de hachage du fichier, il peut être stocké pour une comparaison ultérieure. Si le hachage du fichier ne renvoie pas plus tard la même chaîne de hachage qu'auparavant, nous savons que le fichier a été modifié.

Base de données

Tout d'abord, nous devons disposer une table de base pour stocker la valeur de hachage du fichier. J'utiliserai le modèle suivant:

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

file_path Le chemin d'accès au fichier sur le serveur de stockage, car la valeur est toujours unique (car deux fichiers ne peuvent pas occuper le même emplacement dans le système de fichiers), c'est notre clé principale. J'ai spécifié sa longueur maximale à 200 caractères, ce qui devrait permettre des chemins de fichier plus longs. file_hash stocke la valeur de hachage du fichier, qui sera une chaîne hexadécimale SHA-1 à 40 caractères.

Collectez des fichiers

L'étape suivante consiste à créer le fichier de configuration de la structure du fichier. Nous définissons le chemin d'accès pour commencer à collectionner des fichiers et itérer sur chaque répertoire récursivement jusqu'à ce que nous écrasons toute la branche du système de fichiers et pouvons éventuellement exclure certains répertoires ou extensions de fichiers. Nous collectons les valeurs de hachage requises lors de la traversée de l'arborescence de fichiers, puis la stockons dans la base de données ou à titre de comparaison. PHP fournit plusieurs façons de traverser l'arborescence de fichiers; 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();
}
Notez que j'ai référencé le même dossier deux fois dans le tableau

. Ce n'est pas parce que j'ai choisi d'ignorer un répertoire spécifique que l'itérateur ignore également tous les sous-directeurs, selon vos besoins, qui peuvent être utiles ou ennuyeux. La classe $skip nous donne accès à plusieurs méthodes: logs RecursiveDirectoryIterator

    Vérifiez si nous utilisons des fichiers valides
  • valid()
  • Déterminez si le répertoire est "."
  • isDot() Retournez au nom du dossier où le pointeur de fichier est actuellement situé
  • getSubPath() Renvoie le chemin complet et le nom du fichier
  • key() redémarrer la boucle
  • next() Il existe de nombreuses autres méthodes disponibles, mais la plupart du temps, les éléments ci-dessus sont toutes les méthodes dont nous avons besoin, bien que la méthode
  • ait été ajoutée dans PHP 5.3.4, qui renvoie l'extension de fichier. Si votre version PHP le prend en charge, vous pouvez l'utiliser pour filtrer les entrées indésirables au lieu de ce que j'ai fait avec
. Après l'exécution, le code doit remplir le tableau

avec des résultats similaires à: getExtension() pathinfo() $files Après la création du fichier de configuration, il est très facile de mettre à jour la base de données.

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

Vérifiez la différence
<?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();
}

Vous savez maintenant comment créer un nouveau fichier de configuration pour la structure du répertoire et comment mettre à jour les enregistrements dans la base de données. L'étape suivante consiste à le combiner dans une sorte d'application réelle, comme un travail cron avec des notifications par e-mail, une interface d'administration ou tout ce que vous aimez. Si vous souhaitez simplement collecter une liste de fichiers modifiés sans se soucier de leur changement, le moyen le plus simple consiste à extraire les données de la base de données dans un tableau similaire à et à utiliser la fonction PHP

pour supprimer le contenu indésirable.

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

Dans cet exemple, $diffs sera rempli avec toutes les différences trouvées, ou si la structure de fichier est terminée, ce sera un tableau vide. Contrairement à array_diff(), array_diff_assoc() utilisera la clé en comparaison, ce qui est important lorsque nous confrontésons, comme deux fichiers vides, la même valeur de hachage. Si vous souhaitez aller plus loin, vous pouvez ajouter une logique simple pour déterminer avec précision comment le fichier est affecté, qu'il soit supprimé, modifié ou ajouté.

<?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();
}

Lorsque nous traversons les résultats dans la base de données, nous effectuons plusieurs vérifications. Tout d'abord, utilisez array_key_exists() pour vérifier si le chemin du fichier dans notre base de données apparaît dans $files, et sinon, le fichier doit avoir été supprimé. Deuxièmement, si le fichier existe mais que le hachage ne correspond pas, le fichier doit avoir été modifié ou non modifié. Nous stockons chaque vérification dans un tableau temporaire appelé $tmp et enfin, si le nombre dans $files est supérieur au nombre de la base de données, nous savons que les fichiers non contrôlés restants ont été ajoutés. Une fois terminé, $diffs est soit un tableau vide, soit contient des différences trouvées sous la forme d'un tableau multidimensionnel, qui pourrait ressembler à ceci:

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

Pour afficher les résultats dans un format plus convivial (tel que l'interface de gestion), vous pouvez par exemple itérer sur les résultats et les publier sous forme de listes à puces.

<?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();
}

À ce stade, vous pouvez fournir un lien pour déclencher le fonctionnement de la mise à jour de la base de données avec la nouvelle structure de fichiers (auquel cas vous pouvez choisir de stocker $files dans une variable de session), ou si vous n'approuvez pas les différences, vous pouvez les gérer selon les besoins.

Résumé

J'espère que ce guide vous aidera à mieux comprendre la surveillance de l'intégrité des fichiers. L'installation d'un tel contenu sur votre site Web est une mesure de sécurité précieuse et vous pouvez être assuré que vos fichiers resteront les mêmes que vous l'intention. Bien sûr, n'oubliez pas de sauvegarder régulièrement. au cas où.

(La partie FAQ du texte d'origine doit être conservée ici, car le contenu de cette partie n'a rien à voir avec la partie du code, appartient à la description supplémentaire et ne tombe pas dans la catégorie de la pseudo-originalité)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:phpmaster | Variables PHPArticle suivant:phpmaster | Variables PHP