Поместить скрипт в корневую директорию сайта в виде файла: #!/bin/bash
# Получаем директорию, где находится сам скрипт
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Файл для записи даты и времени (будет создан в той же директории, что и скрипт)
LOG_FILE="$SCRIPT_DIR/last_run.txt"
# Записываем текущую дату и время в нужном формате
date '+%Y-%m-%d %H:%M:%S' > "$LOG_FILE"Дать права на выполнение - выполнить в консоли команду, указав в команде правильный путь к файлу скрипта от корня сайта:
chmod +x /путь/к/скрипту/last_run.shДобавить в крон задачу на выполнение каждую минуту: * * * * * /путь/к/скрипту/last_run.shПроверить, что скрипт запускается по крону - открыть файл last_run.txt. Вы должны увидеть что-то вроде: 2026-06-14 15:30:00 В IPS 5 можно определить права по умолчанию через файл constants.php: <?php
define( 'IPS_FOLDER_PERMISSION', 0777 );
define( 'FOLDER_PERMISSION_NO_WRITE', 0755 );
define( 'IPS_FILE_PERMISSION', 0666 );
define( 'FILE_PERMISSION_NO_WRITE', 0644 ); Скрипт для проверки прав на папки и файлы: Создайте файл check_permissions.php в корневой директории вашего сайта (там же, где лежит conf_global.php). <?php
/**
* Скрипт проверки прав на файлы и папки IPS5
* Разместите этот файл в корневой директории сайта и запустите через браузер
* После проверки УДАЛИТЕ файл с сервера!
*/
// Отключаем ограничение времени выполнения
set_time_limit(0);
// Включаем вывод всех ошибок для диагностики
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "<!DOCTYPE html>";
echo "<html><head><meta charset='UTF-8'><title>IPS5 - Проверка прав на файлы и папки</title>";
echo "<style>
body { font-family: monospace; background: #f5f5f5; padding: 20px; }
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
h1 { color: #333; border-bottom: 2px solid #eee; padding-bottom: 10px; }
h2 { color: #555; margin-top: 20px; font-size: 18px; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 8px 12px; text-align: left; border-bottom: 1px solid #ddd; }
th { background: #f0f0f0; font-weight: bold; }
.success { color: green; font-weight: bold; }
.warning { color: orange; font-weight: bold; }
.error { color: red; font-weight: bold; }
.info { color: blue; }
.summary { margin: 20px 0; padding: 15px; border-radius: 5px; }
.summary.good { background: #d4edda; border: 1px solid #c3e6cb; color: #155724; }
.summary.bad { background: #f8d7da; border: 1px solid #f5c6cb; color: #721c24; }
.summary.warning { background: #fff3cd; border: 1px solid #ffeeba; color: #856404; }
</style></head><body>";
echo "<div class='container'>";
echo "<h1> Invision Community 5 - Проверка прав на файлы и папки</h1>";
echo "<p><strong>Время проверки:</strong> " . date('Y-m-d H:i:s') . "</p>";
echo "<p><strong>Директория проверки:</strong> " . __DIR__ . "</p>";
// Определяем необходимые права для разных типов
$requiredPermissions = [
// Папки, требующие права на запись
'writable_dirs' => [
'uploads',
'datastore',
'applications',
'plugins',
],
// Файлы, требующие права на запись
'writable_files' => [
'conf_global.php',
],
// Папки, которые должны быть доступны для чтения (755)
'readable_dirs' => [
'applications',
'plugins',
'uploads',
'datastore',
'system',
'themes',
],
];
$results = [
'total' => 0,
'success' => 0,
'warning' => 0,
'error' => 0,
'details' => [],
];
// Функция для получения прав в читаемом виде
function getPermString($perms) {
if (($perms & 0xC000) == 0xC000) { // Socket
$info = 's';
} elseif (($perms & 0xA000) == 0xA000) { // Symbolic Link
$info = 'l';
} elseif (($perms & 0x8000) == 0x8000) { // Regular
$info = '-';
} elseif (($perms & 0x6000) == 0x6000) { // Block special
$info = 'b';
} elseif (($perms & 0x4000) == 0x4000) { // Directory
$info = 'd';
} elseif (($perms & 0x2000) == 0x2000) { // Character special
$info = 'c';
} elseif (($perms & 0x1000) == 0x1000) { // FIFO pipe
$info = 'p';
} else { // Unknown
$info = 'u';
}
// Владелец
$info .= (($perms & 0x0100) ? 'r' : '-');
$info .= (($perms & 0x0080) ? 'w' : '-');
$info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
// Группа
$info .= (($perms & 0x0020) ? 'r' : '-');
$info .= (($perms & 0x0010) ? 'w' : '-');
$info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
// Остальные
$info .= (($perms & 0x0004) ? 'r' : '-');
$info .= (($perms & 0x0002) ? 'w' : '-');
$info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
return $info;
}
// Функция проверки прав на папку
function checkDirectory($path, $required, $results, $isWritable = true) {
if (!file_exists($path)) {
$results['details'][] = [
'path' => $path,
'type' => 'directory',
'status' => 'warning',
'current' => 'не существует',
'required' => $required,
'message' => ' Папка не найдена!'
];
$results['warning']++;
return $results;
}
$perms = fileperms($path);
$permString = getPermString($perms);
$permOctal = substr(sprintf('%o', $perms), -4);
$isWritableActual = is_writable($path);
$isReadableActual = is_readable($path);
if ($isWritable) {
$isOk = $isWritableActual;
$requiredDesc = "должна быть записываемой (writable)";
} else {
$isOk = $isReadableActual;
$requiredDesc = "должна быть читаемой (readable)";
}
$status = $isOk ? 'success' : 'error';
$statusText = $isOk ? ' OK' : ' ОШИБКА';
$statusClass = $isOk ? 'success' : 'error';
$results['details'][] = [
'path' => $path,
'type' => 'directory',
'status' => $status,
'current' => "$permOctal ($permString)",
'required' => $requiredDesc,
'message' => $statusText
];
if ($isOk) {
$results['success']++;
} else {
$results['error']++;
}
$results['total']++;
return $results;
}
// Функция проверки прав на файл
function checkFile($path, $requiredPerm, $results) {
if (!file_exists($path)) {
$results['details'][] = [
'path' => $path,
'type' => 'file',
'status' => 'warning',
'current' => 'не существует',
'required' => $requiredPerm,
'message' => ' Файл не найден (возможно, это нормально)'
];
$results['warning']++;
return $results;
}
$perms = fileperms($path);
$permString = getPermString($perms);
$permOctal = substr(sprintf('%o', $perms), -4);
$isOk = false;
if ($requiredPerm === 'writable') {
$isOk = is_writable($path);
$requiredDesc = "должен быть записываемым (writable, обычно 666)";
} elseif ($requiredPerm === 'readable') {
$isOk = is_readable($path);
$requiredDesc = "должен быть читаемым (readable, обычно 644)";
} elseif ($requiredPerm === 'executable') {
$isOk = is_executable($path);
$requiredDesc = "должен быть исполняемым (executable, обычно 755)";
}
$status = $isOk ? 'success' : 'error';
$statusText = $isOk ? ' OK' : ' ОШИБКА';
$statusClass = $isOk ? 'success' : 'error';
// Для conf_global.php особая проверка
if (basename($path) === 'conf_global.php') {
if ($isOk) {
$statusText = ' OK (файл существует и доступен для записи)';
} else {
$statusText = ' ОШИБКА (файл должен быть доступен для записи, chmod 666)';
}
}
$results['details'][] = [
'path' => $path,
'type' => 'file',
'status' => $status,
'current' => "$permOctal ($permString)",
'required' => $requiredDesc,
'message' => $statusText
];
if ($isOk) {
$results['success']++;
} else {
$results['error']++;
}
$results['total']++;
return $results;
}
// Функция рекурсивной проверки папки
function checkDirectoryRecursive($dir, $results, $depth = 0) {
if ($depth > 3) return $results; // Ограничиваем глубину
if (!is_dir($dir)) return $results;
$files = scandir($dir);
if (!$files) return $results;
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (is_dir($path)) {
// Проверяем папку
$perms = fileperms($path);
$permOctal = substr(sprintf('%o', $perms), -4);
$expectedReadable = '755';
$isReadable = is_readable($path);
$isWritable = is_writable($path);
// Для uploads проверяем особо
if (basename($path) === 'uploads' || strpos($path, '/uploads/') !== false) {
$isOk = ($isWritable && $isReadable);
} else {
$isOk = $isReadable;
}
$results['details'][] = [
'path' => $path,
'type' => 'directory',
'status' => $isOk ? 'success' : ($isReadable ? 'warning' : 'error'),
'current' => $permOctal,
'required' => (basename($path) === 'uploads' ? '777 (writable)' : '755 (readable)'),
'message' => $isOk ? ' OK' : (is_writable($path) ? ' Нет прав на чтение' : ' Нет прав')
];
if ($isOk) {
$results['success']++;
} elseif ($isReadable) {
$results['warning']++;
} else {
$results['error']++;
}
$results['total']++;
// Рекурсивно проверяем вложенные папки
$results = checkDirectoryRecursive($path, $results, $depth + 1);
}
}
return $results;
}
echo "<h2> Проверка основных папок и файлов IPS5</h2>";
echo "<table>";
echo "<tr><th>Путь</th><th>Тип</th><th>Текущие права</th><th>Требуется</th><th>Статус</th></tr>";
$baseDir = __DIR__;
// Проверяем основные папки
$writableDirs = ['uploads', 'datastore', 'applications', 'plugins'];
foreach ($writableDirs as $dir) {
$path = $baseDir . '/' . $dir;
$results = checkDirectory($path, 'записываемая (writable, 777 для uploads, 755 для остальных)', $results, true);
}
// Проверяем conf_global.php
$results = checkFile($baseDir . '/conf_global.php', 'writable', $results);
// Проверяем дополнительные важные папки
$importantDirs = ['system', 'themes'];
foreach ($importantDirs as $dir) {
$path = $baseDir . '/' . $dir;
if (file_exists($path)) {
$results = checkDirectory($path, 'читаемая (readable, 755)', $results, false);
}
}
// Проверяем папку uploads рекурсивно
if (file_exists($baseDir . '/uploads')) {
echo "</table>";
echo "<h2> Глубокая проверка папки uploads (рекурсивно)</h2>";
echo "<table>";
echo "<tr><th>Путь</th><th>Тип</th><th>Права</th><th>Требуется</th><th>Статус</th></tr>";
$results = checkDirectoryRecursive($baseDir . '/uploads', $results);
}
echo "</table>";
// Вывод результатов
echo "<h2> Итог проверки</h2>";
$summaryClass = 'good';
if ($results['error'] > 0) {
$summaryClass = 'bad';
} elseif ($results['warning'] > 0) {
$summaryClass = 'warning';
}
echo "<div class='summary $summaryClass'>";
echo "<strong>Результаты:</strong><br>";
echo " Успешно: {$results['success']}<br>";
echo " Предупреждений: {$results['warning']}<br>";
echo " Ошибок: {$results['error']}<br>";
echo " Всего проверено: {$results['total']}<br>";
echo "</div>";
// Команды для исправления прав
if ($results['error'] > 0 || $results['warning'] > 0) {
echo "<h2> Команды для исправления прав</h2>";
echo "<div style='background: #f8f9fa; padding: 15px; border-radius: 5px; font-family: monospace;'>";
echo "<p><strong>Выполните следующие команды через SSH:</strong></p>";
echo "<code>";
echo "# Установка прав на папки (755) и файлы (644)<br>";
echo "find " . $baseDir . " -type d -exec chmod 755 {} \;<br>";
echo "find " . $baseDir . " -type f -exec chmod 644 {} \;<br><br>";
echo "# Папка uploads и все вложенные (777)<br>";
echo "chmod -R 777 " . $baseDir . "/uploads<br><br>";
echo "# Папка datastore (777)<br>";
echo "chmod 777 " . $baseDir . "/datastore<br><br>";
echo "# Папки applications и plugins (755)<br>";
echo "chmod 755 " . $baseDir . "/applications " . $baseDir . "/plugins<br><br>";
echo "# Файл conf_global.php (666)<br>";
echo "chmod 666 " . $baseDir . "/conf_global.php<br><br>";
echo "# Если проблемы сохраняются, проверьте владельца файлов:<br>";
echo "chown -R www-data:www-data " . $baseDir . "<br>";
echo "(замените www-data на пользователя вашего веб-сервера)";
echo "</code>";
echo "</div>";
}
// Проверка PHP расширений
echo "<h2> Проверка PHP расширений</h2>";
echo "<table>";
echo "<tr><th>Расширение</th><th>Статус</th></tr>";
$extensions = [
'curl' => 'cURL',
'gd' => 'GD',
'mysqli' => 'MySQLi',
'json' => 'JSON',
'mbstring' => 'Multibyte String',
'zip' => 'Zip',
'xml' => 'XML',
'dom' => 'DOM',
'simplexml' => 'SimpleXML',
'openssl' => 'OpenSSL',
'session' => 'Session',
'pdo' => 'PDO',
];
foreach ($extensions as $ext => $name) {
$loaded = extension_loaded($ext);
$status = $loaded ? ' Загружено' : ' Не загружено';
$class = $loaded ? 'success' : 'error';
echo "<tr><td>$name ($ext)</td><td class='$class'>$status</td></tr>";
}
echo "</table>";
// Информация о PHP
echo "<h2> Информация о PHP</h2>";
echo "<table>";
echo "<tr><th>Параметр</th><th>Значение</th></tr>";
echo "<tr><td>PHP версия</td><td>" . PHP_VERSION . "</td></tr>";
echo "<tr><td>memory_limit</td><td>" . ini_get('memory_limit') . "</td></tr>";
echo "<tr><td>upload_max_filesize</td><td>" . ini_get('upload_max_filesize') . "</td></tr>";
echo "<tr><td>post_max_size</td><td>" . ini_get('post_max_size') . "</td></tr>";
echo "<tr><td>max_execution_time</td><td>" . ini_get('max_execution_time') . " сек</td></tr>";
echo "</table>";
echo "<p style='margin-top: 30px; padding: 10px; background: #fff3cd; border-radius: 5px;'>";
echo " <strong>Важно:</strong> После проверки удалите этот файл с сервера!<br>";
echo "Он может представлять угрозу безопасности, так как раскрывает информацию о вашей системе.";
echo "</p>";
echo "</div></body></html>";Запустите через браузер http://ваш-сайт.ru/check_permissions.phpСкрипт покажет: ✅ Зелёным — правильные права ⚠️ Жёлтым — предупреждения ❌ Красным — ошибки Если скрипт нашёл ошибки, он покажет готовые команды для SSH внизу страницы. Скопируйте и выполните их. Обязательно удалите файл check_permissions.php с сервера после проверки! Он содержит информацию о структуре вашего сайта и может быть использован злоумышленниками.